Annotation of embedaddon/smartmontools/os_qnxnto.cpp, revision 1.1.1.2

1.1       misho       1: 
                      2: 
                      3: // This is needed for the various HAVE_* macros and PROJECT_* macros.
                      4: #include "config.h"
                      5: 
                      6: // These are needed to define prototypes and structures for the
                      7: // functions defined below
                      8: #include "int64.h"
                      9: #include "atacmds.h"
                     10: #include "scsicmds.h"
                     11: #include "utility.h"
                     12: 
                     13: // This is to include whatever structures and prototypes you define in
                     14: // os_generic.h
                     15: #include "os_qnxnto.h"
1.1.1.2 ! misho      16: #include <errno.h>
1.1       misho      17: 
                     18: // Needed by '-V' option (CVS versioning) of smartd/smartctl.  You
                     19: // should have one *_H_CVSID macro appearing below for each file
                     20: // appearing with #include "*.h" above.  Please list these (below) in
                     21: // alphabetic/dictionary order.
1.1.1.2 ! misho      22: const char *os_XXXX_c_cvsid="$Id: os_qnxnto.cpp 3746 2013-01-13 17:11:58Z chrfranke $" \
1.1       misho      23: ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_QNXNTO_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
                     24: 
                     25: 
                     26: // This is here to prevent compiler warnings for unused arguments of
                     27: // functions.
                     28: #define ARGUSED(x) ((void)(x))
                     29: 
                     30: // Please eliminate the following block: both the #include and
                     31: // the 'unsupported()' function.  They are only here to warn
                     32: // unsuspecting users that their Operating System is not supported! If
                     33: // you wish, you can use a similar warning mechanism for any of the
                     34: // functions in this file that you can not (or choose not to)
                     35: // implement.
                     36: 
                     37: 
                     38: #ifdef HAVE_UNAME
                     39: #include <sys/utsname.h>
                     40: #endif
                     41: //----------------------------------------------------------------------------------------------
                     42: // private Functions
                     43: static int ata_sense_data(void *sdata,int *error,int *key,int *asc,int *ascq);
                     44: static int ata_interpret_sense(struct cam_pass_thru *cpt,void *sense,int *status,int rcount);
                     45: static int ata_pass_thru(int fd,struct cam_pass_thru *pcpt);
                     46: //----------------------------------------------------------------------------------------------
                     47: static void unsupported(){
                     48:   static int warninggiven;
                     49: 
                     50:   if (!warninggiven) {
                     51:     char *osname;
                     52: 
                     53: #ifdef HAVE_UNAME
                     54:     struct utsname ostype;
                     55:     uname(&ostype);
                     56:     osname=ostype.sysname;
                     57: #else
                     58:     osname="host's";
                     59: #endif
                     60: 
                     61:     pout("\n"
                     62:          "############################################################################\n"
                     63:          "WARNING: smartmontools has not been ported to the %s Operating System.\n"
                     64:          "Please see the files os_generic.cpp and os_generic.h for porting instructions.\n"
                     65:          "############################################################################\n\n",
                     66:          osname);
                     67:     warninggiven=1;
                     68:   }
                     69: 
                     70:   return;
                     71: }
                     72: // End of the 'unsupported()' block that you should eliminate.
                     73: 
                     74: 
                     75: // print examples for smartctl.  You should modify this function so
                     76: // that the device paths are sensible for your OS, and to eliminate
                     77: // unsupported commands (eg, 3ware controllers).
                     78: void print_smartctl_examples(){
                     79:   printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
                     80: #ifdef HAVE_GETOPT_LONG
                     81:   printf(
                     82:          "  smartctl -a /dev/hd0                       (Prints all SMART information)\n\n"
                     83:          "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hd0\n"
                     84:          "                                              (Enables SMART on first disk)\n\n"
                     85:          "  smartctl -t long /dev/hd0              (Executes extended disk self-test)\n\n"
                     86:          "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hd0\n"
                     87:          "                                      (Prints Self-Test & Attribute errors)\n"
                     88:          "  smartctl -a --device=3ware,2 /dev/sda\n"
                     89:          "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
                     90:          );
                     91: #else
                     92:   printf(
                     93:          "  smartctl -a /dev/hd0                       (Prints all SMART information)\n"
                     94:          "  smartctl -s on -o on -S on /dev/hd0         (Enables SMART on first disk)\n"
                     95:          "  smartctl -t long /dev/hd0              (Executes extended disk self-test)\n"
                     96:          "  smartctl -A -l selftest -q errorsonly /dev/hd0\n"
                     97:          "                                      (Prints Self-Test & Attribute errors)\n"
                     98:          "  smartctl -a -d 3ware,2 /dev/sda\n"
                     99:          "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
                    100:          );
                    101: #endif
                    102:   return;
                    103: }
                    104: 
                    105: // tries to guess device type given the name (a path).  See utility.h
                    106: // for return values.
                    107: static const char *net_dev_prefix = "/dev/";
                    108: static const char *net_dev_ata_disk = "hd";
                    109: 
                    110: int guess_device_type (const char* dev_name)
                    111: {
                    112: int len,dev_prefix_len;
                    113:   dev_prefix_len=strlen(net_dev_prefix);
                    114:   if(!dev_name||!(len=strlen(dev_name)))
                    115:     return(CONTROLLER_UNKNOWN);
                    116:   if (!strncmp(net_dev_prefix,dev_name,dev_prefix_len))
                    117:    {
                    118:     if(len<=dev_prefix_len)
                    119:       return(CONTROLLER_UNKNOWN);
                    120:     else
                    121:       dev_name += dev_prefix_len;
                    122:    }
                    123:   if(!strncmp(net_dev_ata_disk,dev_name,strlen(net_dev_ata_disk)))
                    124:     return(CONTROLLER_ATA);
                    125:   return(CONTROLLER_UNKNOWN);
                    126: }
                    127: 
                    128: // makes a list of ATA or SCSI devices for the DEVICESCAN directive of
                    129: // smartd.  Returns number N of devices, or -1 if out of
                    130: // memory. Allocates N+1 arrays: one of N pointers (devlist); the
                    131: // other N arrays each contain null-terminated character strings.  In
                    132: // the case N==0, no arrays are allocated because the array of 0
                    133: // pointers has zero length, equivalent to calling malloc(0).
                    134: int make_device_names (char*** devlist, const char* name) {
                    135:   ARGUSED(devlist);
                    136:   ARGUSED(name);
                    137:   unsupported();
                    138:   return 0;
                    139: }
                    140: 
                    141: // Like open().  Return non-negative integer handle, only used by the
                    142: // functions below.  type=="ATA" or "SCSI".  If you need to store
                    143: // extra information about your devices, create a private internal
                    144: // array within this file (see os_freebsd.cpp for an example).  If you
                    145: // can not open the device (permission denied, does not exist, etc)
                    146: // set errno as open() does and return <0.
                    147: int deviceopen(const char *pathname, char *type)
                    148: {
                    149:   if(!strcmp(type, "ATA"))
                    150:     return(open(pathname,O_RDWR|O_NONBLOCK));
                    151:   else
                    152:     return(-1);
                    153: }
                    154: 
                    155: // Like close().  Acts only on integer handles returned by
                    156: // deviceopen() above.
                    157: int deviceclose(int fd)
                    158: {
                    159:   return(close(fd));
                    160: }
                    161: //----------------------------------------------------------------------------------------------
                    162: // Interface to ATA devices.  See os_linux.cpp for the cannonical example.
                    163: // DETAILED DESCRIPTION OF ARGUMENTS
                    164: //   device: is the integer handle provided by deviceopen()
                    165: //   command: defines the different operations, see atacmds.h
                    166: //   select: additional input data IF NEEDED (which log, which type of
                    167: //           self-test).
                    168: //   data:   location to write output data, IF NEEDED (1 or 512 bytes).
                    169: //   Note: not all commands use all arguments.
                    170: // RETURN VALUES (for all commands BUT command==STATUS_CHECK)
                    171: //  -1 if the command failed
                    172: //   0 if the command succeeded,
                    173: // RETURN VALUES if command==STATUS_CHECK
                    174: //  -1 if the command failed OR the disk SMART status can't be determined
                    175: //   0 if the command succeeded and disk SMART status is "OK"
                    176: //   1 if the command succeeded and disk SMART status is "FAILING"
                    177: int ata_command_interface(int fd,smart_command_set command,int select,char *data)
                    178: {
                    179: struct cam_pass_thru cpt;
                    180: ATA_SENSE            sense;
                    181: CDB                  *cdb;
                    182: int                  status,rc;
                    183:   memset(&cpt,0x00,sizeof(struct cam_pass_thru));
                    184:   cdb=(CDB *)cpt.cam_cdb;
                    185:   rc=-1;
                    186:   switch(command)
                    187:    {
                    188:     case READ_VALUES:
                    189:          cpt.cam_flags                  = CAM_DIR_IN;
                    190:          cpt.cam_cdb_len                = 16;
                    191:          cpt.cam_dxfer_len              = 512;
                    192:          cpt.cam_data_ptr               = (uint32_t)data;
                    193:          cpt.cam_sense_len              = sizeof(sense);
                    194:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    195:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    196:          cdb->ata_pass_thru.protocol    = ATA_PROTO_PIO_DATA_IN;
                    197:          cdb->ata_pass_thru.flags       = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
                    198:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    199:          cdb->ata_pass_thru.features    = ATA_SMART_READ_VALUES;
                    200:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    201:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    202:          break;
                    203:     case READ_THRESHOLDS:
                    204:          cpt.cam_flags                  = CAM_DIR_IN;
                    205:          cpt.cam_cdb_len                = 16;
                    206:          cpt.cam_dxfer_len              = 512;
                    207:          cpt.cam_data_ptr               = (uint32_t)data;
                    208:          cpt.cam_sense_len              = sizeof(sense);
                    209:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    210:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    211:          cdb->ata_pass_thru.protocol    = ATA_PROTO_PIO_DATA_IN;
                    212:          cdb->ata_pass_thru.flags       = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
                    213:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    214:          cdb->ata_pass_thru.features    = ATA_SMART_READ_THRESHOLDS;
                    215:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    216:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    217:          break;
                    218:     case READ_LOG:
                    219:          cpt.cam_flags                  = CAM_DIR_IN;
                    220:          cpt.cam_cdb_len                = 16;
                    221:          cpt.cam_dxfer_len              = 512;
                    222:          cpt.cam_data_ptr               = (uint32_t)data;
                    223:          cpt.cam_sense_len              = sizeof(sense);
                    224:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    225:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    226:          cdb->ata_pass_thru.protocol    = ATA_PROTO_PIO_DATA_IN;
                    227:          cdb->ata_pass_thru.flags       = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
                    228:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    229:          cdb->ata_pass_thru.features    = ATA_SMART_READ_LOG_SECTOR;
                    230:          cdb->ata_pass_thru.sector_count= 1;
                    231:          cdb->ata_pass_thru.lba_low     = select;
                    232:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    233:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    234:          break;
                    235:     case WRITE_LOG:
                    236:          return(-1);
                    237:          break;
                    238:     case IDENTIFY:
                    239:          cpt.cam_flags                  = CAM_DIR_IN;
                    240:          cpt.cam_cdb_len                = 16;
                    241:          cpt.cam_dxfer_len              = 512;
                    242:          cpt.cam_data_ptr               = (uint32_t)data;
                    243:          cpt.cam_sense_len              = sizeof(sense);
                    244:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    245:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    246:          cdb->ata_pass_thru.protocol    = ATA_PROTO_PIO_DATA_IN;
                    247:          cdb->ata_pass_thru.flags       = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
                    248:          cdb->ata_pass_thru.command     = ATA_IDENTIFY_DEVICE;
                    249:          break;
                    250:     case PIDENTIFY:
                    251:          cpt.cam_flags                  = CAM_DIR_IN;
                    252:          cpt.cam_cdb_len                = 16;
                    253:          cpt.cam_dxfer_len              = 512;
                    254:          cpt.cam_data_ptr               = (uint32_t)data;
                    255:          cpt.cam_sense_len              = sizeof(sense);
                    256:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    257:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    258:          cdb->ata_pass_thru.protocol    = ATA_PROTO_PIO_DATA_IN;
                    259:          cdb->ata_pass_thru.flags       = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
                    260:          cdb->ata_pass_thru.command     = ATA_IDENTIFY_PACKET_DEVICE;
                    261:          break;
                    262:     case ENABLE:
                    263:          cpt.cam_flags                  = CAM_DIR_NONE;
                    264:          cpt.cam_cdb_len                = 16;
                    265:          cpt.cam_sense_len              = sizeof(sense);
                    266:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    267:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    268:          cdb->ata_pass_thru.protocol    = ATA_PROTO_DATA_NONE;
                    269:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    270:          cdb->ata_pass_thru.features    = ATA_SMART_ENABLE;
                    271:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    272:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    273:          break;
                    274:     case DISABLE:
                    275:          cpt.cam_flags                  = CAM_DIR_NONE;
                    276:          cpt.cam_cdb_len                = 16;
                    277:          cpt.cam_sense_len              = sizeof(sense);
                    278:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    279:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    280:          cdb->ata_pass_thru.protocol    = ATA_PROTO_DATA_NONE;
                    281:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    282:          cdb->ata_pass_thru.features    = ATA_SMART_DISABLE;
                    283:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    284:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    285:          break;
                    286:     case AUTO_OFFLINE:
                    287:     // NOTE: According to ATAPI 4 and UP, this command is obsolete 
                    288:          cpt.cam_flags                  = CAM_DIR_NONE;
                    289:          cpt.cam_cdb_len                = 16;
                    290:          cpt.cam_sense_len              = sizeof(sense);
                    291:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    292:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    293:          cdb->ata_pass_thru.protocol    = ATA_PROTO_DATA_NONE;
                    294:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    295:          cdb->ata_pass_thru.features    = ATA_SMART_AUTO_OFFLINE;
                    296:          cdb->ata_pass_thru.lba_low     = select;
                    297:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    298:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    299:          break;
                    300:     case AUTOSAVE:
                    301:          cpt.cam_flags                  = CAM_DIR_NONE;
                    302:          cpt.cam_cdb_len                = 16;
                    303:          cpt.cam_sense_len              = sizeof(sense);
                    304:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    305:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    306:          cdb->ata_pass_thru.protocol    = ATA_PROTO_DATA_NONE;
                    307:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    308:          cdb->ata_pass_thru.features    = ATA_SMART_AUTOSAVE;
                    309:          cdb->ata_pass_thru.sector_count= select;
                    310:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    311:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    312:          break;
                    313:     case IMMEDIATE_OFFLINE:
                    314:     // NOTE: According to ATAPI 4 and UP, this command is obsolete 
                    315:          cpt.cam_flags                  = CAM_DIR_NONE;
                    316:          cpt.cam_cdb_len                = 16;
                    317:          cpt.cam_sense_len              = sizeof(sense);
                    318:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    319:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    320:          cdb->ata_pass_thru.protocol    = ATA_PROTO_DATA_NONE;
                    321:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    322:          cdb->ata_pass_thru.features    = ATA_SMART_IMMEDIATE_OFFLINE;
                    323:          cdb->ata_pass_thru.lba_low     = select;
                    324:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    325:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    326:          break;
                    327:     case STATUS_CHECK:
                    328:     // same command, no HDIO in NetBSD 
                    329:     case STATUS:
                    330:          cpt.cam_flags                  = CAM_DIR_NONE;
                    331:          cpt.cam_cdb_len                = 16;
                    332:          cpt.cam_sense_len              = sizeof(sense);
                    333:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    334:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    335:          cdb->ata_pass_thru.protocol    = ATA_PROTO_DATA_NONE;
                    336:          cdb->ata_pass_thru.flags       = ATA_FLG_CK_COND;
                    337:          cdb->ata_pass_thru.command     = ATA_SMART_CMD;
                    338:          cdb->ata_pass_thru.features    = ATA_SMART_STATUS;
                    339:          cdb->ata_pass_thru.lba_mid     = ATA_SMART_LBA_MID_SIG;
                    340:          cdb->ata_pass_thru.lba_high    = ATA_SMART_LBA_HI_SIG;
                    341:          break;
                    342:     case CHECK_POWER_MODE:
                    343:          cpt.cam_flags                  = CAM_DIR_NONE;
                    344:          cpt.cam_cdb_len                = 16;
                    345:          cpt.cam_sense_len              = sizeof(sense);
                    346:          cpt.cam_sense_ptr              = (uint32_t)&sense;
                    347:          cdb->ata_pass_thru.opcode      = SC_ATA_PT16;
                    348:          cdb->ata_pass_thru.protocol    = ATA_PROTO_DATA_NONE;
                    349:          cdb->ata_pass_thru.flags       = ATA_FLG_CK_COND;
                    350:          cdb->ata_pass_thru.command     = ATA_CHECK_POWER_MODE;
                    351:          break;
                    352:     default:
                    353:          pout("Unrecognized command %d in ata_command_interface()\n", command);
                    354:          errno=ENOSYS;
                    355:          return(-1);
                    356:    }
                    357: // execute now
                    358:   if((status=ata_pass_thru(fd,&cpt))==EOK)
                    359:    {
                    360:     rc=status==EOK?0:-1;
                    361:     if(cpt.cam_status!=CAM_REQ_CMP)
                    362:      {
                    363:       ata_interpret_sense(&cpt,&sense,&status,0);
                    364:       if(command==STATUS||command==STATUS_CHECK)
                    365:         rc=((sense.desc.lba_high<<8)|sense.desc.lba_mid)==ATA_SMART_SIG?0:1;
                    366:      }
                    367:    }
                    368:   if(command==CHECK_POWER_MODE)
                    369:     data[0]=cdb->ata_pass_thru.sector_count;
                    370: // finish
                    371:   return(rc);
                    372: }
                    373: //----------------------------------------------------------------------------------------------
                    374: int marvell_command_interface(int fd, smart_command_set command, int select, char *data)
                    375: {
                    376:   ARGUSED(fd);
                    377:   ARGUSED(command);
                    378:   ARGUSED(select);
                    379:   ARGUSED(data);
                    380:   unsupported();
                    381:   return -1;
                    382: }
                    383: //----------------------------------------------------------------------------------------------
                    384: int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
                    385: {
                    386:   ARGUSED(fd);
                    387:   ARGUSED(command);
                    388:   ARGUSED(select);
                    389:   ARGUSED(data);
                    390:   unsupported();
                    391:   return -1;
                    392: }
                    393: //----------------------------------------------------------------------------------------------
                    394: // Interface to ATA devices behind 3ware escalade/apache RAID
                    395: // controller cards.  Same description as ata_command_interface()
                    396: // above except that 0 <= disknum <= 15 specifies the ATA disk
                    397: // attached to the controller, and controller_type specifies the
                    398: // precise type of 3ware controller.  See os_linux.c
                    399: int escalade_command_interface(int fd,int disknum,int controller_type,smart_command_set command,int select,char *data)
                    400: {
                    401:   ARGUSED(fd);
                    402:   ARGUSED(disknum);
                    403:   ARGUSED(controller_type);
                    404:   ARGUSED(command);
                    405:   ARGUSED(select);
                    406:   ARGUSED(data);
                    407: 
                    408:   unsupported();
                    409:   return -1;
                    410: }
                    411: 
                    412: int areca_command_interface(int fd,int disknum,smart_command_set command,int select,char *data)
                    413: {
                    414:   ARGUSED(fd);
                    415:   ARGUSED(disknum);
                    416:   ARGUSED(command);
                    417:   ARGUSED(select);
                    418:   ARGUSED(data);
                    419: 
                    420:   unsupported();
                    421:   return -1;
                    422: }
                    423: //----------------------------------------------------------------------------------------------
                    424: // Interface to SCSI devices.  See os_linux.c
                    425: int do_scsi_cmnd_io(int fd,struct scsi_cmnd_io * iop,int report)
                    426: {
                    427:   ARGUSED(fd);
                    428:   ARGUSED(iop);
                    429:   ARGUSED(report);
                    430:   unsupported();
                    431:   return -ENOSYS;
                    432: }
                    433: //----------------------------------------------------------------------------------------------
                    434: //----------------------------------------------------------------------------------------------
                    435: static int ata_sense_data(void *sdata,int *error,int *key,int *asc,int *ascq)
                    436: {
                    437: SCSI_SENSE     *sf;
                    438: SCSI_SENSE_DESCRIPTOR  *sd;
                    439:   sf=(SCSI_SENSE *)sdata;
                    440:   sd=(SCSI_SENSE_DESCRIPTOR *)sdata;
                    441:   *error=sf->error;
                    442:   if(*error & SENSE_DATA_FMT_DESCRIPTOR)
                    443:    {
                    444:     *key=sd->sense & SK_MSK;
                    445:     *asc=sd->asc;
                    446:     *ascq=sd->ascq;
                    447:    }
                    448:   else
                    449:    {
                    450:     *key=sf->sense & SK_MSK;
                    451:     *asc=sf->asc;
                    452:     *ascq=sf->ascq;
                    453:    }
                    454:   return(CAM_SUCCESS);
                    455: }
                    456: //----------------------------------------------------------------------------------------------
                    457: static int ata_interpret_sense(struct cam_pass_thru *cpt,void *sense,int *status,int rcount)
                    458: {
                    459: int retry;
                    460: int key;
                    461: int asc;
                    462: int ascq;
                    463: int error;
                    464:   *status=EIO;
                    465:   retry=CAM_TRUE;
                    466:   if(cpt->cam_status&CAM_AUTOSNS_VALID)
                    467:    {
                    468:     ata_sense_data(sense,&error,&key,&asc,&ascq);
                    469:     switch(key)
                    470:      {
                    471:       case SK_NO_SENSE:                                        // No sense data (no error)
                    472:            retry=CAM_FALSE;
                    473:            *status=EOK;
                    474:            break;
                    475:       case SK_RECOVERED:                                       // Recovered error
                    476:           switch(asc)
                    477:             {
                    478:              case ASC_ATA_PASS_THRU:
                    479:                   switch(ascq)
                    480:                    {
                    481:                     case ASCQ_ATA_PASS_THRU_INFO_AVAIL:
                    482:                          break;
                    483:                     default:
                    484:                          break;
                    485:                    }
                    486:                   break;
                    487:              default:
                    488:                   break;
                    489:             }
                    490:            retry=CAM_FALSE;
                    491:            *status=EOK;
                    492:            break;
                    493:       case SK_NOT_RDY:                                 // Device not ready
                    494:            *status=EAGAIN;
                    495:            switch(asc)
                    496:             {
                    497:              case ASC_NOT_READY:
                    498:                   switch(ascq)
                    499:                    {
                    500:                     case ASCQ_BECOMING_READY:
                    501:                     case ASCQ_CAUSE_NOT_REPORTABLE:
                    502:                     default:
                    503:                     retry=CAM_FALSE;
                    504:                     break;
                    505:                    }
                    506:                   break;
                    507:              case ASC_MEDIA_NOT_PRESENT:
                    508:                   *status=ENXIO;
                    509:                   retry=CAM_FALSE;
                    510:                   break;
                    511:             }
                    512:            break;
                    513:       case SK_MEDIUM:                                          // Medium error
                    514:       case SK_HARDWARE:                                        // Hardware error
                    515:            retry=CAM_FALSE;
                    516:            *status=EIO;
                    517:            break;
                    518:       case SK_ILLEGAL:                                 // Illegal Request (bad command)
                    519:            retry=CAM_FALSE;
                    520:            *status=EINVAL;
                    521:            break;
                    522:       case SK_UNIT_ATN:                                        // Unit Attention
                    523:            switch(asc)
                    524:             {
                    525:              case ASC_MEDIUM_CHANGED:
                    526:                   *status=ESTALE;
                    527:                   retry=CAM_FALSE;
                    528:                   break;
                    529:              case ASC_BUS_RESET:
                    530:                   break;
                    531:             }
                    532:            break;
                    533:       case SK_DATA_PROT:                                       // Data Protect
                    534:            retry=CAM_FALSE;
                    535:            *status=EROFS;
                    536:            break;
                    537:       case SK_VENDOR:                                          // Vendor Specific
                    538:       case SK_CPY_ABORT:                                       // Copy Aborted
                    539:            retry=CAM_FALSE;
                    540:            *status=EIO;
                    541:            break;
                    542:       case SK_CMD_ABORT:                                       // Aborted Command
                    543:            retry=CAM_FALSE;
                    544:            *status=ECANCELED;
                    545:            break;
                    546:       case SK_EQUAL:                                           // Equal
                    547:       case SK_VOL_OFL:                                 // Volume Overflow
                    548:       case SK_MISCMP:                                          // Miscompare
                    549:       case SK_RESERVED:                                        // Reserved
                    550:            break; 
                    551:      }
                    552:     if(*status==EOK)
                    553:      {
                    554:       switch(cpt->cam_status&CAM_STATUS_MASK) 
                    555:        {
                    556:         case CAM_REQ_CMP_ERR:                  // CCB request completed with an err
                    557:              retry=CAM_FALSE;
                    558:              *status=EIO;
                    559:              break;
                    560:         case CAM_BUSY:                                 // CAM subsystem is busy
                    561:              *status=EAGAIN;
                    562:              break;
                    563:         case CAM_REQ_INVALID:                  // CCB request is invalid
                    564:         case CAM_PATH_INVALID:                 // Path ID supplied is invalid
                    565:         case CAM_DEV_NOT_THERE:                        // SCSI device not installed/there
                    566:         case CAM_SEL_TIMEOUT:                  // Target selection timeout
                    567:         case CAM_LUN_INVALID:                  // LUN supplied is invalid
                    568:         case CAM_TID_INVALID:                  // Target ID supplied is invalid
                    569:              retry=CAM_FALSE;
                    570:              *status=ENXIO;
                    571:              break;
                    572:         case CAM_CMD_TIMEOUT:                  // Command timeout
                    573:              *status=rcount?EAGAIN:EIO;
                    574:              break;
                    575:         case CAM_MSG_REJECT_REC:               // Message reject received
                    576:         case CAM_SCSI_BUS_RESET:               // SCSI bus reset sent/received
                    577:         case CAM_UNCOR_PARITY:                 // Uncorrectable parity err occurred
                    578:         case CAM_AUTOSENSE_FAIL:               // Autosense: Request sense cmd fail
                    579:         case CAM_NO_HBA:                               // No HBA detected Error
                    580:         case CAM_DATA_RUN_ERR:                 // Data overrun/underrun error
                    581:              retry=CAM_FALSE;
                    582:              *status=EIO;
                    583:              break;
                    584:         case CAM_UNEXP_BUSFREE:                        // Unexpected BUS free
                    585:         case CAM_SEQUENCE_FAIL:                        // Target bus phase sequence failure
                    586:              *status=EIO;
                    587:              break;
                    588:         case CAM_PROVIDE_FAIL:                 // Unable to provide requ. capability
                    589:              retry=CAM_FALSE;
                    590:              *status=ENOTTY;
                    591:              break;
                    592:         case CAM_CCB_LEN_ERR:                  // CCB length supplied is inadequate
                    593:         case CAM_BDR_SENT:                             // A SCSI BDR msg was sent to target
                    594:         case CAM_REQ_TERMIO:                   // CCB request terminated by the host
                    595:         case CAM_FUNC_NOTAVAIL:                        // The requ. func is not available
                    596:         case CAM_NO_NEXUS:                             // Nexus is not established
                    597:         case CAM_IID_INVALID:                  // The initiator ID is invalid
                    598:         case CAM_CDB_RECVD:                            // The SCSI CDB has been received
                    599:              retry=CAM_FALSE;
                    600:              *status=EIO;
                    601:              break;
                    602:         case CAM_SCSI_BUSY:                            // SCSI bus busy
                    603:              *status=EAGAIN;
                    604:              break;
                    605:        }
                    606:      }
                    607:    }
                    608:   return(retry);
                    609: }
                    610: //----------------------------------------------------------------------------------------------
                    611: static int ata_pass_thru(int fd,struct cam_pass_thru *pcpt)
                    612: {
                    613: int    icnt;
                    614: int    status;
                    615: iov_t  iov[3];
                    616: struct cam_pass_thru   cpt;
                    617:   cpt=*pcpt;
                    618:   icnt=1;
                    619:   SETIOV(&iov[0],&cpt,sizeof(cpt));
                    620:   cpt.cam_timeout=cpt.cam_timeout?cpt.cam_timeout:CAM_TIME_DEFAULT;
                    621:   if(cpt.cam_sense_len)
                    622:    {
                    623:     SETIOV(&iov[1],(void *)cpt.cam_sense_ptr,cpt.cam_sense_len);
                    624:     cpt.cam_sense_ptr=sizeof(cpt);
                    625:     icnt++;
                    626:    }
                    627:   if(cpt.cam_dxfer_len)
                    628:    {
                    629:     SETIOV(&iov[2],(void *)cpt.cam_data_ptr,cpt.cam_dxfer_len);
                    630:     cpt.cam_data_ptr=(paddr_t)sizeof(cpt)+cpt.cam_sense_len;
                    631:     icnt++;
                    632:    }
                    633:   if((status=devctlv(fd,DCMD_CAM_PASS_THRU,icnt,icnt,iov,iov,NULL)))
                    634:     pout("ata_pass_thru devctl:  %s\n",strerror(status));
                    635:   pcpt->cam_status=cpt.cam_status;
                    636:   pcpt->cam_scsi_status=cpt.cam_scsi_status;
                    637:   return(status);
                    638: }
                    639: //----------------------------------------------------------------------------------------------

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>