mirror of
https://git.FreeBSD.org/ports.git
synced 2024-12-24 04:33:24 +00:00
Add patches for twa (3ware 9000 series controller) support.
Bump PORTREVISION. PR: ports/84948 Submitted by: Rudolf Cejka <cejkar@fit.vutbr.cz> Approved by: martines@rochester.rr.com (maintainer, timeout 5 weeks)
This commit is contained in:
parent
a411714224
commit
7983d22598
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=144808
@ -7,7 +7,7 @@
|
||||
|
||||
PORTNAME= smartmontools
|
||||
PORTVERSION= 5.33
|
||||
PORTREVISION= 1
|
||||
PORTREVISION= 2
|
||||
CATEGORIES= sysutils
|
||||
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE}
|
||||
MASTER_SITE_SUBDIR= ${PORTNAME}
|
||||
|
12
sysutils/smartmontools-devel/files/patch-config.h.in
Normal file
12
sysutils/smartmontools-devel/files/patch-config.h.in
Normal file
@ -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
|
||||
|
11
sysutils/smartmontools-devel/files/patch-configure.in
Normal file
11
sysutils/smartmontools-devel/files/patch-configure.in
Normal file
@ -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.
|
||||
|
@ -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);
|
||||
@ -28,11 +28,26 @@
|
||||
+ 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;
|
||||
+ 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
|
||||
|
265
sysutils/smartmontools-devel/files/patch-os_freebsd.h
Normal file
265
sysutils/smartmontools-devel/files/patch-os_freebsd.h
Normal file
@ -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.
|
@ -7,7 +7,7 @@
|
||||
|
||||
PORTNAME= smartmontools
|
||||
PORTVERSION= 5.33
|
||||
PORTREVISION= 1
|
||||
PORTREVISION= 2
|
||||
CATEGORIES= sysutils
|
||||
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE}
|
||||
MASTER_SITE_SUBDIR= ${PORTNAME}
|
||||
|
12
sysutils/smartmontools/files/patch-config.h.in
Normal file
12
sysutils/smartmontools/files/patch-config.h.in
Normal file
@ -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
|
||||
|
11
sysutils/smartmontools/files/patch-configure.in
Normal file
11
sysutils/smartmontools/files/patch-configure.in
Normal file
@ -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.
|
||||
|
@ -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);
|
||||
@ -28,11 +28,26 @@
|
||||
+ 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;
|
||||
+ 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
|
||||
|
265
sysutils/smartmontools/files/patch-os_freebsd.h
Normal file
265
sysutils/smartmontools/files/patch-os_freebsd.h
Normal file
@ -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.
|
Loading…
Reference in New Issue
Block a user