Annotation of embedaddon/smartmontools/os_qnxnto.cpp, revision 1.1.1.1
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"
16:
17: // Needed by '-V' option (CVS versioning) of smartd/smartctl. You
18: // should have one *_H_CVSID macro appearing below for each file
19: // appearing with #include "*.h" above. Please list these (below) in
20: // alphabetic/dictionary order.
21: const char *os_XXXX_c_cvsid="$Id: os_qnxnto.cpp 3191 2010-10-27 19:55:33Z chrfranke $" \
22: ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_QNXNTO_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
23:
24:
25: // This is here to prevent compiler warnings for unused arguments of
26: // functions.
27: #define ARGUSED(x) ((void)(x))
28:
29: // Please eliminate the following block: both the #include and
30: // the 'unsupported()' function. They are only here to warn
31: // unsuspecting users that their Operating System is not supported! If
32: // you wish, you can use a similar warning mechanism for any of the
33: // functions in this file that you can not (or choose not to)
34: // implement.
35:
36:
37: #ifdef HAVE_UNAME
38: #include <sys/utsname.h>
39: #endif
40: //----------------------------------------------------------------------------------------------
41: // private Functions
42: static int ata_sense_data(void *sdata,int *error,int *key,int *asc,int *ascq);
43: static int ata_interpret_sense(struct cam_pass_thru *cpt,void *sense,int *status,int rcount);
44: static int ata_pass_thru(int fd,struct cam_pass_thru *pcpt);
45: //----------------------------------------------------------------------------------------------
46: static void unsupported(){
47: static int warninggiven;
48:
49: if (!warninggiven) {
50: char *osname;
51:
52: #ifdef HAVE_UNAME
53: struct utsname ostype;
54: uname(&ostype);
55: osname=ostype.sysname;
56: #else
57: osname="host's";
58: #endif
59:
60: pout("\n"
61: "############################################################################\n"
62: "WARNING: smartmontools has not been ported to the %s Operating System.\n"
63: "Please see the files os_generic.cpp and os_generic.h for porting instructions.\n"
64: "############################################################################\n\n",
65: osname);
66: warninggiven=1;
67: }
68:
69: return;
70: }
71: // End of the 'unsupported()' block that you should eliminate.
72:
73:
74: // print examples for smartctl. You should modify this function so
75: // that the device paths are sensible for your OS, and to eliminate
76: // unsupported commands (eg, 3ware controllers).
77: void print_smartctl_examples(){
78: printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
79: #ifdef HAVE_GETOPT_LONG
80: printf(
81: " smartctl -a /dev/hd0 (Prints all SMART information)\n\n"
82: " smartctl --smart=on --offlineauto=on --saveauto=on /dev/hd0\n"
83: " (Enables SMART on first disk)\n\n"
84: " smartctl -t long /dev/hd0 (Executes extended disk self-test)\n\n"
85: " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hd0\n"
86: " (Prints Self-Test & Attribute errors)\n"
87: " smartctl -a --device=3ware,2 /dev/sda\n"
88: " (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
89: );
90: #else
91: printf(
92: " smartctl -a /dev/hd0 (Prints all SMART information)\n"
93: " smartctl -s on -o on -S on /dev/hd0 (Enables SMART on first disk)\n"
94: " smartctl -t long /dev/hd0 (Executes extended disk self-test)\n"
95: " smartctl -A -l selftest -q errorsonly /dev/hd0\n"
96: " (Prints Self-Test & Attribute errors)\n"
97: " smartctl -a -d 3ware,2 /dev/sda\n"
98: " (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
99: );
100: #endif
101: return;
102: }
103:
104: // tries to guess device type given the name (a path). See utility.h
105: // for return values.
106: static const char *net_dev_prefix = "/dev/";
107: static const char *net_dev_ata_disk = "hd";
108:
109: int guess_device_type (const char* dev_name)
110: {
111: int len,dev_prefix_len;
112: dev_prefix_len=strlen(net_dev_prefix);
113: if(!dev_name||!(len=strlen(dev_name)))
114: return(CONTROLLER_UNKNOWN);
115: if (!strncmp(net_dev_prefix,dev_name,dev_prefix_len))
116: {
117: if(len<=dev_prefix_len)
118: return(CONTROLLER_UNKNOWN);
119: else
120: dev_name += dev_prefix_len;
121: }
122: if(!strncmp(net_dev_ata_disk,dev_name,strlen(net_dev_ata_disk)))
123: return(CONTROLLER_ATA);
124: return(CONTROLLER_UNKNOWN);
125: }
126:
127: // makes a list of ATA or SCSI devices for the DEVICESCAN directive of
128: // smartd. Returns number N of devices, or -1 if out of
129: // memory. Allocates N+1 arrays: one of N pointers (devlist); the
130: // other N arrays each contain null-terminated character strings. In
131: // the case N==0, no arrays are allocated because the array of 0
132: // pointers has zero length, equivalent to calling malloc(0).
133: int make_device_names (char*** devlist, const char* name) {
134: ARGUSED(devlist);
135: ARGUSED(name);
136: unsupported();
137: return 0;
138: }
139:
140: // Like open(). Return non-negative integer handle, only used by the
141: // functions below. type=="ATA" or "SCSI". If you need to store
142: // extra information about your devices, create a private internal
143: // array within this file (see os_freebsd.cpp for an example). If you
144: // can not open the device (permission denied, does not exist, etc)
145: // set errno as open() does and return <0.
146: int deviceopen(const char *pathname, char *type)
147: {
148: if(!strcmp(type, "ATA"))
149: return(open(pathname,O_RDWR|O_NONBLOCK));
150: else
151: return(-1);
152: }
153:
154: // Like close(). Acts only on integer handles returned by
155: // deviceopen() above.
156: int deviceclose(int fd)
157: {
158: return(close(fd));
159: }
160: //----------------------------------------------------------------------------------------------
161: // Interface to ATA devices. See os_linux.cpp for the cannonical example.
162: // DETAILED DESCRIPTION OF ARGUMENTS
163: // device: is the integer handle provided by deviceopen()
164: // command: defines the different operations, see atacmds.h
165: // select: additional input data IF NEEDED (which log, which type of
166: // self-test).
167: // data: location to write output data, IF NEEDED (1 or 512 bytes).
168: // Note: not all commands use all arguments.
169: // RETURN VALUES (for all commands BUT command==STATUS_CHECK)
170: // -1 if the command failed
171: // 0 if the command succeeded,
172: // RETURN VALUES if command==STATUS_CHECK
173: // -1 if the command failed OR the disk SMART status can't be determined
174: // 0 if the command succeeded and disk SMART status is "OK"
175: // 1 if the command succeeded and disk SMART status is "FAILING"
176: int ata_command_interface(int fd,smart_command_set command,int select,char *data)
177: {
178: struct cam_pass_thru cpt;
179: ATA_SENSE sense;
180: CDB *cdb;
181: int status,rc;
182: memset(&cpt,0x00,sizeof(struct cam_pass_thru));
183: cdb=(CDB *)cpt.cam_cdb;
184: rc=-1;
185: switch(command)
186: {
187: case READ_VALUES:
188: cpt.cam_flags = CAM_DIR_IN;
189: cpt.cam_cdb_len = 16;
190: cpt.cam_dxfer_len = 512;
191: cpt.cam_data_ptr = (uint32_t)data;
192: cpt.cam_sense_len = sizeof(sense);
193: cpt.cam_sense_ptr = (uint32_t)&sense;
194: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
195: cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
196: cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
197: cdb->ata_pass_thru.command = ATA_SMART_CMD;
198: cdb->ata_pass_thru.features = ATA_SMART_READ_VALUES;
199: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
200: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
201: break;
202: case READ_THRESHOLDS:
203: cpt.cam_flags = CAM_DIR_IN;
204: cpt.cam_cdb_len = 16;
205: cpt.cam_dxfer_len = 512;
206: cpt.cam_data_ptr = (uint32_t)data;
207: cpt.cam_sense_len = sizeof(sense);
208: cpt.cam_sense_ptr = (uint32_t)&sense;
209: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
210: cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
211: cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
212: cdb->ata_pass_thru.command = ATA_SMART_CMD;
213: cdb->ata_pass_thru.features = ATA_SMART_READ_THRESHOLDS;
214: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
215: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
216: break;
217: case READ_LOG:
218: cpt.cam_flags = CAM_DIR_IN;
219: cpt.cam_cdb_len = 16;
220: cpt.cam_dxfer_len = 512;
221: cpt.cam_data_ptr = (uint32_t)data;
222: cpt.cam_sense_len = sizeof(sense);
223: cpt.cam_sense_ptr = (uint32_t)&sense;
224: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
225: cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
226: cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
227: cdb->ata_pass_thru.command = ATA_SMART_CMD;
228: cdb->ata_pass_thru.features = ATA_SMART_READ_LOG_SECTOR;
229: cdb->ata_pass_thru.sector_count= 1;
230: cdb->ata_pass_thru.lba_low = select;
231: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
232: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
233: break;
234: case WRITE_LOG:
235: return(-1);
236: break;
237: case IDENTIFY:
238: cpt.cam_flags = CAM_DIR_IN;
239: cpt.cam_cdb_len = 16;
240: cpt.cam_dxfer_len = 512;
241: cpt.cam_data_ptr = (uint32_t)data;
242: cpt.cam_sense_len = sizeof(sense);
243: cpt.cam_sense_ptr = (uint32_t)&sense;
244: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
245: cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
246: cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
247: cdb->ata_pass_thru.command = ATA_IDENTIFY_DEVICE;
248: break;
249: case PIDENTIFY:
250: cpt.cam_flags = CAM_DIR_IN;
251: cpt.cam_cdb_len = 16;
252: cpt.cam_dxfer_len = 512;
253: cpt.cam_data_ptr = (uint32_t)data;
254: cpt.cam_sense_len = sizeof(sense);
255: cpt.cam_sense_ptr = (uint32_t)&sense;
256: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
257: cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
258: cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
259: cdb->ata_pass_thru.command = ATA_IDENTIFY_PACKET_DEVICE;
260: break;
261: case ENABLE:
262: cpt.cam_flags = CAM_DIR_NONE;
263: cpt.cam_cdb_len = 16;
264: cpt.cam_sense_len = sizeof(sense);
265: cpt.cam_sense_ptr = (uint32_t)&sense;
266: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
267: cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
268: cdb->ata_pass_thru.command = ATA_SMART_CMD;
269: cdb->ata_pass_thru.features = ATA_SMART_ENABLE;
270: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
271: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
272: break;
273: case DISABLE:
274: cpt.cam_flags = CAM_DIR_NONE;
275: cpt.cam_cdb_len = 16;
276: cpt.cam_sense_len = sizeof(sense);
277: cpt.cam_sense_ptr = (uint32_t)&sense;
278: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
279: cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
280: cdb->ata_pass_thru.command = ATA_SMART_CMD;
281: cdb->ata_pass_thru.features = ATA_SMART_DISABLE;
282: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
283: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
284: break;
285: case AUTO_OFFLINE:
286: // NOTE: According to ATAPI 4 and UP, this command is obsolete
287: cpt.cam_flags = CAM_DIR_NONE;
288: cpt.cam_cdb_len = 16;
289: cpt.cam_sense_len = sizeof(sense);
290: cpt.cam_sense_ptr = (uint32_t)&sense;
291: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
292: cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
293: cdb->ata_pass_thru.command = ATA_SMART_CMD;
294: cdb->ata_pass_thru.features = ATA_SMART_AUTO_OFFLINE;
295: cdb->ata_pass_thru.lba_low = select;
296: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
297: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
298: break;
299: case AUTOSAVE:
300: cpt.cam_flags = CAM_DIR_NONE;
301: cpt.cam_cdb_len = 16;
302: cpt.cam_sense_len = sizeof(sense);
303: cpt.cam_sense_ptr = (uint32_t)&sense;
304: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
305: cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
306: cdb->ata_pass_thru.command = ATA_SMART_CMD;
307: cdb->ata_pass_thru.features = ATA_SMART_AUTOSAVE;
308: cdb->ata_pass_thru.sector_count= select;
309: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
310: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
311: break;
312: case IMMEDIATE_OFFLINE:
313: // NOTE: According to ATAPI 4 and UP, this command is obsolete
314: cpt.cam_flags = CAM_DIR_NONE;
315: cpt.cam_cdb_len = 16;
316: cpt.cam_sense_len = sizeof(sense);
317: cpt.cam_sense_ptr = (uint32_t)&sense;
318: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
319: cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
320: cdb->ata_pass_thru.command = ATA_SMART_CMD;
321: cdb->ata_pass_thru.features = ATA_SMART_IMMEDIATE_OFFLINE;
322: cdb->ata_pass_thru.lba_low = select;
323: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
324: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
325: break;
326: case STATUS_CHECK:
327: // same command, no HDIO in NetBSD
328: case STATUS:
329: cpt.cam_flags = CAM_DIR_NONE;
330: cpt.cam_cdb_len = 16;
331: cpt.cam_sense_len = sizeof(sense);
332: cpt.cam_sense_ptr = (uint32_t)&sense;
333: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
334: cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
335: cdb->ata_pass_thru.flags = ATA_FLG_CK_COND;
336: cdb->ata_pass_thru.command = ATA_SMART_CMD;
337: cdb->ata_pass_thru.features = ATA_SMART_STATUS;
338: cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
339: cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
340: break;
341: case CHECK_POWER_MODE:
342: cpt.cam_flags = CAM_DIR_NONE;
343: cpt.cam_cdb_len = 16;
344: cpt.cam_sense_len = sizeof(sense);
345: cpt.cam_sense_ptr = (uint32_t)&sense;
346: cdb->ata_pass_thru.opcode = SC_ATA_PT16;
347: cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
348: cdb->ata_pass_thru.flags = ATA_FLG_CK_COND;
349: cdb->ata_pass_thru.command = ATA_CHECK_POWER_MODE;
350: break;
351: default:
352: pout("Unrecognized command %d in ata_command_interface()\n", command);
353: errno=ENOSYS;
354: return(-1);
355: }
356: // execute now
357: if((status=ata_pass_thru(fd,&cpt))==EOK)
358: {
359: rc=status==EOK?0:-1;
360: if(cpt.cam_status!=CAM_REQ_CMP)
361: {
362: ata_interpret_sense(&cpt,&sense,&status,0);
363: if(command==STATUS||command==STATUS_CHECK)
364: rc=((sense.desc.lba_high<<8)|sense.desc.lba_mid)==ATA_SMART_SIG?0:1;
365: }
366: }
367: if(command==CHECK_POWER_MODE)
368: data[0]=cdb->ata_pass_thru.sector_count;
369: // finish
370: return(rc);
371: }
372: //----------------------------------------------------------------------------------------------
373: int marvell_command_interface(int fd, smart_command_set command, int select, char *data)
374: {
375: ARGUSED(fd);
376: ARGUSED(command);
377: ARGUSED(select);
378: ARGUSED(data);
379: unsupported();
380: return -1;
381: }
382: //----------------------------------------------------------------------------------------------
383: int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
384: {
385: ARGUSED(fd);
386: ARGUSED(command);
387: ARGUSED(select);
388: ARGUSED(data);
389: unsupported();
390: return -1;
391: }
392: //----------------------------------------------------------------------------------------------
393: // Interface to ATA devices behind 3ware escalade/apache RAID
394: // controller cards. Same description as ata_command_interface()
395: // above except that 0 <= disknum <= 15 specifies the ATA disk
396: // attached to the controller, and controller_type specifies the
397: // precise type of 3ware controller. See os_linux.c
398: int escalade_command_interface(int fd,int disknum,int controller_type,smart_command_set command,int select,char *data)
399: {
400: ARGUSED(fd);
401: ARGUSED(disknum);
402: ARGUSED(controller_type);
403: ARGUSED(command);
404: ARGUSED(select);
405: ARGUSED(data);
406:
407: unsupported();
408: return -1;
409: }
410:
411: int areca_command_interface(int fd,int disknum,smart_command_set command,int select,char *data)
412: {
413: ARGUSED(fd);
414: ARGUSED(disknum);
415: ARGUSED(command);
416: ARGUSED(select);
417: ARGUSED(data);
418:
419: unsupported();
420: return -1;
421: }
422: //----------------------------------------------------------------------------------------------
423: #include <errno.h>
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>