2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL
);
31 #include <ipxe/list.h>
32 #include <ipxe/process.h>
33 #include <ipxe/xfer.h>
34 #include <ipxe/blockdev.h>
35 #include <ipxe/scsi.h>
43 /** Maximum number of command retries */
44 #define SCSICMD_MAX_RETRIES 10
46 /* Error numbers generated by SCSI sense data */
47 #define EIO_NO_SENSE __einfo_error ( EINFO_EIO_NO_SENSE )
48 #define EINFO_EIO_NO_SENSE \
49 __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )
50 #define EIO_RECOVERED_ERROR __einfo_error ( EINFO_EIO_RECOVERED_ERROR )
51 #define EINFO_EIO_RECOVERED_ERROR \
52 __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )
53 #define EIO_NOT_READY __einfo_error ( EINFO_EIO_NOT_READY )
54 #define EINFO_EIO_NOT_READY \
55 __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )
56 #define EIO_MEDIUM_ERROR __einfo_error ( EINFO_EIO_MEDIUM_ERROR )
57 #define EINFO_EIO_MEDIUM_ERROR \
58 __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )
59 #define EIO_HARDWARE_ERROR __einfo_error ( EINFO_EIO_HARDWARE_ERROR )
60 #define EINFO_EIO_HARDWARE_ERROR \
61 __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )
62 #define EIO_ILLEGAL_REQUEST __einfo_error ( EINFO_EIO_ILLEGAL_REQUEST )
63 #define EINFO_EIO_ILLEGAL_REQUEST \
64 __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )
65 #define EIO_UNIT_ATTENTION __einfo_error ( EINFO_EIO_UNIT_ATTENTION )
66 #define EINFO_EIO_UNIT_ATTENTION \
67 __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )
68 #define EIO_DATA_PROTECT __einfo_error ( EINFO_EIO_DATA_PROTECT )
69 #define EINFO_EIO_DATA_PROTECT \
70 __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )
71 #define EIO_BLANK_CHECK __einfo_error ( EINFO_EIO_BLANK_CHECK )
72 #define EINFO_EIO_BLANK_CHECK \
73 __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )
74 #define EIO_VENDOR_SPECIFIC __einfo_error ( EINFO_EIO_VENDOR_SPECIFIC )
75 #define EINFO_EIO_VENDOR_SPECIFIC \
76 __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )
77 #define EIO_COPY_ABORTED __einfo_error ( EINFO_EIO_COPY_ABORTED )
78 #define EINFO_EIO_COPY_ABORTED \
79 __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )
80 #define EIO_ABORTED_COMMAND __einfo_error ( EINFO_EIO_ABORTED_COMMAND )
81 #define EINFO_EIO_ABORTED_COMMAND \
82 __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )
83 #define EIO_RESERVED __einfo_error ( EINFO_EIO_RESERVED )
84 #define EINFO_EIO_RESERVED \
85 __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )
86 #define EIO_VOLUME_OVERFLOW __einfo_error ( EINFO_EIO_VOLUME_OVERFLOW )
87 #define EINFO_EIO_VOLUME_OVERFLOW \
88 __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )
89 #define EIO_MISCOMPARE __einfo_error ( EINFO_EIO_MISCOMPARE )
90 #define EINFO_EIO_MISCOMPARE \
91 __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )
92 #define EIO_COMPLETED __einfo_error ( EINFO_EIO_COMPLETED )
93 #define EINFO_EIO_COMPLETED \
94 __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )
95 #define EIO_SENSE( key ) \
96 EUNIQ ( EINFO_EIO, (key), EIO_NO_SENSE, EIO_RECOVERED_ERROR, \
97 EIO_NOT_READY, EIO_MEDIUM_ERROR, EIO_HARDWARE_ERROR, \
98 EIO_ILLEGAL_REQUEST, EIO_UNIT_ATTENTION, \
99 EIO_DATA_PROTECT, EIO_BLANK_CHECK, EIO_VENDOR_SPECIFIC, \
100 EIO_COPY_ABORTED, EIO_ABORTED_COMMAND, EIO_RESERVED, \
101 EIO_VOLUME_OVERFLOW, EIO_MISCOMPARE, EIO_COMPLETED )
103 /******************************************************************************
107 ******************************************************************************
113 * @v lun_string LUN string representation
114 * @v lun LUN to fill in
115 * @ret rc Return status code
117 int scsi_parse_lun ( const char *lun_string
, struct scsi_lun
*lun
) {
121 memset ( lun
, 0, sizeof ( *lun
) );
123 p
= ( char * ) lun_string
;
124 for ( i
= 0 ; i
< 4 ; i
++ ) {
125 lun
->u16
[i
] = htons ( strtoul ( p
, &p
, 16 ) );
140 * Parse SCSI sense data
142 * @v data Raw sense data
143 * @v len Length of raw sense data
144 * @v sense Descriptor-format sense data to fill in
146 void scsi_parse_sense ( const void *data
, size_t len
,
147 struct scsi_sns_descriptor
*sense
) {
148 const union scsi_sns
*sns
= data
;
150 /* Avoid returning uninitialised data */
151 memset ( sense
, 0, sizeof ( *sense
) );
153 /* Copy, assuming descriptor-format data */
154 if ( len
< sizeof ( sns
->desc
) )
156 memcpy ( sense
, &sns
->desc
, sizeof ( *sense
) );
158 /* Convert fixed-format to descriptor-format, if applicable */
159 if ( len
< sizeof ( sns
->fixed
) )
161 if ( ! SCSI_SENSE_FIXED ( sns
->code
) )
163 sense
->additional
= sns
->fixed
.additional
;
166 /******************************************************************************
170 ******************************************************************************
176 * @v control SCSI control interface
177 * @v data SCSI data interface
178 * @v command SCSI command
179 * @ret tag Command tag, or negative error
181 int scsi_command ( struct interface
*control
, struct interface
*data
,
182 struct scsi_cmd
*command
) {
183 struct interface
*dest
;
184 scsi_command_TYPE ( void * ) *op
=
185 intf_get_dest_op ( control
, scsi_command
, &dest
);
186 void *object
= intf_object ( dest
);
190 tap
= op ( object
, data
, command
);
192 /* Default is to fail to issue the command */
201 * Report SCSI response
203 * @v interface SCSI command interface
204 * @v response SCSI response
206 void scsi_response ( struct interface
*intf
, struct scsi_rsp
*response
) {
207 struct interface
*dest
;
208 scsi_response_TYPE ( void * ) *op
=
209 intf_get_dest_op ( intf
, scsi_response
, &dest
);
210 void *object
= intf_object ( dest
);
213 op ( object
, response
);
215 /* Default is to ignore the response */
221 /******************************************************************************
223 * SCSI devices and commands
225 ******************************************************************************
230 /** Reference count */
231 struct refcnt refcnt
;
232 /** Block control interface */
233 struct interface block
;
234 /** SCSI control interface */
235 struct interface scsi
;
242 /** TEST UNIT READY interface */
243 struct interface ready
;
244 /** TEST UNIT READY process */
245 struct process process
;
247 /** List of commands */
248 struct list_head cmds
;
251 /** SCSI device flags */
252 enum scsi_device_flags
{
253 /** TEST UNIT READY has been issued */
254 SCSIDEV_UNIT_TESTED
= 0x0001,
255 /** TEST UNIT READY has completed successfully */
256 SCSIDEV_UNIT_READY
= 0x0002,
259 /** A SCSI command */
260 struct scsi_command
{
261 /** Reference count */
262 struct refcnt refcnt
;
264 struct scsi_device
*scsidev
;
265 /** List of SCSI commands */
266 struct list_head list
;
268 /** Block data interface */
269 struct interface block
;
270 /** SCSI data interface */
271 struct interface scsi
;
274 struct scsi_command_type
*type
;
275 /** Starting logical block address */
277 /** Number of blocks */
281 /** Length of data buffer */
287 unsigned int retries
;
293 /** A SCSI command type */
294 struct scsi_command_type
{
297 /** Additional working space */
300 * Construct SCSI command IU
302 * @v scsicmd SCSI command
303 * @v command SCSI command IU
305 void ( * cmd
) ( struct scsi_command
*scsicmd
,
306 struct scsi_cmd
*command
);
308 * Handle SCSI command completion
310 * @v scsicmd SCSI command
311 * @v rc Reason for completion
313 void ( * done
) ( struct scsi_command
*scsicmd
, int rc
);
317 * Get reference to SCSI device
319 * @v scsidev SCSI device
320 * @ret scsidev SCSI device
322 static inline __attribute__ (( always_inline
)) struct scsi_device
*
323 scsidev_get ( struct scsi_device
*scsidev
) {
324 ref_get ( &scsidev
->refcnt
);
329 * Drop reference to SCSI device
331 * @v scsidev SCSI device
333 static inline __attribute__ (( always_inline
)) void
334 scsidev_put ( struct scsi_device
*scsidev
) {
335 ref_put ( &scsidev
->refcnt
);
339 * Get reference to SCSI command
341 * @v scsicmd SCSI command
342 * @ret scsicmd SCSI command
344 static inline __attribute__ (( always_inline
)) struct scsi_command
*
345 scsicmd_get ( struct scsi_command
*scsicmd
) {
346 ref_get ( &scsicmd
->refcnt
);
351 * Drop reference to SCSI command
353 * @v scsicmd SCSI command
355 static inline __attribute__ (( always_inline
)) void
356 scsicmd_put ( struct scsi_command
*scsicmd
) {
357 ref_put ( &scsicmd
->refcnt
);
361 * Get SCSI command private data
363 * @v scsicmd SCSI command
364 * @ret priv Private data
366 static inline __attribute__ (( always_inline
)) void *
367 scsicmd_priv ( struct scsi_command
*scsicmd
) {
368 return scsicmd
->priv
;
374 * @v refcnt Reference count
376 static void scsicmd_free ( struct refcnt
*refcnt
) {
377 struct scsi_command
*scsicmd
=
378 container_of ( refcnt
, struct scsi_command
, refcnt
);
380 /* Remove from list of commands */
381 list_del ( &scsicmd
->list
);
382 scsidev_put ( scsicmd
->scsidev
);
391 * @v scsicmd SCSI command
392 * @v rc Reason for close
394 static void scsicmd_close ( struct scsi_command
*scsicmd
, int rc
) {
395 struct scsi_device
*scsidev
= scsicmd
->scsidev
;
398 DBGC ( scsidev
, "SCSI %p tag %08x closed: %s\n",
399 scsidev
, scsicmd
->tag
, strerror ( rc
) );
402 /* Shut down interfaces */
403 intf_shutdown ( &scsicmd
->scsi
, rc
);
404 intf_shutdown ( &scsicmd
->block
, rc
);
408 * Construct and issue SCSI command
410 * @ret rc Return status code
412 static int scsicmd_command ( struct scsi_command
*scsicmd
) {
413 struct scsi_device
*scsidev
= scsicmd
->scsidev
;
414 struct scsi_cmd command
;
418 /* Construct command */
419 memset ( &command
, 0, sizeof ( command
) );
420 memcpy ( &command
.lun
, &scsidev
->lun
, sizeof ( command
.lun
) );
421 scsicmd
->type
->cmd ( scsicmd
, &command
);
424 if ( ( tag
= scsi_command ( &scsidev
->scsi
, &scsicmd
->scsi
,
427 DBGC ( scsidev
, "SCSI %p could not issue command: %s\n",
428 scsidev
, strerror ( rc
) );
433 if ( scsicmd
->tag
) {
434 DBGC ( scsidev
, "SCSI %p tag %08x is now tag %08x\n",
435 scsidev
, scsicmd
->tag
, tag
);
438 DBGC2 ( scsidev
, "SCSI %p tag %08x %s " SCSI_CDB_FORMAT
"\n",
439 scsidev
, scsicmd
->tag
, scsicmd
->type
->name
,
440 SCSI_CDB_DATA ( command
.cdb
) );
446 * Handle SCSI command completion
448 * @v scsicmd SCSI command
449 * @v rc Reason for close
451 static void scsicmd_done ( struct scsi_command
*scsicmd
, int rc
) {
452 struct scsi_device
*scsidev
= scsicmd
->scsidev
;
454 /* Restart SCSI interface */
455 intf_restart ( &scsicmd
->scsi
, rc
);
457 /* SCSI targets have an annoying habit of returning occasional
458 * pointless "error" messages such as "power-on occurred", so
459 * we have to be prepared to retry commands.
461 if ( ( rc
!= 0 ) && ( scsicmd
->retries
++ < SCSICMD_MAX_RETRIES
) ) {
463 DBGC ( scsidev
, "SCSI %p tag %08x failed: %s\n",
464 scsidev
, scsicmd
->tag
, strerror ( rc
) );
465 DBGC ( scsidev
, "SCSI %p tag %08x retrying (retry %d)\n",
466 scsidev
, scsicmd
->tag
, scsicmd
->retries
);
467 if ( ( rc
= scsicmd_command ( scsicmd
) ) == 0 )
471 /* If we didn't (successfully) reissue the command, hand over
472 * to the command completion handler.
474 scsicmd
->type
->done ( scsicmd
, rc
);
478 * Handle SCSI response
480 * @v scsicmd SCSI command
481 * @v response SCSI response
483 static void scsicmd_response ( struct scsi_command
*scsicmd
,
484 struct scsi_rsp
*response
) {
485 struct scsi_device
*scsidev
= scsicmd
->scsidev
;
490 if ( response
->status
== 0 ) {
491 scsicmd_done ( scsicmd
, 0 );
493 DBGC ( scsidev
, "SCSI %p tag %08x status %02x",
494 scsidev
, scsicmd
->tag
, response
->status
);
495 if ( response
->overrun
> 0 ) {
496 overrun
= response
->overrun
;
497 DBGC ( scsidev
, " overrun +%zd", overrun
);
498 } else if ( response
->overrun
< 0 ) {
499 underrun
= -(response
->overrun
);
500 DBGC ( scsidev
, " underrun -%zd", underrun
);
502 DBGC ( scsidev
, " sense %02x key %02x additional %04x\n",
503 ( response
->sense
.code
& SCSI_SENSE_CODE_MASK
),
504 ( response
->sense
.key
& SCSI_SENSE_KEY_MASK
),
505 ntohs ( response
->sense
.additional
) );
507 /* Construct error number from sense data */
508 rc
= -EIO_SENSE ( response
->sense
.key
& SCSI_SENSE_KEY_MASK
);
509 scsicmd_done ( scsicmd
, rc
);
514 * Construct SCSI READ command
516 * @v scsicmd SCSI command
517 * @v command SCSI command IU
519 static void scsicmd_read_cmd ( struct scsi_command
*scsicmd
,
520 struct scsi_cmd
*command
) {
522 if ( ( scsicmd
->lba
+ scsicmd
->count
) > SCSI_MAX_BLOCK_10
) {
524 command
->cdb
.read16
.opcode
= SCSI_OPCODE_READ_16
;
525 command
->cdb
.read16
.lba
= cpu_to_be64 ( scsicmd
->lba
);
526 command
->cdb
.read16
.len
= cpu_to_be32 ( scsicmd
->count
);
529 command
->cdb
.read10
.opcode
= SCSI_OPCODE_READ_10
;
530 command
->cdb
.read10
.lba
= cpu_to_be32 ( scsicmd
->lba
);
531 command
->cdb
.read10
.len
= cpu_to_be16 ( scsicmd
->count
);
533 command
->data_in
= scsicmd
->buffer
;
534 command
->data_in_len
= scsicmd
->len
;
537 /** SCSI READ command type */
538 static struct scsi_command_type scsicmd_read
= {
540 .cmd
= scsicmd_read_cmd
,
541 .done
= scsicmd_close
,
545 * Construct SCSI WRITE command
547 * @v scsicmd SCSI command
548 * @v command SCSI command IU
550 static void scsicmd_write_cmd ( struct scsi_command
*scsicmd
,
551 struct scsi_cmd
*command
) {
553 if ( ( scsicmd
->lba
+ scsicmd
->count
) > SCSI_MAX_BLOCK_10
) {
555 command
->cdb
.write16
.opcode
= SCSI_OPCODE_WRITE_16
;
556 command
->cdb
.write16
.lba
= cpu_to_be64 ( scsicmd
->lba
);
557 command
->cdb
.write16
.len
= cpu_to_be32 ( scsicmd
->count
);
560 command
->cdb
.write10
.opcode
= SCSI_OPCODE_WRITE_10
;
561 command
->cdb
.write10
.lba
= cpu_to_be32 ( scsicmd
->lba
);
562 command
->cdb
.write10
.len
= cpu_to_be16 ( scsicmd
->count
);
564 command
->data_out
= scsicmd
->buffer
;
565 command
->data_out_len
= scsicmd
->len
;
568 /** SCSI WRITE command type */
569 static struct scsi_command_type scsicmd_write
= {
571 .cmd
= scsicmd_write_cmd
,
572 .done
= scsicmd_close
,
575 /** SCSI READ CAPACITY private data */
576 struct scsi_read_capacity_private
{
577 /** Use READ CAPACITY (16) */
579 /** Data buffer for READ CAPACITY commands */
581 /** Data buffer for READ CAPACITY (10) */
582 struct scsi_capacity_10 capacity10
;
583 /** Data buffer for READ CAPACITY (16) */
584 struct scsi_capacity_16 capacity16
;
589 * Construct SCSI READ CAPACITY command
591 * @v scsicmd SCSI command
592 * @v command SCSI command IU
594 static void scsicmd_read_capacity_cmd ( struct scsi_command
*scsicmd
,
595 struct scsi_cmd
*command
) {
596 struct scsi_read_capacity_private
*priv
= scsicmd_priv ( scsicmd
);
597 struct scsi_cdb_read_capacity_16
*readcap16
= &command
->cdb
.readcap16
;
598 struct scsi_cdb_read_capacity_10
*readcap10
= &command
->cdb
.readcap10
;
599 struct scsi_capacity_16
*capacity16
= &priv
->capacity
.capacity16
;
600 struct scsi_capacity_10
*capacity10
= &priv
->capacity
.capacity10
;
603 /* Use READ CAPACITY (16) */
604 readcap16
->opcode
= SCSI_OPCODE_SERVICE_ACTION_IN
;
605 readcap16
->service_action
=
606 SCSI_SERVICE_ACTION_READ_CAPACITY_16
;
607 readcap16
->len
= cpu_to_be32 ( sizeof ( *capacity16
) );
608 command
->data_in
= virt_to_user ( capacity16
);
609 command
->data_in_len
= sizeof ( *capacity16
);
611 /* Use READ CAPACITY (10) */
612 readcap10
->opcode
= SCSI_OPCODE_READ_CAPACITY_10
;
613 command
->data_in
= virt_to_user ( capacity10
);
614 command
->data_in_len
= sizeof ( *capacity10
);
619 * Handle SCSI READ CAPACITY command completion
621 * @v scsicmd SCSI command
622 * @v rc Reason for completion
624 static void scsicmd_read_capacity_done ( struct scsi_command
*scsicmd
,
626 struct scsi_read_capacity_private
*priv
= scsicmd_priv ( scsicmd
);
627 struct scsi_capacity_16
*capacity16
= &priv
->capacity
.capacity16
;
628 struct scsi_capacity_10
*capacity10
= &priv
->capacity
.capacity10
;
629 struct block_device_capacity capacity
;
631 /* Close if command failed */
633 scsicmd_close ( scsicmd
, rc
);
637 /* Extract capacity */
639 capacity
.blocks
= ( be64_to_cpu ( capacity16
->lba
) + 1 );
640 capacity
.blksize
= be32_to_cpu ( capacity16
->blksize
);
642 capacity
.blocks
= ( be32_to_cpu ( capacity10
->lba
) + 1 );
643 capacity
.blksize
= be32_to_cpu ( capacity10
->blksize
);
645 /* If capacity range was exceeded (i.e. capacity.lba
646 * was 0xffffffff, meaning that blockdev->blocks is
647 * now zero), use READ CAPACITY (16) instead. READ
648 * CAPACITY (16) is not mandatory, so we can't just
649 * use it straight off.
651 if ( capacity
.blocks
== 0 ) {
653 if ( ( rc
= scsicmd_command ( scsicmd
) ) != 0 ) {
654 scsicmd_close ( scsicmd
, rc
);
660 capacity
.max_count
= -1U;
662 /* Return capacity to caller */
663 block_capacity ( &scsicmd
->block
, &capacity
);
666 scsicmd_close ( scsicmd
, 0 );
669 /** SCSI READ CAPACITY command type */
670 static struct scsi_command_type scsicmd_read_capacity
= {
671 .name
= "READ CAPACITY",
672 .priv_len
= sizeof ( struct scsi_read_capacity_private
),
673 .cmd
= scsicmd_read_capacity_cmd
,
674 .done
= scsicmd_read_capacity_done
,
678 * Construct SCSI TEST UNIT READY command
680 * @v scsicmd SCSI command
681 * @v command SCSI command IU
683 static void scsicmd_test_unit_ready_cmd ( struct scsi_command
*scsicmd __unused
,
684 struct scsi_cmd
*command
) {
685 struct scsi_cdb_test_unit_ready
*testready
= &command
->cdb
.testready
;
687 testready
->opcode
= SCSI_OPCODE_TEST_UNIT_READY
;
690 /** SCSI TEST UNIT READY command type */
691 static struct scsi_command_type scsicmd_test_unit_ready
= {
692 .name
= "TEST UNIT READY",
693 .cmd
= scsicmd_test_unit_ready_cmd
,
694 .done
= scsicmd_close
,
697 /** SCSI command block interface operations */
698 static struct interface_operation scsicmd_block_op
[] = {
699 INTF_OP ( intf_close
, struct scsi_command
*, scsicmd_close
),
702 /** SCSI command block interface descriptor */
703 static struct interface_descriptor scsicmd_block_desc
=
704 INTF_DESC_PASSTHRU ( struct scsi_command
, block
,
705 scsicmd_block_op
, scsi
);
707 /** SCSI command SCSI interface operations */
708 static struct interface_operation scsicmd_scsi_op
[] = {
709 INTF_OP ( intf_close
, struct scsi_command
*, scsicmd_done
),
710 INTF_OP ( scsi_response
, struct scsi_command
*, scsicmd_response
),
713 /** SCSI command SCSI interface descriptor */
714 static struct interface_descriptor scsicmd_scsi_desc
=
715 INTF_DESC_PASSTHRU ( struct scsi_command
, scsi
,
716 scsicmd_scsi_op
, block
);
719 * Create SCSI command
721 * @v scsidev SCSI device
722 * @v block Block data interface
723 * @v type SCSI command type
724 * @v lba Starting logical block address
725 * @v count Number of blocks to transfer
726 * @v buffer Data buffer
727 * @v len Length of data buffer
728 * @ret rc Return status code
730 static int scsidev_command ( struct scsi_device
*scsidev
,
731 struct interface
*block
,
732 struct scsi_command_type
*type
,
733 uint64_t lba
, unsigned int count
,
734 userptr_t buffer
, size_t len
) {
735 struct scsi_command
*scsicmd
;
738 /* Allocate and initialise structure */
739 scsicmd
= zalloc ( sizeof ( *scsicmd
) + type
->priv_len
);
744 ref_init ( &scsicmd
->refcnt
, scsicmd_free
);
745 intf_init ( &scsicmd
->block
, &scsicmd_block_desc
, &scsicmd
->refcnt
);
746 intf_init ( &scsicmd
->scsi
, &scsicmd_scsi_desc
,
748 scsicmd
->scsidev
= scsidev_get ( scsidev
);
749 list_add ( &scsicmd
->list
, &scsidev
->cmds
);
750 scsicmd
->type
= type
;
752 scsicmd
->count
= count
;
753 scsicmd
->buffer
= buffer
;
756 /* Issue SCSI command */
757 if ( ( rc
= scsicmd_command ( scsicmd
) ) != 0 )
760 /* Attach to parent interface, mortalise self, and return */
761 intf_plug_plug ( &scsicmd
->block
, block
);
762 ref_put ( &scsicmd
->refcnt
);
766 scsicmd_close ( scsicmd
, rc
);
767 ref_put ( &scsicmd
->refcnt
);
773 * Issue SCSI block read
775 * @v scsidev SCSI device
776 * @v block Block data interface
777 * @v lba Starting logical block address
778 * @v count Number of blocks to transfer
779 * @v buffer Data buffer
780 * @v len Length of data buffer
781 * @ret rc Return status code
784 static int scsidev_read ( struct scsi_device
*scsidev
,
785 struct interface
*block
,
786 uint64_t lba
, unsigned int count
,
787 userptr_t buffer
, size_t len
) {
788 return scsidev_command ( scsidev
, block
, &scsicmd_read
,
789 lba
, count
, buffer
, len
);
793 * Issue SCSI block write
795 * @v scsidev SCSI device
796 * @v block Block data interface
797 * @v lba Starting logical block address
798 * @v count Number of blocks to transfer
799 * @v buffer Data buffer
800 * @v len Length of data buffer
801 * @ret rc Return status code
803 static int scsidev_write ( struct scsi_device
*scsidev
,
804 struct interface
*block
,
805 uint64_t lba
, unsigned int count
,
806 userptr_t buffer
, size_t len
) {
807 return scsidev_command ( scsidev
, block
, &scsicmd_write
,
808 lba
, count
, buffer
, len
);
812 * Read SCSI device capacity
814 * @v scsidev SCSI device
815 * @v block Block data interface
816 * @ret rc Return status code
818 static int scsidev_read_capacity ( struct scsi_device
*scsidev
,
819 struct interface
*block
) {
820 return scsidev_command ( scsidev
, block
, &scsicmd_read_capacity
,
825 * Test to see if SCSI device is ready
827 * @v scsidev SCSI device
828 * @v block Block data interface
829 * @ret rc Return status code
831 static int scsidev_test_unit_ready ( struct scsi_device
*scsidev
,
832 struct interface
*block
) {
833 return scsidev_command ( scsidev
, block
, &scsicmd_test_unit_ready
,
838 * Check SCSI device flow-control window
840 * @v scsidev SCSI device
841 * @ret len Length of window
843 static size_t scsidev_window ( struct scsi_device
*scsidev
) {
845 /* Refuse commands until unit is confirmed ready */
846 if ( ! ( scsidev
->flags
& SCSIDEV_UNIT_READY
) )
849 return xfer_window ( &scsidev
->scsi
);
855 * @v scsidev SCSI device
856 * @v rc Reason for close
858 static void scsidev_close ( struct scsi_device
*scsidev
, int rc
) {
859 struct scsi_command
*scsicmd
;
860 struct scsi_command
*tmp
;
863 process_del ( &scsidev
->process
);
865 /* Shut down interfaces */
866 intf_shutdown ( &scsidev
->block
, rc
);
867 intf_shutdown ( &scsidev
->scsi
, rc
);
868 intf_shutdown ( &scsidev
->ready
, rc
);
870 /* Shut down any remaining commands */
871 list_for_each_entry_safe ( scsicmd
, tmp
, &scsidev
->cmds
, list
) {
872 scsicmd_get ( scsicmd
);
873 scsicmd_close ( scsicmd
, rc
);
874 scsicmd_put ( scsicmd
);
878 /** SCSI device block interface operations */
879 static struct interface_operation scsidev_block_op
[] = {
880 INTF_OP ( xfer_window
, struct scsi_device
*, scsidev_window
),
881 INTF_OP ( block_read
, struct scsi_device
*, scsidev_read
),
882 INTF_OP ( block_write
, struct scsi_device
*, scsidev_write
),
883 INTF_OP ( block_read_capacity
, struct scsi_device
*,
884 scsidev_read_capacity
),
885 INTF_OP ( intf_close
, struct scsi_device
*, scsidev_close
),
888 /** SCSI device block interface descriptor */
889 static struct interface_descriptor scsidev_block_desc
=
890 INTF_DESC_PASSTHRU ( struct scsi_device
, block
,
891 scsidev_block_op
, scsi
);
894 * Handle SCSI TEST UNIT READY response
896 * @v scsidev SCSI device
897 * @v rc Reason for close
899 static void scsidev_ready ( struct scsi_device
*scsidev
, int rc
) {
901 /* Shut down interface */
902 intf_shutdown ( &scsidev
->ready
, rc
);
904 /* Close device on failure */
906 DBGC ( scsidev
, "SCSI %p not ready: %s\n",
907 scsidev
, strerror ( rc
) );
908 scsidev_close ( scsidev
, rc
);
912 /* Mark device as ready */
913 scsidev
->flags
|= SCSIDEV_UNIT_READY
;
914 xfer_window_changed ( &scsidev
->block
);
915 DBGC ( scsidev
, "SCSI %p unit is ready\n", scsidev
);
918 /** SCSI device TEST UNIT READY interface operations */
919 static struct interface_operation scsidev_ready_op
[] = {
920 INTF_OP ( intf_close
, struct scsi_device
*, scsidev_ready
),
923 /** SCSI device TEST UNIT READY interface descriptor */
924 static struct interface_descriptor scsidev_ready_desc
=
925 INTF_DESC ( struct scsi_device
, ready
, scsidev_ready_op
);
928 * SCSI TEST UNIT READY process
930 * @v scsidev SCSI device
932 static void scsidev_step ( struct scsi_device
*scsidev
) {
935 /* Do nothing if we have already issued TEST UNIT READY */
936 if ( scsidev
->flags
& SCSIDEV_UNIT_TESTED
)
939 /* Wait until underlying SCSI device is ready */
940 if ( xfer_window ( &scsidev
->scsi
) == 0 )
943 DBGC ( scsidev
, "SCSI %p waiting for unit to become ready\n",
946 /* Mark TEST UNIT READY as sent */
947 scsidev
->flags
|= SCSIDEV_UNIT_TESTED
;
949 /* Issue TEST UNIT READY command */
950 if ( ( rc
= scsidev_test_unit_ready ( scsidev
, &scsidev
->ready
)) !=0){
951 scsidev_close ( scsidev
, rc
);
956 /** SCSI device SCSI interface operations */
957 static struct interface_operation scsidev_scsi_op
[] = {
958 INTF_OP ( xfer_window_changed
, struct scsi_device
*, scsidev_step
),
959 INTF_OP ( intf_close
, struct scsi_device
*, scsidev_close
),
962 /** SCSI device SCSI interface descriptor */
963 static struct interface_descriptor scsidev_scsi_desc
=
964 INTF_DESC_PASSTHRU ( struct scsi_device
, scsi
,
965 scsidev_scsi_op
, block
);
967 /** SCSI device process descriptor */
968 static struct process_descriptor scsidev_process_desc
=
969 PROC_DESC_ONCE ( struct scsi_device
, process
, scsidev_step
);
974 * @v block Block control interface
975 * @v scsi SCSI control interface
977 * @ret rc Return status code
979 int scsi_open ( struct interface
*block
, struct interface
*scsi
,
980 struct scsi_lun
*lun
) {
981 struct scsi_device
*scsidev
;
983 /* Allocate and initialise structure */
984 scsidev
= zalloc ( sizeof ( *scsidev
) );
987 ref_init ( &scsidev
->refcnt
, NULL
);
988 intf_init ( &scsidev
->block
, &scsidev_block_desc
, &scsidev
->refcnt
);
989 intf_init ( &scsidev
->scsi
, &scsidev_scsi_desc
, &scsidev
->refcnt
);
990 intf_init ( &scsidev
->ready
, &scsidev_ready_desc
, &scsidev
->refcnt
);
991 process_init ( &scsidev
->process
, &scsidev_process_desc
,
993 INIT_LIST_HEAD ( &scsidev
->cmds
);
994 memcpy ( &scsidev
->lun
, lun
, sizeof ( scsidev
->lun
) );
995 DBGC ( scsidev
, "SCSI %p created for LUN " SCSI_LUN_FORMAT
"\n",
996 scsidev
, SCSI_LUN_DATA ( scsidev
->lun
) );
998 /* Attach to SCSI and parent interfaces, mortalise self, and return */
999 intf_plug_plug ( &scsidev
->scsi
, scsi
);
1000 intf_plug_plug ( &scsidev
->block
, block
);
1001 ref_put ( &scsidev
->refcnt
);