|
|
1.1 root 1: /*
2: * Copyright (C) 2006 Michael Brown <[email protected]>.
3: *
4: * This program is free software; you can redistribute it and/or
5: * modify it under the terms of the GNU General Public License as
6: * published by the Free Software Foundation; either version 2 of the
7: * License, or any later version.
8: *
9: * This program is distributed in the hope that it will be useful, but
10: * WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12: * General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with this program; if not, write to the Free Software
16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17: */
18:
19: FILE_LICENCE ( GPL2_OR_LATER );
20:
21: #include <stddef.h>
22: #include <stdlib.h>
23: #include <string.h>
24: #include <byteswap.h>
25: #include <errno.h>
26: #include <ipxe/list.h>
27: #include <ipxe/process.h>
28: #include <ipxe/xfer.h>
29: #include <ipxe/blockdev.h>
30: #include <ipxe/scsi.h>
31:
32: /** @file
33: *
34: * SCSI block device
35: *
36: */
37:
38: /** Maximum number of command retries */
39: #define SCSICMD_MAX_RETRIES 10
40:
41: /* Error numbers generated by SCSI sense data */
42: #define EIO_NO_SENSE __einfo_error ( EINFO_EIO_NO_SENSE )
43: #define EINFO_EIO_NO_SENSE \
44: __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )
45: #define EIO_RECOVERED_ERROR __einfo_error ( EINFO_EIO_RECOVERED_ERROR )
46: #define EINFO_EIO_RECOVERED_ERROR \
47: __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )
48: #define EIO_NOT_READY __einfo_error ( EINFO_EIO_NOT_READY )
49: #define EINFO_EIO_NOT_READY \
50: __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )
51: #define EIO_MEDIUM_ERROR __einfo_error ( EINFO_EIO_MEDIUM_ERROR )
52: #define EINFO_EIO_MEDIUM_ERROR \
53: __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )
54: #define EIO_HARDWARE_ERROR __einfo_error ( EINFO_EIO_HARDWARE_ERROR )
55: #define EINFO_EIO_HARDWARE_ERROR \
56: __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )
57: #define EIO_ILLEGAL_REQUEST __einfo_error ( EINFO_EIO_ILLEGAL_REQUEST )
58: #define EINFO_EIO_ILLEGAL_REQUEST \
59: __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )
60: #define EIO_UNIT_ATTENTION __einfo_error ( EINFO_EIO_UNIT_ATTENTION )
61: #define EINFO_EIO_UNIT_ATTENTION \
62: __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )
63: #define EIO_DATA_PROTECT __einfo_error ( EINFO_EIO_DATA_PROTECT )
64: #define EINFO_EIO_DATA_PROTECT \
65: __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )
66: #define EIO_BLANK_CHECK __einfo_error ( EINFO_EIO_BLANK_CHECK )
67: #define EINFO_EIO_BLANK_CHECK \
68: __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )
69: #define EIO_VENDOR_SPECIFIC __einfo_error ( EINFO_EIO_VENDOR_SPECIFIC )
70: #define EINFO_EIO_VENDOR_SPECIFIC \
71: __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )
72: #define EIO_COPY_ABORTED __einfo_error ( EINFO_EIO_COPY_ABORTED )
73: #define EINFO_EIO_COPY_ABORTED \
74: __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )
75: #define EIO_ABORTED_COMMAND __einfo_error ( EINFO_EIO_ABORTED_COMMAND )
76: #define EINFO_EIO_ABORTED_COMMAND \
77: __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )
78: #define EIO_RESERVED __einfo_error ( EINFO_EIO_RESERVED )
79: #define EINFO_EIO_RESERVED \
80: __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )
81: #define EIO_VOLUME_OVERFLOW __einfo_error ( EINFO_EIO_VOLUME_OVERFLOW )
82: #define EINFO_EIO_VOLUME_OVERFLOW \
83: __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )
84: #define EIO_MISCOMPARE __einfo_error ( EINFO_EIO_MISCOMPARE )
85: #define EINFO_EIO_MISCOMPARE \
86: __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )
87: #define EIO_COMPLETED __einfo_error ( EINFO_EIO_COMPLETED )
88: #define EINFO_EIO_COMPLETED \
89: __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )
90: #define EIO_SENSE( key ) \
91: EUNIQ ( EIO, (key), EIO_NO_SENSE, EIO_RECOVERED_ERROR, \
92: EIO_NOT_READY, EIO_MEDIUM_ERROR, EIO_HARDWARE_ERROR, \
93: EIO_ILLEGAL_REQUEST, EIO_UNIT_ATTENTION, \
94: EIO_DATA_PROTECT, EIO_BLANK_CHECK, EIO_VENDOR_SPECIFIC, \
95: EIO_COPY_ABORTED, EIO_ABORTED_COMMAND, EIO_RESERVED, \
96: EIO_VOLUME_OVERFLOW, EIO_MISCOMPARE, EIO_COMPLETED )
97:
98: /******************************************************************************
99: *
100: * Utility functions
101: *
102: ******************************************************************************
103: */
104:
105: /**
106: * Parse SCSI LUN
107: *
108: * @v lun_string LUN string representation
109: * @v lun LUN to fill in
110: * @ret rc Return status code
111: */
112: int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ) {
113: char *p;
114: int i;
115:
116: memset ( lun, 0, sizeof ( *lun ) );
117: if ( lun_string ) {
118: p = ( char * ) lun_string;
119: for ( i = 0 ; i < 4 ; i++ ) {
120: lun->u16[i] = htons ( strtoul ( p, &p, 16 ) );
121: if ( *p == '\0' )
122: break;
123: if ( *p != '-' )
124: return -EINVAL;
125: p++;
126: }
127: if ( *p )
128: return -EINVAL;
129: }
130:
131: return 0;
132: }
133:
134: /******************************************************************************
135: *
136: * Interface methods
137: *
138: ******************************************************************************
139: */
140:
141: /**
142: * Issue SCSI command
143: *
144: * @v control SCSI control interface
145: * @v data SCSI data interface
146: * @v command SCSI command
147: * @ret tag Command tag, or negative error
148: */
149: int scsi_command ( struct interface *control, struct interface *data,
150: struct scsi_cmd *command ) {
151: struct interface *dest;
152: scsi_command_TYPE ( void * ) *op =
153: intf_get_dest_op ( control, scsi_command, &dest );
154: void *object = intf_object ( dest );
155: int tap;
156:
157: if ( op ) {
158: tap = op ( object, data, command );
159: } else {
160: /* Default is to fail to issue the command */
161: tap = -EOPNOTSUPP;
162: }
163:
164: intf_put ( dest );
165: return tap;
166: }
167:
168: /**
169: * Report SCSI response
170: *
171: * @v interface SCSI command interface
172: * @v response SCSI response
173: */
174: void scsi_response ( struct interface *intf, struct scsi_rsp *response ) {
175: struct interface *dest;
176: scsi_response_TYPE ( void * ) *op =
177: intf_get_dest_op ( intf, scsi_response, &dest );
178: void *object = intf_object ( dest );
179:
180: if ( op ) {
181: op ( object, response );
182: } else {
183: /* Default is to ignore the response */
184: }
185:
186: intf_put ( dest );
187: }
188:
189: /******************************************************************************
190: *
191: * SCSI devices and commands
192: *
193: ******************************************************************************
194: */
195:
196: /** A SCSI device */
197: struct scsi_device {
198: /** Reference count */
199: struct refcnt refcnt;
200: /** Block control interface */
201: struct interface block;
202: /** SCSI control interface */
203: struct interface scsi;
204:
205: /** SCSI LUN */
206: struct scsi_lun lun;
207: /** Flags */
208: unsigned int flags;
209:
210: /** TEST UNIT READY interface */
211: struct interface ready;
212: /** TEST UNIT READY process */
213: struct process process;
214:
215: /** List of commands */
216: struct list_head cmds;
217: };
218:
219: /** SCSI device flags */
220: enum scsi_device_flags {
221: /** Unit is ready */
222: SCSIDEV_UNIT_READY = 0x0001,
223: };
224:
225: /** A SCSI command */
226: struct scsi_command {
227: /** Reference count */
228: struct refcnt refcnt;
229: /** SCSI device */
230: struct scsi_device *scsidev;
231: /** List of SCSI commands */
232: struct list_head list;
233:
234: /** Block data interface */
235: struct interface block;
236: /** SCSI data interface */
237: struct interface scsi;
238:
239: /** Command type */
240: struct scsi_command_type *type;
241: /** Starting logical block address */
242: uint64_t lba;
243: /** Number of blocks */
244: unsigned int count;
245: /** Data buffer */
246: userptr_t buffer;
247: /** Length of data buffer */
248: size_t len;
249: /** Command tag */
250: uint32_t tag;
251:
252: /** Retry count */
253: unsigned int retries;
254:
255: /** Private data */
256: uint8_t priv[0];
257: };
258:
259: /** A SCSI command type */
260: struct scsi_command_type {
261: /** Name */
262: const char *name;
263: /** Additional working space */
264: size_t priv_len;
265: /**
266: * Construct SCSI command IU
267: *
268: * @v scsicmd SCSI command
269: * @v command SCSI command IU
270: */
271: void ( * cmd ) ( struct scsi_command *scsicmd,
272: struct scsi_cmd *command );
273: /**
274: * Handle SCSI command completion
275: *
276: * @v scsicmd SCSI command
277: * @v rc Reason for completion
278: */
279: void ( * done ) ( struct scsi_command *scsicmd, int rc );
280: };
281:
282: /**
283: * Get reference to SCSI device
284: *
285: * @v scsidev SCSI device
286: * @ret scsidev SCSI device
287: */
288: static inline __attribute__ (( always_inline )) struct scsi_device *
289: scsidev_get ( struct scsi_device *scsidev ) {
290: ref_get ( &scsidev->refcnt );
291: return scsidev;
292: }
293:
294: /**
295: * Drop reference to SCSI device
296: *
297: * @v scsidev SCSI device
298: */
299: static inline __attribute__ (( always_inline )) void
300: scsidev_put ( struct scsi_device *scsidev ) {
301: ref_put ( &scsidev->refcnt );
302: }
303:
304: /**
305: * Get reference to SCSI command
306: *
307: * @v scsicmd SCSI command
308: * @ret scsicmd SCSI command
309: */
310: static inline __attribute__ (( always_inline )) struct scsi_command *
311: scsicmd_get ( struct scsi_command *scsicmd ) {
312: ref_get ( &scsicmd->refcnt );
313: return scsicmd;
314: }
315:
316: /**
317: * Drop reference to SCSI command
318: *
319: * @v scsicmd SCSI command
320: */
321: static inline __attribute__ (( always_inline )) void
322: scsicmd_put ( struct scsi_command *scsicmd ) {
323: ref_put ( &scsicmd->refcnt );
324: }
325:
326: /**
327: * Get SCSI command private data
328: *
329: * @v scsicmd SCSI command
330: * @ret priv Private data
331: */
332: static inline __attribute__ (( always_inline )) void *
333: scsicmd_priv ( struct scsi_command *scsicmd ) {
334: return scsicmd->priv;
335: }
336:
337: /**
338: * Free SCSI command
339: *
340: * @v refcnt Reference count
341: */
342: static void scsicmd_free ( struct refcnt *refcnt ) {
343: struct scsi_command *scsicmd =
344: container_of ( refcnt, struct scsi_command, refcnt );
345:
346: /* Remove from list of commands */
347: list_del ( &scsicmd->list );
348: scsidev_put ( scsicmd->scsidev );
349:
350: /* Free command */
351: free ( scsicmd );
352: }
353:
354: /**
355: * Close SCSI command
356: *
357: * @v scsicmd SCSI command
358: * @v rc Reason for close
359: */
360: static void scsicmd_close ( struct scsi_command *scsicmd, int rc ) {
361: struct scsi_device *scsidev = scsicmd->scsidev;
362:
363: if ( rc != 0 ) {
364: DBGC ( scsidev, "SCSI %p tag %08x closed: %s\n",
365: scsidev, scsicmd->tag, strerror ( rc ) );
366: }
367:
368: /* Shut down interfaces */
369: intf_shutdown ( &scsicmd->scsi, rc );
370: intf_shutdown ( &scsicmd->block, rc );
371: }
372:
373: /**
374: * Construct and issue SCSI command
375: *
376: * @ret rc Return status code
377: */
378: static int scsicmd_command ( struct scsi_command *scsicmd ) {
379: struct scsi_device *scsidev = scsicmd->scsidev;
380: struct scsi_cmd command;
381: int tag;
382: int rc;
383:
384: /* Construct command */
385: memset ( &command, 0, sizeof ( command ) );
386: memcpy ( &command.lun, &scsidev->lun, sizeof ( command.lun ) );
387: scsicmd->type->cmd ( scsicmd, &command );
388:
389: /* Issue command */
390: if ( ( tag = scsi_command ( &scsidev->scsi, &scsicmd->scsi,
391: &command ) ) < 0 ) {
392: rc = tag;
393: DBGC ( scsidev, "SCSI %p could not issue command: %s\n",
394: scsidev, strerror ( rc ) );
395: return rc;
396: }
397:
398: /* Record tag */
399: if ( scsicmd->tag ) {
400: DBGC ( scsidev, "SCSI %p tag %08x is now tag %08x\n",
401: scsidev, scsicmd->tag, tag );
402: }
403: scsicmd->tag = tag;
404: DBGC2 ( scsidev, "SCSI %p tag %08x %s " SCSI_CDB_FORMAT "\n",
405: scsidev, scsicmd->tag, scsicmd->type->name,
406: SCSI_CDB_DATA ( command.cdb ) );
407:
408: return 0;
409: }
410:
411: /**
412: * Handle SCSI command completion
413: *
414: * @v scsicmd SCSI command
415: * @v rc Reason for close
416: */
417: static void scsicmd_done ( struct scsi_command *scsicmd, int rc ) {
418: struct scsi_device *scsidev = scsicmd->scsidev;
419:
420: /* Restart SCSI interface */
421: intf_restart ( &scsicmd->scsi, rc );
422:
423: /* SCSI targets have an annoying habit of returning occasional
424: * pointless "error" messages such as "power-on occurred", so
425: * we have to be prepared to retry commands.
426: */
427: if ( ( rc != 0 ) && ( scsicmd->retries++ < SCSICMD_MAX_RETRIES ) ) {
428: /* Retry command */
429: DBGC ( scsidev, "SCSI %p tag %08x failed: %s\n",
430: scsidev, scsicmd->tag, strerror ( rc ) );
431: DBGC ( scsidev, "SCSI %p tag %08x retrying (retry %d)\n",
432: scsidev, scsicmd->tag, scsicmd->retries );
433: if ( ( rc = scsicmd_command ( scsicmd ) ) == 0 )
434: return;
435: }
436:
437: /* If we didn't (successfully) reissue the command, hand over
438: * to the command completion handler.
439: */
440: scsicmd->type->done ( scsicmd, rc );
441: }
442:
443: /**
444: * Handle SCSI response
445: *
446: * @v scsicmd SCSI command
447: * @v response SCSI response
448: */
449: static void scsicmd_response ( struct scsi_command *scsicmd,
450: struct scsi_rsp *response ) {
451: struct scsi_device *scsidev = scsicmd->scsidev;
452: size_t overrun;
453: size_t underrun;
454: int rc;
455:
456: if ( response->status == 0 ) {
457: scsicmd_done ( scsicmd, 0 );
458: } else {
459: DBGC ( scsidev, "SCSI %p tag %08x status %02x",
460: scsidev, scsicmd->tag, response->status );
461: if ( response->overrun > 0 ) {
462: overrun = response->overrun;
463: DBGC ( scsidev, " overrun +%zd", overrun );
464: } else if ( response->overrun < 0 ) {
465: underrun = -(response->overrun);
466: DBGC ( scsidev, " underrun -%zd", underrun );
467: }
468: DBGC ( scsidev, " sense %02x:%02x:%08x\n",
469: response->sense.code, response->sense.key,
470: ntohl ( response->sense.info ) );
471:
472: /* Construct error number from sense data */
473: rc = -EIO_SENSE ( response->sense.key & SCSI_SENSE_KEY_MASK );
474: scsicmd_done ( scsicmd, rc );
475: }
476: }
477:
478: /**
479: * Construct SCSI READ command
480: *
481: * @v scsicmd SCSI command
482: * @v command SCSI command IU
483: */
484: static void scsicmd_read_cmd ( struct scsi_command *scsicmd,
485: struct scsi_cmd *command ) {
486:
487: if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
488: /* Use READ (16) */
489: command->cdb.read16.opcode = SCSI_OPCODE_READ_16;
490: command->cdb.read16.lba = cpu_to_be64 ( scsicmd->lba );
491: command->cdb.read16.len = cpu_to_be32 ( scsicmd->count );
492: } else {
493: /* Use READ (10) */
494: command->cdb.read10.opcode = SCSI_OPCODE_READ_10;
495: command->cdb.read10.lba = cpu_to_be32 ( scsicmd->lba );
496: command->cdb.read10.len = cpu_to_be16 ( scsicmd->count );
497: }
498: command->data_in = scsicmd->buffer;
499: command->data_in_len = scsicmd->len;
500: }
501:
502: /** SCSI READ command type */
503: static struct scsi_command_type scsicmd_read = {
504: .name = "READ",
505: .cmd = scsicmd_read_cmd,
506: .done = scsicmd_close,
507: };
508:
509: /**
510: * Construct SCSI WRITE command
511: *
512: * @v scsicmd SCSI command
513: * @v command SCSI command IU
514: */
515: static void scsicmd_write_cmd ( struct scsi_command *scsicmd,
516: struct scsi_cmd *command ) {
517:
518: if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
519: /* Use WRITE (16) */
520: command->cdb.write16.opcode = SCSI_OPCODE_WRITE_16;
521: command->cdb.write16.lba = cpu_to_be64 ( scsicmd->lba );
522: command->cdb.write16.len = cpu_to_be32 ( scsicmd->count );
523: } else {
524: /* Use WRITE (10) */
525: command->cdb.write10.opcode = SCSI_OPCODE_WRITE_10;
526: command->cdb.write10.lba = cpu_to_be32 ( scsicmd->lba );
527: command->cdb.write10.len = cpu_to_be16 ( scsicmd->count );
528: }
529: command->data_out = scsicmd->buffer;
530: command->data_out_len = scsicmd->len;
531: }
532:
533: /** SCSI WRITE command type */
534: static struct scsi_command_type scsicmd_write = {
535: .name = "WRITE",
536: .cmd = scsicmd_write_cmd,
537: .done = scsicmd_close,
538: };
539:
540: /** SCSI READ CAPACITY private data */
541: struct scsi_read_capacity_private {
542: /** Use READ CAPACITY (16) */
543: int use16;
544: /** Data buffer for READ CAPACITY commands */
545: union {
546: /** Data buffer for READ CAPACITY (10) */
547: struct scsi_capacity_10 capacity10;
548: /** Data buffer for READ CAPACITY (16) */
549: struct scsi_capacity_16 capacity16;
550: } capacity;
551: };
552:
553: /**
554: * Construct SCSI READ CAPACITY command
555: *
556: * @v scsicmd SCSI command
557: * @v command SCSI command IU
558: */
559: static void scsicmd_read_capacity_cmd ( struct scsi_command *scsicmd,
560: struct scsi_cmd *command ) {
561: struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
562: struct scsi_cdb_read_capacity_16 *readcap16 = &command->cdb.readcap16;
563: struct scsi_cdb_read_capacity_10 *readcap10 = &command->cdb.readcap10;
564: struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
565: struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
566:
567: if ( priv->use16 ) {
568: /* Use READ CAPACITY (16) */
569: readcap16->opcode = SCSI_OPCODE_SERVICE_ACTION_IN;
570: readcap16->service_action =
571: SCSI_SERVICE_ACTION_READ_CAPACITY_16;
572: readcap16->len = cpu_to_be32 ( sizeof ( *capacity16 ) );
573: command->data_in = virt_to_user ( capacity16 );
574: command->data_in_len = sizeof ( *capacity16 );
575: } else {
576: /* Use READ CAPACITY (10) */
577: readcap10->opcode = SCSI_OPCODE_READ_CAPACITY_10;
578: command->data_in = virt_to_user ( capacity10 );
579: command->data_in_len = sizeof ( *capacity10 );
580: }
581: }
582:
583: /**
584: * Handle SCSI READ CAPACITY command completion
585: *
586: * @v scsicmd SCSI command
587: * @v rc Reason for completion
588: */
589: static void scsicmd_read_capacity_done ( struct scsi_command *scsicmd,
590: int rc ) {
591: struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
592: struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
593: struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
594: struct block_device_capacity capacity;
595:
596: /* Close if command failed */
597: if ( rc != 0 ) {
598: scsicmd_close ( scsicmd, rc );
599: return;
600: }
601:
602: /* Extract capacity */
603: if ( priv->use16 ) {
604: capacity.blocks = ( be64_to_cpu ( capacity16->lba ) + 1 );
605: capacity.blksize = be32_to_cpu ( capacity16->blksize );
606: } else {
607: capacity.blocks = ( be32_to_cpu ( capacity10->lba ) + 1 );
608: capacity.blksize = be32_to_cpu ( capacity10->blksize );
609:
610: /* If capacity range was exceeded (i.e. capacity.lba
611: * was 0xffffffff, meaning that blockdev->blocks is
612: * now zero), use READ CAPACITY (16) instead. READ
613: * CAPACITY (16) is not mandatory, so we can't just
614: * use it straight off.
615: */
616: if ( capacity.blocks == 0 ) {
617: priv->use16 = 1;
618: if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 ) {
619: scsicmd_close ( scsicmd, rc );
620: return;
621: }
622: return;
623: }
624: }
625: capacity.max_count = -1U;
626:
627: /* Return capacity to caller */
628: block_capacity ( &scsicmd->block, &capacity );
629:
630: /* Close command */
631: scsicmd_close ( scsicmd, 0 );
632: }
633:
634: /** SCSI READ CAPACITY command type */
635: static struct scsi_command_type scsicmd_read_capacity = {
636: .name = "READ CAPACITY",
637: .priv_len = sizeof ( struct scsi_read_capacity_private ),
638: .cmd = scsicmd_read_capacity_cmd,
639: .done = scsicmd_read_capacity_done,
640: };
641:
642: /**
643: * Construct SCSI TEST UNIT READY command
644: *
645: * @v scsicmd SCSI command
646: * @v command SCSI command IU
647: */
648: static void scsicmd_test_unit_ready_cmd ( struct scsi_command *scsicmd __unused,
649: struct scsi_cmd *command ) {
650: struct scsi_cdb_test_unit_ready *testready = &command->cdb.testready;
651:
652: testready->opcode = SCSI_OPCODE_TEST_UNIT_READY;
653: }
654:
655: /** SCSI TEST UNIT READY command type */
656: static struct scsi_command_type scsicmd_test_unit_ready = {
657: .name = "TEST UNIT READY",
658: .cmd = scsicmd_test_unit_ready_cmd,
659: .done = scsicmd_close,
660: };
661:
662: /** SCSI command block interface operations */
663: static struct interface_operation scsicmd_block_op[] = {
664: INTF_OP ( intf_close, struct scsi_command *, scsicmd_close ),
665: };
666:
667: /** SCSI command block interface descriptor */
668: static struct interface_descriptor scsicmd_block_desc =
669: INTF_DESC_PASSTHRU ( struct scsi_command, block,
670: scsicmd_block_op, scsi );
671:
672: /** SCSI command SCSI interface operations */
673: static struct interface_operation scsicmd_scsi_op[] = {
674: INTF_OP ( intf_close, struct scsi_command *, scsicmd_done ),
675: INTF_OP ( scsi_response, struct scsi_command *, scsicmd_response ),
676: };
677:
678: /** SCSI command SCSI interface descriptor */
679: static struct interface_descriptor scsicmd_scsi_desc =
680: INTF_DESC_PASSTHRU ( struct scsi_command, scsi,
681: scsicmd_scsi_op, block );
682:
683: /**
684: * Create SCSI command
685: *
686: * @v scsidev SCSI device
687: * @v block Block data interface
688: * @v type SCSI command type
689: * @v lba Starting logical block address
690: * @v count Number of blocks to transfer
691: * @v buffer Data buffer
692: * @v len Length of data buffer
693: * @ret rc Return status code
694: */
695: static int scsidev_command ( struct scsi_device *scsidev,
696: struct interface *block,
697: struct scsi_command_type *type,
698: uint64_t lba, unsigned int count,
699: userptr_t buffer, size_t len ) {
700: struct scsi_command *scsicmd;
701: int rc;
702:
703: /* Allocate and initialise structure */
704: scsicmd = zalloc ( sizeof ( *scsicmd ) + type->priv_len );
705: if ( ! scsicmd ) {
706: rc = -ENOMEM;
707: goto err_zalloc;
708: }
709: ref_init ( &scsicmd->refcnt, scsicmd_free );
710: intf_init ( &scsicmd->block, &scsicmd_block_desc, &scsicmd->refcnt );
711: intf_init ( &scsicmd->scsi, &scsicmd_scsi_desc,
712: &scsicmd->refcnt );
713: scsicmd->scsidev = scsidev_get ( scsidev );
714: list_add ( &scsicmd->list, &scsidev->cmds );
715: scsicmd->type = type;
716: scsicmd->lba = lba;
717: scsicmd->count = count;
718: scsicmd->buffer = buffer;
719: scsicmd->len = len;
720:
721: /* Issue SCSI command */
722: if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 )
723: goto err_command;
724:
725: /* Attach to parent interface, mortalise self, and return */
726: intf_plug_plug ( &scsicmd->block, block );
727: ref_put ( &scsicmd->refcnt );
728: return 0;
729:
730: err_command:
731: scsicmd_close ( scsicmd, rc );
732: ref_put ( &scsicmd->refcnt );
733: err_zalloc:
734: return rc;
735: }
736:
737: /**
738: * Issue SCSI block read
739: *
740: * @v scsidev SCSI device
741: * @v block Block data interface
742: * @v lba Starting logical block address
743: * @v count Number of blocks to transfer
744: * @v buffer Data buffer
745: * @v len Length of data buffer
746: * @ret rc Return status code
747:
748: */
749: static int scsidev_read ( struct scsi_device *scsidev,
750: struct interface *block,
751: uint64_t lba, unsigned int count,
752: userptr_t buffer, size_t len ) {
753: return scsidev_command ( scsidev, block, &scsicmd_read,
754: lba, count, buffer, len );
755: }
756:
757: /**
758: * Issue SCSI block write
759: *
760: * @v scsidev SCSI device
761: * @v block Block data interface
762: * @v lba Starting logical block address
763: * @v count Number of blocks to transfer
764: * @v buffer Data buffer
765: * @v len Length of data buffer
766: * @ret rc Return status code
767: */
768: static int scsidev_write ( struct scsi_device *scsidev,
769: struct interface *block,
770: uint64_t lba, unsigned int count,
771: userptr_t buffer, size_t len ) {
772: return scsidev_command ( scsidev, block, &scsicmd_write,
773: lba, count, buffer, len );
774: }
775:
776: /**
777: * Read SCSI device capacity
778: *
779: * @v scsidev SCSI device
780: * @v block Block data interface
781: * @ret rc Return status code
782: */
783: static int scsidev_read_capacity ( struct scsi_device *scsidev,
784: struct interface *block ) {
785: return scsidev_command ( scsidev, block, &scsicmd_read_capacity,
786: 0, 0, UNULL, 0 );
787: }
788:
789: /**
790: * Test to see if SCSI device is ready
791: *
792: * @v scsidev SCSI device
793: * @v block Block data interface
794: * @ret rc Return status code
795: */
796: static int scsidev_test_unit_ready ( struct scsi_device *scsidev,
797: struct interface *block ) {
798: return scsidev_command ( scsidev, block, &scsicmd_test_unit_ready,
799: 0, 0, UNULL, 0 );
800: }
801:
802: /**
803: * Check SCSI device flow-control window
804: *
805: * @v scsidev SCSI device
806: * @ret len Length of window
807: */
808: static size_t scsidev_window ( struct scsi_device *scsidev ) {
809:
810: /* Refuse commands until unit is confirmed ready */
811: if ( ! ( scsidev->flags & SCSIDEV_UNIT_READY ) )
812: return 0;
813:
814: return xfer_window ( &scsidev->scsi );
815: }
816:
817: /**
818: * Close SCSI device
819: *
820: * @v scsidev SCSI device
821: * @v rc Reason for close
822: */
823: static void scsidev_close ( struct scsi_device *scsidev, int rc ) {
824: struct scsi_command *scsicmd;
825: struct scsi_command *tmp;
826:
827: /* Stop process */
828: process_del ( &scsidev->process );
829:
830: /* Shut down interfaces */
831: intf_shutdown ( &scsidev->block, rc );
832: intf_shutdown ( &scsidev->scsi, rc );
833: intf_shutdown ( &scsidev->ready, rc );
834:
835: /* Shut down any remaining commands */
836: list_for_each_entry_safe ( scsicmd, tmp, &scsidev->cmds, list ) {
837: scsicmd_get ( scsicmd );
838: scsicmd_close ( scsicmd, rc );
839: scsicmd_put ( scsicmd );
840: }
841: }
842:
843: /** SCSI device block interface operations */
844: static struct interface_operation scsidev_block_op[] = {
845: INTF_OP ( xfer_window, struct scsi_device *, scsidev_window ),
846: INTF_OP ( block_read, struct scsi_device *, scsidev_read ),
847: INTF_OP ( block_write, struct scsi_device *, scsidev_write ),
848: INTF_OP ( block_read_capacity, struct scsi_device *,
849: scsidev_read_capacity ),
850: INTF_OP ( intf_close, struct scsi_device *, scsidev_close ),
851: };
852:
853: /** SCSI device block interface descriptor */
854: static struct interface_descriptor scsidev_block_desc =
855: INTF_DESC_PASSTHRU ( struct scsi_device, block,
856: scsidev_block_op, scsi );
857:
858: /**
859: * Handle SCSI TEST UNIT READY response
860: *
861: * @v scsidev SCSI device
862: * @v rc Reason for close
863: */
864: static void scsidev_ready ( struct scsi_device *scsidev, int rc ) {
865:
866: /* Shut down interface */
867: intf_shutdown ( &scsidev->ready, rc );
868:
869: /* Close device on failure */
870: if ( rc != 0 ) {
871: DBGC ( scsidev, "SCSI %p not ready: %s\n",
872: scsidev, strerror ( rc ) );
873: scsidev_close ( scsidev, rc );
874: return;
875: }
876:
877: /* Mark device as ready */
878: scsidev->flags |= SCSIDEV_UNIT_READY;
879: xfer_window_changed ( &scsidev->block );
880: DBGC ( scsidev, "SCSI %p unit is ready\n", scsidev );
881: }
882:
883: /** SCSI device TEST UNIT READY interface operations */
884: static struct interface_operation scsidev_ready_op[] = {
885: INTF_OP ( intf_close, struct scsi_device *, scsidev_ready ),
886: };
887:
888: /** SCSI device TEST UNIT READY interface descriptor */
889: static struct interface_descriptor scsidev_ready_desc =
890: INTF_DESC ( struct scsi_device, ready, scsidev_ready_op );
891:
892: /**
893: * SCSI TEST UNIT READY process
894: *
895: * @v process Process
896: */
897: static void scsidev_step ( struct process *process ) {
898: struct scsi_device *scsidev =
899: container_of ( process, struct scsi_device, process );
900: int rc;
901:
902: /* Wait until underlying SCSI device is ready */
903: if ( xfer_window ( &scsidev->scsi ) == 0 )
904: return;
905:
906: /* Stop process */
907: process_del ( &scsidev->process );
908:
909: DBGC ( scsidev, "SCSI %p waiting for unit to become ready\n",
910: scsidev );
911:
912: /* Issue TEST UNIT READY command */
913: if ( ( rc = scsidev_test_unit_ready ( scsidev, &scsidev->ready )) !=0){
914: scsidev_close ( scsidev, rc );
915: return;
916: }
917: }
918:
919: /** SCSI device SCSI interface operations */
920: static struct interface_operation scsidev_scsi_op[] = {
921: INTF_OP ( intf_close, struct scsi_device *, scsidev_close ),
922: };
923:
924: /** SCSI device SCSI interface descriptor */
925: static struct interface_descriptor scsidev_scsi_desc =
926: INTF_DESC_PASSTHRU ( struct scsi_device, scsi,
927: scsidev_scsi_op, block );
928:
929: /**
930: * Open SCSI device
931: *
932: * @v block Block control interface
933: * @v scsi SCSI control interface
934: * @v lun SCSI LUN
935: * @ret rc Return status code
936: */
937: int scsi_open ( struct interface *block, struct interface *scsi,
938: struct scsi_lun *lun ) {
939: struct scsi_device *scsidev;
940:
941: /* Allocate and initialise structure */
942: scsidev = zalloc ( sizeof ( *scsidev ) );
943: if ( ! scsidev )
944: return -ENOMEM;
945: ref_init ( &scsidev->refcnt, NULL );
946: intf_init ( &scsidev->block, &scsidev_block_desc, &scsidev->refcnt );
947: intf_init ( &scsidev->scsi, &scsidev_scsi_desc, &scsidev->refcnt );
948: intf_init ( &scsidev->ready, &scsidev_ready_desc, &scsidev->refcnt );
949: process_init ( &scsidev->process, scsidev_step, &scsidev->refcnt );
950: INIT_LIST_HEAD ( &scsidev->cmds );
951: memcpy ( &scsidev->lun, lun, sizeof ( scsidev->lun ) );
952: DBGC ( scsidev, "SCSI %p created for LUN " SCSI_LUN_FORMAT "\n",
953: scsidev, SCSI_LUN_DATA ( scsidev->lun ) );
954:
955: /* Attach to SCSI and parent interfaces, mortalise self, and return */
956: intf_plug_plug ( &scsidev->scsi, scsi );
957: intf_plug_plug ( &scsidev->block, block );
958: ref_put ( &scsidev->refcnt );
959: return 0;
960: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.