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., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <gpxe/blockdev.h>
24 #include <gpxe/scsi.h>
32 static inline __attribute__ (( always_inline
)) struct scsi_device
*
33 block_to_scsi ( struct block_device
*blockdev
) {
34 return container_of ( blockdev
, struct scsi_device
, blockdev
);
41 * @v command SCSI command
42 * @ret rc Return status code
44 static int scsi_command ( struct scsi_device
*scsi
,
45 struct scsi_command
*command
) {
48 /* Clear sense response code before issuing command */
49 command
->sense_response
= 0;
51 /* Issue SCSI command */
52 if ( ( rc
= scsi
->command ( scsi
, command
) ) != 0 ) {
53 /* Something went wrong with the issuing mechanism,
54 * (rather than with the command itself)
56 DBG ( "SCSI %p " SCSI_CDB_FORMAT
" err %d\n",
57 scsi
, SCSI_CDB_DATA ( command
->cdb
), rc
);
61 /* Check for SCSI errors */
62 if ( command
->status
!= 0 ) {
63 DBG ( "SCSI %p " SCSI_CDB_FORMAT
" status %02x sense %02x\n",
64 scsi
, SCSI_CDB_DATA ( command
->cdb
),
65 command
->status
, command
->sense_response
);
73 * Read block from SCSI device using READ (10)
75 * @v blockdev Block device
76 * @v block LBA block number
77 * @v count Block count
78 * @v buffer Data buffer
79 * @ret rc Return status code
81 static int scsi_read_10 ( struct block_device
*blockdev
, uint64_t block
,
82 unsigned long count
, userptr_t buffer
) {
83 struct scsi_device
*scsi
= block_to_scsi ( blockdev
);
84 struct scsi_command command
;
85 struct scsi_cdb_read_10
*cdb
= &command
.cdb
.read10
;
88 memset ( &command
, 0, sizeof ( command
) );
89 cdb
->opcode
= SCSI_OPCODE_READ_10
;
90 cdb
->lba
= cpu_to_be32 ( block
);
91 cdb
->len
= cpu_to_be16 ( count
);
92 command
.data_in
= buffer
;
93 command
.data_in_len
= ( count
* blockdev
->blksize
);
94 return scsi_command ( scsi
, &command
);
98 * Read block from SCSI device using READ (16)
100 * @v blockdev Block device
101 * @v block LBA block number
102 * @v count Block count
103 * @v buffer Data buffer
104 * @ret rc Return status code
106 static int scsi_read_16 ( struct block_device
*blockdev
, uint64_t block
,
107 unsigned long count
, userptr_t buffer
) {
108 struct scsi_device
*scsi
= block_to_scsi ( blockdev
);
109 struct scsi_command command
;
110 struct scsi_cdb_read_16
*cdb
= &command
.cdb
.read16
;
112 /* Issue READ (16) */
113 memset ( &command
, 0, sizeof ( command
) );
114 cdb
->opcode
= SCSI_OPCODE_READ_16
;
115 cdb
->lba
= cpu_to_be64 ( block
);
116 cdb
->len
= cpu_to_be32 ( count
);
117 command
.data_in
= buffer
;
118 command
.data_in_len
= ( count
* blockdev
->blksize
);
119 return scsi_command ( scsi
, &command
);
123 * Write block to SCSI device using WRITE (10)
125 * @v blockdev Block device
126 * @v block LBA block number
127 * @v count Block count
128 * @v buffer Data buffer
129 * @ret rc Return status code
131 static int scsi_write_10 ( struct block_device
*blockdev
, uint64_t block
,
132 unsigned long count
, userptr_t buffer
) {
133 struct scsi_device
*scsi
= block_to_scsi ( blockdev
);
134 struct scsi_command command
;
135 struct scsi_cdb_write_10
*cdb
= &command
.cdb
.write10
;
137 /* Issue WRITE (10) */
138 memset ( &command
, 0, sizeof ( command
) );
139 cdb
->opcode
= SCSI_OPCODE_WRITE_10
;
140 cdb
->lba
= cpu_to_be32 ( block
);
141 cdb
->len
= cpu_to_be16 ( count
);
142 command
.data_out
= buffer
;
143 command
.data_out_len
= ( count
* blockdev
->blksize
);
144 return scsi_command ( scsi
, &command
);
148 * Write block to SCSI device using WRITE (16)
150 * @v blockdev Block device
151 * @v block LBA block number
152 * @v count Block count
153 * @v buffer Data buffer
154 * @ret rc Return status code
156 static int scsi_write_16 ( struct block_device
*blockdev
, uint64_t block
,
157 unsigned long count
, userptr_t buffer
) {
158 struct scsi_device
*scsi
= block_to_scsi ( blockdev
);
159 struct scsi_command command
;
160 struct scsi_cdb_write_16
*cdb
= &command
.cdb
.write16
;
162 /* Issue WRITE (16) */
163 memset ( &command
, 0, sizeof ( command
) );
164 cdb
->opcode
= SCSI_OPCODE_WRITE_16
;
165 cdb
->lba
= cpu_to_be64 ( block
);
166 cdb
->len
= cpu_to_be32 ( count
);
167 command
.data_out
= buffer
;
168 command
.data_out_len
= ( count
* blockdev
->blksize
);
169 return scsi_command ( scsi
, &command
);
173 * Read capacity of SCSI device via READ CAPACITY (10)
175 * @v blockdev Block device
176 * @ret rc Return status code
178 static int scsi_read_capacity_10 ( struct block_device
*blockdev
) {
179 struct scsi_device
*scsi
= block_to_scsi ( blockdev
);
180 struct scsi_command command
;
181 struct scsi_cdb_read_capacity_10
*cdb
= &command
.cdb
.readcap10
;
182 struct scsi_capacity_10 capacity
;
185 /* Issue READ CAPACITY (10) */
186 memset ( &command
, 0, sizeof ( command
) );
187 cdb
->opcode
= SCSI_OPCODE_READ_CAPACITY_10
;
188 command
.data_in
= virt_to_user ( &capacity
);
189 command
.data_in_len
= sizeof ( capacity
);
191 if ( ( rc
= scsi_command ( scsi
, &command
) ) != 0 )
194 /* Fill in block device fields */
195 blockdev
->blksize
= be32_to_cpu ( capacity
.blksize
);
196 blockdev
->blocks
= ( be32_to_cpu ( capacity
.lba
) + 1 );
202 * Read capacity of SCSI device via READ CAPACITY (16)
204 * @v blockdev Block device
205 * @ret rc Return status code
207 static int scsi_read_capacity_16 ( struct block_device
*blockdev
) {
208 struct scsi_device
*scsi
= block_to_scsi ( blockdev
);
209 struct scsi_command command
;
210 struct scsi_cdb_read_capacity_16
*cdb
= &command
.cdb
.readcap16
;
211 struct scsi_capacity_16 capacity
;
214 /* Issue READ CAPACITY (16) */
215 memset ( &command
, 0, sizeof ( command
) );
216 cdb
->opcode
= SCSI_OPCODE_SERVICE_ACTION_IN
;
217 cdb
->service_action
= SCSI_SERVICE_ACTION_READ_CAPACITY_16
;
218 cdb
->len
= cpu_to_be32 ( sizeof ( capacity
) );
219 command
.data_in
= virt_to_user ( &capacity
);
220 command
.data_in_len
= sizeof ( capacity
);
222 if ( ( rc
= scsi_command ( scsi
, &command
) ) != 0 )
225 /* Fill in block device fields */
226 blockdev
->blksize
= be32_to_cpu ( capacity
.blksize
);
227 blockdev
->blocks
= ( be64_to_cpu ( capacity
.lba
) + 1 );
232 * Initialise SCSI device
234 * @v scsi SCSI device
235 * @ret rc Return status code
237 * Initialises a SCSI device. The scsi_device::command and
238 * scsi_device::lun fields must already be filled in. This function
239 * will configure scsi_device::blockdev, including issuing a READ
240 * CAPACITY call to determine the block size and total device size.
242 int init_scsidev ( struct scsi_device
*scsi
) {
245 /* Issue a theoretically extraneous READ CAPACITY (10)
246 * command, solely in order to draw out the "CHECK CONDITION
247 * (power-on occurred)" that some dumb targets insist on
248 * sending as an error at start of day.
250 scsi_read_capacity_10 ( &scsi
->blockdev
);
252 /* Try READ CAPACITY (10), which is a mandatory command, first. */
253 scsi
->blockdev
.read
= scsi_read_10
;
254 scsi
->blockdev
.write
= scsi_write_10
;
255 if ( ( rc
= scsi_read_capacity_10 ( &scsi
->blockdev
) ) != 0 )
258 /* If capacity range was exceeded (i.e. capacity.lba was
259 * 0xffffffff, meaning that blockdev->blocks is now zero), use
260 * READ CAPACITY (16) instead. READ CAPACITY (16) is not
261 * mandatory, so we can't just use it straight off.
263 if ( scsi
->blockdev
.blocks
== 0 ) {
264 scsi
->blockdev
.read
= scsi_read_16
;
265 scsi
->blockdev
.write
= scsi_write_16
;
266 if ( ( rc
= scsi_read_capacity_16 ( &scsi
->blockdev
) ) != 0 )