diff options
author | Sam Lawrance <lawrance@FreeBSD.org> | 2005-10-10 12:39:59 +0000 |
---|---|---|
committer | Sam Lawrance <lawrance@FreeBSD.org> | 2005-10-10 12:39:59 +0000 |
commit | 7983d22598d760373466c2d1addd89222fa03f32 (patch) | |
tree | b23645cec794731f2692b2d1ad33c92c7064dbab /sysutils/smartmontools-devel | |
parent | a4117142249dffdfbe9a54fdb7c23e0a98c8d6c4 (diff) | |
download | ports-7983d22598d760373466c2d1addd89222fa03f32.tar.gz ports-7983d22598d760373466c2d1addd89222fa03f32.zip |
Notes
Diffstat (limited to 'sysutils/smartmontools-devel')
-rw-r--r-- | sysutils/smartmontools-devel/Makefile | 2 | ||||
-rw-r--r-- | sysutils/smartmontools-devel/files/patch-config.h.in | 12 | ||||
-rw-r--r-- | sysutils/smartmontools-devel/files/patch-configure.in | 11 | ||||
-rw-r--r-- | sysutils/smartmontools-devel/files/patch-os_freebsd.c | 373 | ||||
-rw-r--r-- | sysutils/smartmontools-devel/files/patch-os_freebsd.h | 265 |
5 files changed, 642 insertions, 21 deletions
diff --git a/sysutils/smartmontools-devel/Makefile b/sysutils/smartmontools-devel/Makefile index 6a08e04958b3..fa9a7ced3640 100644 --- a/sysutils/smartmontools-devel/Makefile +++ b/sysutils/smartmontools-devel/Makefile @@ -7,7 +7,7 @@ PORTNAME= smartmontools PORTVERSION= 5.33 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= sysutils MASTER_SITES= ${MASTER_SITE_SOURCEFORGE} MASTER_SITE_SUBDIR= ${PORTNAME} diff --git a/sysutils/smartmontools-devel/files/patch-config.h.in b/sysutils/smartmontools-devel/files/patch-config.h.in new file mode 100644 index 000000000000..b4887d8ab341 --- /dev/null +++ b/sysutils/smartmontools-devel/files/patch-config.h.in @@ -0,0 +1,12 @@ +--- config.h.in.orig Thu Aug 4 15:16:22 2005 ++++ config.h.in Thu Aug 4 15:19:21 2005 +@@ -66,6 +66,9 @@ + /* Define to 1 if you have the <sys/twereg.h> header file. */ + #undef HAVE_SYS_TWEREG_H + ++/* Define to 1 if you have the <sys/tw_osl_ioctl.h> header file. */ ++#undef HAVE_SYS_TW_OSL_IOCTL_H ++ + /* Define to 1 if you have the <sys/types.h> header file. */ + #undef HAVE_SYS_TYPES_H + diff --git a/sysutils/smartmontools-devel/files/patch-configure.in b/sysutils/smartmontools-devel/files/patch-configure.in new file mode 100644 index 000000000000..da1074dc8dd2 --- /dev/null +++ b/sysutils/smartmontools-devel/files/patch-configure.in @@ -0,0 +1,11 @@ +--- configure.in.orig Thu Aug 4 15:16:15 2005 ++++ configure.in Thu Aug 4 15:18:50 2005 +@@ -56,6 +56,8 @@ + dnl Check for FreeBSD twe include files...currently missing on 5.2, but should be there + AC_CHECK_HEADERS([sys/tweio.h]) + AC_CHECK_HEADERS([sys/twereg.h]) ++dnl Check for FreeBSD twa include files... ++AC_CHECK_HEADERS([sys/tw_osl_ioctl.h]) + + dnl Checks for typedefs, structures, and compiler characteristics. + diff --git a/sysutils/smartmontools-devel/files/patch-os_freebsd.c b/sysutils/smartmontools-devel/files/patch-os_freebsd.c index 74c78fcf7bd0..e215f1fb78fe 100644 --- a/sysutils/smartmontools-devel/files/patch-os_freebsd.c +++ b/sysutils/smartmontools-devel/files/patch-os_freebsd.c @@ -1,5 +1,5 @@ ---- os_freebsd.c.orig Sun Sep 5 09:16:07 2004 -+++ os_freebsd.c Mon May 23 19:29:43 2005 +--- os_freebsd.c.orig Sun Oct 9 13:00:56 2005 ++++ os_freebsd.c Sun Oct 9 13:00:46 2005 @@ -18,6 +18,7 @@ #include <stdio.h> #include <sys/types.h> @@ -20,7 +20,7 @@ int myerror = errno; //preserve across free call free (fdchan); errno = myerror; -@@ -120,7 +125,11 @@ +@@ -120,7 +125,26 @@ if (parse_ok == CONTROLLER_3WARE_678K_CHAR) { char buf[512]; sprintf(buf,"/dev/twe%d",fdchan->device); @@ -29,10 +29,25 @@ +#else if ((fdchan->atacommand = open(buf,O_RDWR))<0) { +#endif ++ int myerror = errno; // preserver across free call ++ free(fdchan); ++ errno=myerror; ++ return -1; ++ } ++ } ++ ++ if (parse_ok == CONTROLLER_3WARE_9000_CHAR) { ++ char buf[512]; ++ sprintf(buf,"/dev/twa%d",fdchan->device); ++#ifdef IOCATAREQUEST ++ if ((fdchan->device = open(buf,O_RDWR))<0) { ++#else ++ if ((fdchan->atacommand = open(buf,O_RDWR))<0) { ++#endif int myerror = errno; // preserver across free call free(fdchan); errno=myerror; -@@ -167,8 +176,13 @@ +@@ -167,8 +191,13 @@ free(fdchan->devname); // close device, if open @@ -46,7 +61,7 @@ if (fdchan->scsicontrol) failed=close(fdchan->scsicontrol); -@@ -221,7 +235,7 @@ +@@ -221,7 +250,7 @@ } int ata_command_interface(int fd, smart_command_set command, int select, char *data) { @@ -55,7 +70,7 @@ // sorry, but without ATAng, we can't do anything here printwarning(BAD_KERNEL,NULL); errno = ENOSYS; -@@ -229,7 +243,11 @@ +@@ -229,7 +258,11 @@ #else struct freebsd_dev_channel* con; int retval, copydata=0; @@ -67,7 +82,7 @@ unsigned char buff[512]; // check that "file descriptor" is valid -@@ -238,89 +256,97 @@ +@@ -238,89 +271,97 @@ bzero(buff,512); @@ -211,14 +226,15 @@ break; default: pout("Unrecognized command %d in ata_command_interface()\n" -@@ -334,15 +360,19 @@ +@@ -334,15 +375,19 @@ unsigned const char failed_lo=0xf4, failed_hi=0x2c; unsigned char low,high; +- if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) +#ifdef IOCATAREQUEST -+ if ((retval=ioctl(con->device, IOCATAREQUEST, &request))) ++ if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error) +#else - if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) ++ if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error) +#endif return -1; @@ -233,7 +249,7 @@ // Cyl low and Cyl high unchanged means "Good SMART status" if (low==normal_lo && high==normal_hi) -@@ -355,18 +385,22 @@ +@@ -355,21 +400,23 @@ // We haven't gotten output that makes sense; print out some debugging info char buf[512]; sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n", @@ -255,35 +271,327 @@ return 0; } +- if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) { +- perror("Failed command: "); +#ifdef IOCATAREQUEST -+ if ((retval=ioctl(con->device, IOCATAREQUEST, &request))) { ++ if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error) +#else - if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) { ++ if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error) +#endif - perror("Failed command: "); return -1; +- } + // + if (copydata) + memcpy(data, buff, 512); +@@ -483,16 +530,22 @@ + + // Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c + ++#define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520 ++#define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048 ++#define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) ) ++ + int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data) { + // to hold true file descriptor + struct freebsd_dev_channel* con; + + // return value and buffer for ioctl() + int ioctlreturn, readdata=0; +- struct twe_usercommand* cmd = NULL; ++ struct twe_usercommand* cmd_twe = NULL; ++ TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL; ++ TWE_Command_ATA* ata = NULL; + + // Used by both the SCSI and char interfaces +- char ioctl_buffer[sizeof(struct twe_usercommand)]; ++ char ioctl_buffer[TW_IOCTL_BUFFER_SIZE]; + + if (disknum < 0) { + printwarning(NO_DISK_3WARE,NULL); +@@ -503,27 +556,40 @@ + if (isnotopen(&fd,&con)) + return -1; + +- memset(ioctl_buffer, 0, sizeof(struct twe_usercommand)); ++ memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE); + +- cmd = (struct twe_usercommand*)ioctl_buffer; +- cmd->tu_command.ata.opcode = TWE_OP_ATA_PASSTHROUGH; ++ if (escalade_type==CONTROLLER_3WARE_9000_CHAR) { ++ cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer; ++ cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf; ++ cmd_twa->driver_pkt.buffer_length = 512; ++ ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k; ++ } else if (escalade_type==CONTROLLER_3WARE_678K_CHAR) { ++ cmd_twe = (struct twe_usercommand*)ioctl_buffer; ++ ata = &cmd_twe->tu_command.ata; ++ } else { ++ pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n" ++ "Please contact " PACKAGE_BUGREPORT "\n", escalade_type, disknum); ++ errno=ENOSYS; ++ return -1; ++ } + + // Same for (almost) all commands - but some reset below +- cmd->tu_command.ata.request_id = 0xFF; +- cmd->tu_command.ata.unit = disknum; +- cmd->tu_command.ata.host_id = 0; +- cmd->tu_command.ata.status = 0; +- cmd->tu_command.ata.flags = 0x1; +- cmd->tu_command.ata.drive_head = 0x0; +- cmd->tu_command.ata.sector_num = 0; ++ ata->opcode = TWE_OP_ATA_PASSTHROUGH; ++ ata->request_id = 0xFF; ++ ata->unit = disknum; ++ ata->host_id = 0; ++ ata->status = 0; ++ ata->flags = 0x1; ++ ata->drive_head = 0x0; ++ ata->sector_num = 0; + + // All SMART commands use this CL/CH signature. These are magic + // values from the ATA specifications. +- cmd->tu_command.ata.cylinder_lo = 0x4F; +- cmd->tu_command.ata.cylinder_hi = 0xC2; ++ ata->cylinder_lo = 0x4F; ++ ata->cylinder_hi = 0xC2; + + // SMART ATA COMMAND REGISTER value +- cmd->tu_command.ata.command = ATA_SMART_CMD; ++ ata->command = ATA_SMART_CMD; + + // Is this a command that reads or returns 512 bytes? + // passthru->param values are: +@@ -538,61 +604,63 @@ + command == IDENTIFY || + command == WRITE_LOG ) { + readdata=1; +- cmd->tu_size = 512; +- cmd->tu_data = data; +- cmd->tu_command.ata.sgl_offset = 0x5; +- cmd->tu_command.ata.size = 0x5; +- cmd->tu_command.ata.param = 0xD; +- cmd->tu_command.ata.sector_count = 0x1; ++ if (escalade_type==CONTROLLER_3WARE_678K_CHAR) { ++ cmd_twe->tu_data = data; ++ cmd_twe->tu_size = 512; ++ } ++ ata->sgl_offset = 0x5; ++ ata->size = 0x5; ++ ata->param = 0xD; ++ ata->sector_count = 0x1; + // For 64-bit to work correctly, up the size of the command packet + // in dwords by 1 to account for the 64-bit single sgl 'address' + // field. Note that this doesn't agree with the typedefs but it's + // right (agree with kernel driver behavior/typedefs). +- //if (sizeof(long)==8) +- // cmd->tu_command.ata.size++; ++ //if (escalade_type==CONTROLLER_3WARE_9000_CHAR && sizeof(long)==8) ++ // ata->size++; } -@@ -637,7 +671,11 @@ + else { + // Non data command -- but doesn't use large sector + // count register values. +- cmd->tu_command.ata.sgl_offset = 0x0; +- cmd->tu_command.ata.size = 0x5; +- cmd->tu_command.ata.param = 0x8; +- cmd->tu_command.ata.sector_count = 0x0; ++ ata->sgl_offset = 0x0; ++ ata->size = 0x5; ++ ata->param = 0x8; ++ ata->sector_count = 0x0; + } + + // Now set ATA registers depending upon command + switch (command){ + case CHECK_POWER_MODE: +- cmd->tu_command.ata.command = ATA_CHECK_POWER_MODE; +- cmd->tu_command.ata.features = 0; +- cmd->tu_command.ata.cylinder_lo = 0; +- cmd->tu_command.ata.cylinder_hi = 0; ++ ata->command = ATA_CHECK_POWER_MODE; ++ ata->features = 0; ++ ata->cylinder_lo = 0; ++ ata->cylinder_hi = 0; + break; + case READ_VALUES: +- cmd->tu_command.ata.features = ATA_SMART_READ_VALUES; ++ ata->features = ATA_SMART_READ_VALUES; + break; + case READ_THRESHOLDS: +- cmd->tu_command.ata.features = ATA_SMART_READ_THRESHOLDS; ++ ata->features = ATA_SMART_READ_THRESHOLDS; + break; + case READ_LOG: +- cmd->tu_command.ata.features = ATA_SMART_READ_LOG_SECTOR; ++ ata->features = ATA_SMART_READ_LOG_SECTOR; + // log number to return +- cmd->tu_command.ata.sector_num = select; ++ ata->sector_num = select; + break; + case WRITE_LOG: +- cmd->tu_data = data; ++ if (escalade_type==CONTROLLER_3WARE_9000_CHAR) ++ memcpy(cmd_twa->pdata, data, 512); + readdata=0; +- cmd->tu_command.ata.features = ATA_SMART_WRITE_LOG_SECTOR; +- cmd->tu_command.ata.sector_count = 1; +- cmd->tu_command.ata.sector_num = select; +- cmd->tu_command.ata.param = 0xF; // PIO data write ++ ata->features = ATA_SMART_WRITE_LOG_SECTOR; ++ ata->sector_num = select; ++ ata->param = 0xF; // PIO data write + break; + case IDENTIFY: + // ATA IDENTIFY DEVICE +- cmd->tu_command.ata.command = ATA_IDENTIFY_DEVICE; +- cmd->tu_command.ata.features = 0; +- cmd->tu_command.ata.cylinder_lo = 0; +- cmd->tu_command.ata.cylinder_hi = 0; ++ ata->command = ATA_IDENTIFY_DEVICE; ++ ata->features = 0; ++ ata->cylinder_lo = 0; ++ ata->cylinder_hi = 0; + break; + case PIDENTIFY: + // 3WARE controller can NOT have packet device internally +@@ -600,34 +668,34 @@ + errno=ENODEV; + return -1; + case ENABLE: +- cmd->tu_command.ata.features = ATA_SMART_ENABLE; ++ ata->features = ATA_SMART_ENABLE; + break; + case DISABLE: +- cmd->tu_command.ata.features = ATA_SMART_DISABLE; ++ ata->features = ATA_SMART_DISABLE; + break; + case AUTO_OFFLINE: +- cmd->tu_command.ata.features = ATA_SMART_AUTO_OFFLINE; ++ ata->features = ATA_SMART_AUTO_OFFLINE; + // Enable or disable? +- cmd->tu_command.ata.sector_count = select; ++ ata->sector_count = select; + break; + case AUTOSAVE: +- cmd->tu_command.ata.features = ATA_SMART_AUTOSAVE; ++ ata->features = ATA_SMART_AUTOSAVE; + // Enable or disable? +- cmd->tu_command.ata.sector_count = select; ++ ata->sector_count = select; + break; + case IMMEDIATE_OFFLINE: +- cmd->tu_command.ata.features = ATA_SMART_IMMEDIATE_OFFLINE; ++ ata->features = ATA_SMART_IMMEDIATE_OFFLINE; + // What test type to run? +- cmd->tu_command.ata.sector_num = select; ++ ata->sector_num = select; + break; + case STATUS_CHECK: +- cmd->tu_command.ata.features = ATA_SMART_STATUS; ++ ata->features = ATA_SMART_STATUS; + break; + case STATUS: + // This is JUST to see if SMART is enabled, by giving SMART status + // command. But it doesn't say if status was good, or failing. + // See below for the difference. +- cmd->tu_command.ata.features = ATA_SMART_STATUS; ++ ata->features = ATA_SMART_STATUS; + break; + default: + pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n" +@@ -637,7 +705,19 @@ } // Now send the command down through an ioctl() +- ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd); ++ if (escalade_type==CONTROLLER_3WARE_9000_CHAR) { +#ifdef IOCATAREQUEST -+ ioctlreturn=ioctl(con->device,TWEIO_COMMAND,cmd); ++ ioctlreturn=ioctl(con->device,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa); +#else - ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd); ++ ioctlreturn=ioctl(con->atacommand,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa); +#endif ++ } else { ++#ifdef IOCATAREQUEST ++ ioctlreturn=ioctl(con->device,TWEIO_COMMAND,cmd_twe); ++#else ++ ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd_twe); ++#endif ++ } // Deal with the different error cases if (ioctlreturn) { -@@ -709,6 +747,7 @@ +@@ -648,9 +728,9 @@ + + // See if the ATA command failed. Now that we have returned from + // the ioctl() call, if passthru is valid, then: +- // - cmd->tu_command.ata.status contains the 3ware controller STATUS +- // - cmd->tu_command.ata.command contains the ATA STATUS register +- // - cmd->tu_command.ata.features contains the ATA ERROR register ++ // - ata->status contains the 3ware controller STATUS ++ // - ata->command contains the ATA STATUS register ++ // - ata->features contains the ATA ERROR register + // + // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS + // If bit 0 (error bit) is set, then ATA ERROR register is valid. +@@ -658,21 +738,27 @@ + // doesn't make much sense: we don't care in detail why the error + // happened. + +- if (cmd->tu_command.ata.status || (cmd->tu_command.ata.command & 0x21)) { +- pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",cmd->tu_command.ata.status,cmd->tu_command.ata.command,cmd->tu_command.ata.flags); ++ if (ata->status || (ata->command & 0x21)) { ++ pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",ata->status,ata->command,ata->flags); + errno=EIO; + return -1; + } + ++ // If this is a read data command, copy data to output buffer ++ if (readdata) { ++ if (escalade_type==CONTROLLER_3WARE_9000_CHAR) ++ memcpy(data, cmd_twa->pdata, 512); ++ } ++ + // For STATUS_CHECK, we need to check register values + if (command==STATUS_CHECK) { + + // To find out if the SMART RETURN STATUS is good or failing, we + // need to examine the values of the Cylinder Low and Cylinder + // High Registers. +- +- unsigned short cyl_lo=cmd->tu_command.ata.cylinder_lo; +- unsigned short cyl_hi=cmd->tu_command.ata.cylinder_hi; ++ ++ unsigned short cyl_lo=ata->cylinder_lo; ++ unsigned short cyl_hi=ata->cylinder_hi; + + // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good. + if (cyl_lo==0x4F && cyl_hi==0xC2) +@@ -688,7 +774,7 @@ + + // copy sector count register (one byte!) to return data + if (command==CHECK_POWER_MODE) +- *data=*(char *)&(cmd->tu_command.ata.sector_count); ++ *data=*(char *)&(ata->sector_count); + + // look for nonexistent devices/ports + if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) { +@@ -709,6 +795,14 @@ return 0; } ++static int get_twa_channel_unit (const char* name, int* unit, int* dev) { ++ if (sscanf(name, "twa%d", dev) != 1) ++ return -1; ++ *unit=0; // not really needed for TWA drives, as we handle that seperately ++ return 0; ++} ++ +#ifndef IOCATAREQUEST static int get_ata_channel_unit ( const char* name, int* unit, int* dev) { #ifndef ATAREQUEST *dev=0; -@@ -756,7 +795,7 @@ +@@ -756,7 +850,7 @@ return 0; #endif } @@ -292,7 +600,15 @@ // Guess device type (ata or scsi) based on device name (FreeBSD // specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst, -@@ -788,11 +827,13 @@ +@@ -768,6 +862,7 @@ + static const char * fbsd_dev_scsi_tape2 = "nsa"; + static const char * fbsd_dev_scsi_tape3 = "esa"; + static const char * fbsd_dev_twe_disk = "twed"; ++static const char * fbsd_dev_twa_disk = "twa"; + + static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) { + int len; +@@ -788,11 +883,13 @@ // form /dev/ad* or ad* if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name, strlen(fbsd_dev_ata_disk_prefix))) { @@ -306,3 +622,20 @@ return CONTROLLER_ATA; } +@@ -824,6 +921,16 @@ + } + } + return CONTROLLER_3WARE_678K_CHAR; ++ } ++ ++ if (!strncmp(fbsd_dev_twa_disk,dev_name, ++ strlen(fbsd_dev_twa_disk))) { ++ if (chan != NULL) { ++ if (get_twa_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) { ++ return CONTROLLER_UNKNOWN; ++ } ++ } ++ return CONTROLLER_3WARE_9000_CHAR; + } + + // we failed to recognize any of the forms diff --git a/sysutils/smartmontools-devel/files/patch-os_freebsd.h b/sysutils/smartmontools-devel/files/patch-os_freebsd.h new file mode 100644 index 000000000000..f4d397fffc29 --- /dev/null +++ b/sysutils/smartmontools-devel/files/patch-os_freebsd.h @@ -0,0 +1,265 @@ +--- os_freebsd.h.orig Sun Sep 5 09:16:07 2004 ++++ os_freebsd.h Sat Aug 6 21:08:54 2005 +@@ -261,6 +261,262 @@ + + #endif + ++#ifdef HAVE_SYS_TW_OSL_IOCTL_H ++#include <sys/tw_osl_ioctl.h> ++#else ++/* ++ * Following cut out of tw_osl_types.h ++ * ++ */ ++ ++typedef void TW_VOID; ++typedef char TW_INT8; ++typedef unsigned char TW_UINT8; ++typedef short TW_INT16; ++typedef unsigned short TW_UINT16; ++typedef int TW_INT32; ++typedef unsigned int TW_UINT32; ++typedef long long TW_INT64; ++typedef unsigned long long TW_UINT64; ++ ++/* ++ * Following cut out of tw_cl_share.h ++ * ++ */ ++ ++#pragma pack(1) ++ ++struct tw_cl_event_packet { ++ TW_UINT32 sequence_id; ++ TW_UINT32 time_stamp_sec; ++ TW_UINT16 aen_code; ++ TW_UINT8 severity; ++ TW_UINT8 retrieved; ++ TW_UINT8 repeat_count; ++ TW_UINT8 parameter_len; ++ TW_UINT8 parameter_data[98]; ++ TW_UINT32 event_src; ++ TW_UINT8 severity_str[20]; ++}; ++ ++#pragma pack() ++ ++/* ++ * Following cut out of tw_cl_fwif.h ++ * ++ */ ++ ++#define TWA_FW_CMD_ATA_PASSTHROUGH 0x11 ++ ++#define TWA_SENSE_DATA_LENGTH 18 ++ ++#pragma pack(1) ++/* 7000 structures. */ ++struct tw_cl_command_init_connect { ++ TW_UINT8 res1__opcode; /* 3:5 */ ++ TW_UINT8 size; ++ TW_UINT8 request_id; ++ TW_UINT8 res2; ++ TW_UINT8 status; ++ TW_UINT8 flags; ++ TW_UINT16 message_credits; ++ TW_UINT32 features; ++ TW_UINT16 fw_srl; ++ TW_UINT16 fw_arch_id; ++ TW_UINT16 fw_branch; ++ TW_UINT16 fw_build; ++ TW_UINT32 result; ++}; ++ ++ ++/* Structure for downloading firmware onto the controller. */ ++struct tw_cl_command_download_firmware { ++ TW_UINT8 sgl_off__opcode;/* 3:5 */ ++ TW_UINT8 size; ++ TW_UINT8 request_id; ++ TW_UINT8 unit; ++ TW_UINT8 status; ++ TW_UINT8 flags; ++ TW_UINT16 param; ++ TW_UINT8 sgl[1]; ++}; ++ ++ ++/* Structure for hard resetting the controller. */ ++struct tw_cl_command_reset_firmware { ++ TW_UINT8 res1__opcode; /* 3:5 */ ++ TW_UINT8 size; ++ TW_UINT8 request_id; ++ TW_UINT8 unit; ++ TW_UINT8 status; ++ TW_UINT8 flags; ++ TW_UINT8 res2; ++ TW_UINT8 param; ++}; ++ ++ ++/* Structure for sending get/set param commands. */ ++struct tw_cl_command_param { ++ TW_UINT8 sgl_off__opcode;/* 3:5 */ ++ TW_UINT8 size; ++ TW_UINT8 request_id; ++ TW_UINT8 host_id__unit; /* 4:4 */ ++ TW_UINT8 status; ++ TW_UINT8 flags; ++ TW_UINT16 param_count; ++ TW_UINT8 sgl[1]; ++}; ++ ++ ++/* Generic command packet. */ ++struct tw_cl_command_generic { ++ TW_UINT8 sgl_off__opcode;/* 3:5 */ ++ TW_UINT8 size; ++ TW_UINT8 request_id; ++ TW_UINT8 host_id__unit; /* 4:4 */ ++ TW_UINT8 status; ++ TW_UINT8 flags; ++ TW_UINT16 count; /* block cnt, parameter cnt, message credits */ ++}; ++ ++ ++/* Command packet header. */ ++struct tw_cl_command_header { ++ TW_UINT8 sense_data[TWA_SENSE_DATA_LENGTH]; ++ struct { ++ TW_INT8 reserved[4]; ++ TW_UINT16 error; ++ TW_UINT8 padding; ++ TW_UINT8 res__severity; /* 5:3 */ ++ } status_block; ++ TW_UINT8 err_specific_desc[98]; ++ struct { ++ TW_UINT8 size_header; ++ TW_UINT16 reserved; ++ TW_UINT8 size_sense; ++ } header_desc; ++}; ++ ++ ++/* 7000 Command packet. */ ++union tw_cl_command_7k { ++ struct tw_cl_command_init_connect init_connect; ++ struct tw_cl_command_download_firmware download_fw; ++ struct tw_cl_command_reset_firmware reset_fw; ++ struct tw_cl_command_param param; ++ struct tw_cl_command_generic generic; ++ TW_UINT8 padding[1024 - sizeof(struct tw_cl_command_header)]; ++}; ++ ++ ++/* 9000 Command Packet. */ ++struct tw_cl_command_9k { ++ TW_UINT8 res__opcode; /* 3:5 */ ++ TW_UINT8 unit; ++ TW_UINT16 lun_l4__req_id; /* 4:12 */ ++ TW_UINT8 status; ++ TW_UINT8 sgl_offset; /* offset (in bytes) to sg_list, from the ++ end of sgl_entries */ ++ TW_UINT16 lun_h4__sgl_entries; ++ TW_UINT8 cdb[16]; ++ TW_UINT8 sg_list[872];/* total struct size = ++ 1024-sizeof(cmd_hdr) */ ++}; ++ ++ ++/* Full command packet. */ ++struct tw_cl_command_packet { ++ struct tw_cl_command_header cmd_hdr; ++ union { ++ union tw_cl_command_7k cmd_pkt_7k; ++ struct tw_cl_command_9k cmd_pkt_9k; ++ } command; ++}; ++ ++#pragma pack() ++ ++/* ++ * Following cut out of tw_cl_ioctl.h ++ * ++ */ ++ ++#pragma pack(1) ++ ++/* Structure used to handle GET/RELEASE LOCK ioctls. */ ++struct tw_cl_lock_packet { ++ TW_UINT32 timeout_msec; ++ TW_UINT32 time_remaining_msec; ++ TW_UINT32 force_flag; ++}; ++ ++ ++/* Structure used to handle GET COMPATIBILITY INFO ioctl. */ ++struct tw_cl_compatibility_packet { ++ TW_UINT8 driver_version[32];/* driver version */ ++ TW_UINT16 working_srl; /* driver & firmware negotiated srl */ ++ TW_UINT16 working_branch; /* branch # of the firmware that the ++ driver is compatible with */ ++ TW_UINT16 working_build; /* build # of the firmware that the ++ driver is compatible with */ ++}; ++ ++ ++/* Driver understandable part of the ioctl packet built by the API. */ ++struct tw_cl_driver_packet { ++ TW_UINT32 control_code; ++ TW_UINT32 status; ++ TW_UINT32 unique_id; ++ TW_UINT32 sequence_id; ++ TW_UINT32 os_status; ++ TW_UINT32 buffer_length; ++}; ++ ++#pragma pack() ++ ++/* ++ * Following cut out of tw_osl_ioctl.h ++ * ++ */ ++ ++#pragma pack(1) ++/* ++ * We need the structure below to ensure that the first byte of ++ * data_buf is not overwritten by the kernel, after we return ++ * from the ioctl call. Note that cmd_pkt has been reduced ++ * to an array of 1024 bytes even though it's actually 2048 bytes ++ * in size. This is because, we don't expect requests from user ++ * land requiring 2048 (273 sg elements) byte cmd pkts. ++ */ ++typedef struct tw_osli_ioctl_no_data_buf { ++ struct tw_cl_driver_packet driver_pkt; ++ TW_VOID *pdata; /* points to data_buf */ ++ TW_INT8 padding[488 - sizeof(TW_VOID *)]; ++ struct tw_cl_command_packet cmd_pkt; ++} TW_OSLI_IOCTL_NO_DATA_BUF; ++ ++#pragma pack() ++ ++#define TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH \ ++ _IOWR('T', 202, TW_OSLI_IOCTL_NO_DATA_BUF) ++ ++#pragma pack(1) ++ ++typedef struct tw_osli_ioctl_with_payload { ++ struct tw_cl_driver_packet driver_pkt; ++ TW_INT8 padding[488]; ++ struct tw_cl_command_packet cmd_pkt; ++ union { ++ struct tw_cl_event_packet event_pkt; ++ struct tw_cl_lock_packet lock_pkt; ++ struct tw_cl_compatibility_packet compat_pkt; ++ TW_INT8 data_buf[1]; ++ } payload; ++} TW_OSLI_IOCTL_WITH_PAYLOAD; ++ ++#pragma pack() ++ ++#endif ++ + /* + The following definitions/macros/prototypes are used for three + different interfaces, referred to as "the three cases" below. |