Initial code release
[external/syslinux.git] / gpxe / src / drivers / block / scsi.c
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
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 <gpxe/blockdev.h>
27 #include <gpxe/process.h>
28 #include <gpxe/scsi.h>
29
30 /** @file
31  *
32  * SCSI block device
33  *
34  */
35
36 /** Maximum number of dummy "read capacity (10)" operations
37  *
38  * These are issued at connection setup to draw out various useless
39  * power-on messages.
40  */
41 #define SCSI_MAX_DUMMY_READ_CAP 10
42
43 static inline __attribute__ (( always_inline )) struct scsi_device *
44 block_to_scsi ( struct block_device *blockdev ) {
45         return container_of ( blockdev, struct scsi_device, blockdev );
46 }
47
48 /**
49  * Handle SCSI command with no backing device
50  *
51  * @v scsi              SCSI device
52  * @v command           SCSI command
53  * @ret rc              Return status code
54  */
55 int scsi_detached_command ( struct scsi_device *scsi __unused,
56                             struct scsi_command *command __unused ) {
57         return -ENODEV;
58 }
59
60 /**
61  * Issue SCSI command
62  *
63  * @v scsi              SCSI device
64  * @v command           SCSI command
65  * @ret rc              Return status code
66  */
67 static int scsi_command ( struct scsi_device *scsi,
68                           struct scsi_command *command ) {
69         int rc;
70
71         DBGC2 ( scsi, "SCSI %p " SCSI_CDB_FORMAT "\n",
72                 scsi, SCSI_CDB_DATA ( command->cdb ) );
73
74         /* Clear sense response code before issuing command */
75         command->sense_response = 0;
76
77         /* Flag command as in-progress */
78         command->rc = -EINPROGRESS;
79
80         /* Issue SCSI command */
81         if ( ( rc = scsi->command ( scsi, command ) ) != 0 ) {
82                 /* Something went wrong with the issuing mechanism */
83                 DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " err %s\n",
84                        scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) );
85                 return rc;
86         }
87
88         /* Wait for command to complete */
89         while ( command->rc == -EINPROGRESS )
90                 step();
91         if ( ( rc = command->rc ) != 0 ) {
92                 /* Something went wrong with the command execution */
93                 DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " err %s\n",
94                        scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) );
95                 return rc;
96         }
97
98         /* Check for SCSI errors */
99         if ( command->status != 0 ) {
100                 DBGC ( scsi, "SCSI %p " SCSI_CDB_FORMAT " status %02x sense "
101                        "%02x\n", scsi, SCSI_CDB_DATA ( command->cdb ),
102                        command->status, command->sense_response );
103                 return -EIO;
104         }
105
106         return 0;
107 }
108
109 /**
110  * Read block from SCSI device using READ (10)
111  *
112  * @v blockdev          Block device
113  * @v block             LBA block number
114  * @v count             Block count
115  * @v buffer            Data buffer
116  * @ret rc              Return status code
117  */
118 static int scsi_read_10 ( struct block_device *blockdev, uint64_t block,
119                           unsigned long count, userptr_t buffer ) {
120         struct scsi_device *scsi = block_to_scsi ( blockdev );
121         struct scsi_command command;
122         struct scsi_cdb_read_10 *cdb = &command.cdb.read10;
123
124         /* Issue READ (10) */
125         memset ( &command, 0, sizeof ( command ) );
126         cdb->opcode = SCSI_OPCODE_READ_10;
127         cdb->lba = cpu_to_be32 ( block );
128         cdb->len = cpu_to_be16 ( count );
129         command.data_in = buffer;
130         command.data_in_len = ( count * blockdev->blksize );
131         return scsi_command ( scsi, &command );
132 }
133
134 /**
135  * Read block from SCSI device using READ (16)
136  *
137  * @v blockdev          Block device
138  * @v block             LBA block number
139  * @v count             Block count
140  * @v buffer            Data buffer
141  * @ret rc              Return status code
142  */
143 static int scsi_read_16 ( struct block_device *blockdev, uint64_t block,
144                           unsigned long count, userptr_t buffer ) {
145         struct scsi_device *scsi = block_to_scsi ( blockdev );
146         struct scsi_command command;
147         struct scsi_cdb_read_16 *cdb = &command.cdb.read16;
148
149         /* Issue READ (16) */
150         memset ( &command, 0, sizeof ( command ) );
151         cdb->opcode = SCSI_OPCODE_READ_16;
152         cdb->lba = cpu_to_be64 ( block );
153         cdb->len = cpu_to_be32 ( count );
154         command.data_in = buffer;
155         command.data_in_len = ( count * blockdev->blksize );
156         return scsi_command ( scsi, &command );
157 }
158
159 /**
160  * Write block to SCSI device using WRITE (10)
161  *
162  * @v blockdev          Block device
163  * @v block             LBA block number
164  * @v count             Block count
165  * @v buffer            Data buffer
166  * @ret rc              Return status code
167  */
168 static int scsi_write_10 ( struct block_device *blockdev, uint64_t block,
169                            unsigned long count, userptr_t buffer ) {
170         struct scsi_device *scsi = block_to_scsi ( blockdev );
171         struct scsi_command command;
172         struct scsi_cdb_write_10 *cdb = &command.cdb.write10;
173
174         /* Issue WRITE (10) */
175         memset ( &command, 0, sizeof ( command ) );
176         cdb->opcode = SCSI_OPCODE_WRITE_10;
177         cdb->lba = cpu_to_be32 ( block );
178         cdb->len = cpu_to_be16 ( count );
179         command.data_out = buffer;
180         command.data_out_len = ( count * blockdev->blksize );
181         return scsi_command ( scsi, &command );
182 }
183
184 /**
185  * Write block to SCSI device using WRITE (16)
186  *
187  * @v blockdev          Block device
188  * @v block             LBA block number
189  * @v count             Block count
190  * @v buffer            Data buffer
191  * @ret rc              Return status code
192  */
193 static int scsi_write_16 ( struct block_device *blockdev, uint64_t block,
194                            unsigned long count, userptr_t buffer ) {
195         struct scsi_device *scsi = block_to_scsi ( blockdev );
196         struct scsi_command command;
197         struct scsi_cdb_write_16 *cdb = &command.cdb.write16;
198
199         /* Issue WRITE (16) */
200         memset ( &command, 0, sizeof ( command ) );
201         cdb->opcode = SCSI_OPCODE_WRITE_16;
202         cdb->lba = cpu_to_be64 ( block );
203         cdb->len = cpu_to_be32 ( count );
204         command.data_out = buffer;
205         command.data_out_len = ( count * blockdev->blksize );
206         return scsi_command ( scsi, &command );
207 }
208
209 /**
210  * Read capacity of SCSI device via READ CAPACITY (10)
211  *
212  * @v blockdev          Block device
213  * @ret rc              Return status code
214  */
215 static int scsi_read_capacity_10 ( struct block_device *blockdev ) {
216         struct scsi_device *scsi = block_to_scsi ( blockdev );
217         struct scsi_command command;
218         struct scsi_cdb_read_capacity_10 *cdb = &command.cdb.readcap10;
219         struct scsi_capacity_10 capacity;
220         int rc;
221
222         /* Issue READ CAPACITY (10) */
223         memset ( &command, 0, sizeof ( command ) );
224         cdb->opcode = SCSI_OPCODE_READ_CAPACITY_10;
225         command.data_in = virt_to_user ( &capacity );
226         command.data_in_len = sizeof ( capacity );
227
228         if ( ( rc = scsi_command ( scsi, &command ) ) != 0 )
229                 return rc;
230
231         /* Fill in block device fields */
232         blockdev->blksize = be32_to_cpu ( capacity.blksize );
233         blockdev->blocks = ( be32_to_cpu ( capacity.lba ) + 1 );
234
235         return 0;
236 }
237
238 /**
239  * Read capacity of SCSI device via READ CAPACITY (16)
240  *
241  * @v blockdev          Block device
242  * @ret rc              Return status code
243  */
244 static int scsi_read_capacity_16 ( struct block_device *blockdev ) {
245         struct scsi_device *scsi = block_to_scsi ( blockdev );
246         struct scsi_command command;
247         struct scsi_cdb_read_capacity_16 *cdb = &command.cdb.readcap16;
248         struct scsi_capacity_16 capacity;
249         int rc;
250
251         /* Issue READ CAPACITY (16) */
252         memset ( &command, 0, sizeof ( command ) );
253         cdb->opcode = SCSI_OPCODE_SERVICE_ACTION_IN;
254         cdb->service_action = SCSI_SERVICE_ACTION_READ_CAPACITY_16;
255         cdb->len = cpu_to_be32 ( sizeof ( capacity ) );
256         command.data_in = virt_to_user ( &capacity );
257         command.data_in_len = sizeof ( capacity );
258
259         if ( ( rc = scsi_command ( scsi, &command ) ) != 0 )
260                 return rc;
261
262         /* Fill in block device fields */
263         blockdev->blksize = be32_to_cpu ( capacity.blksize );
264         blockdev->blocks = ( be64_to_cpu ( capacity.lba ) + 1 );
265         return 0;
266 }
267
268 static struct block_device_operations scsi_operations_16 = {
269         .read   = scsi_read_16,
270         .write  = scsi_write_16,
271 };
272
273 static struct block_device_operations scsi_operations_10 = {
274         .read   = scsi_read_10,
275         .write  = scsi_write_10,
276 };
277
278 /**
279  * Initialise SCSI device
280  *
281  * @v scsi              SCSI device
282  * @ret rc              Return status code
283  *
284  * Initialises a SCSI device.  The scsi_device::command and
285  * scsi_device::lun fields must already be filled in.  This function
286  * will configure scsi_device::blockdev, including issuing a READ
287  * CAPACITY call to determine the block size and total device size.
288  */
289 int init_scsidev ( struct scsi_device *scsi ) {
290         unsigned int i;
291         int rc;
292
293         /* Issue some theoretically extraneous READ CAPACITY (10)
294          * commands, solely in order to draw out the "CHECK CONDITION
295          * (power-on occurred)", "CHECK CONDITION (reported LUNs data
296          * has changed)" etc. that some dumb targets insist on sending
297          * as an error at start of day.  The precise command that we
298          * use is unimportant; we just need to provide the target with
299          * an opportunity to send its responses.
300          */
301         for ( i = 0 ; i < SCSI_MAX_DUMMY_READ_CAP ; i++ ) {
302                 if ( ( rc = scsi_read_capacity_10 ( &scsi->blockdev ) ) == 0 )
303                         break;
304                 DBGC ( scsi, "SCSI %p ignoring start-of-day error (#%d)\n",
305                        scsi, ( i + 1 ) );
306         }
307
308         /* Try READ CAPACITY (10), which is a mandatory command, first. */
309         scsi->blockdev.op = &scsi_operations_10;
310         if ( ( rc = scsi_read_capacity_10 ( &scsi->blockdev ) ) != 0 ) {
311                 DBGC ( scsi, "SCSI %p could not READ CAPACITY (10): %s\n",
312                        scsi, strerror ( rc ) );
313                 return rc;
314         }
315
316         /* If capacity range was exceeded (i.e. capacity.lba was
317          * 0xffffffff, meaning that blockdev->blocks is now zero), use
318          * READ CAPACITY (16) instead.  READ CAPACITY (16) is not
319          * mandatory, so we can't just use it straight off.
320          */
321         if ( scsi->blockdev.blocks == 0 ) {
322                 scsi->blockdev.op = &scsi_operations_16;
323                 if ( ( rc = scsi_read_capacity_16 ( &scsi->blockdev ) ) != 0 ){
324                         DBGC ( scsi, "SCSI %p could not READ CAPACITY (16): "
325                                "%s\n", scsi, strerror ( rc ) );
326                         return rc;
327                 }
328         }
329
330         DBGC ( scsi, "SCSI %p using READ/WRITE (%d) commands\n", scsi,
331                ( ( scsi->blockdev.op == &scsi_operations_10 ) ? 10 : 16 ) );
332         DBGC ( scsi, "SCSI %p capacity is %ld MB (%#llx blocks)\n", scsi,
333                ( ( unsigned long ) ( scsi->blockdev.blocks >> 11 ) ),
334                scsi->blockdev.blocks );
335
336         return 0;
337 }
338
339 /**
340  * Parse SCSI LUN
341  *
342  * @v lun_string        LUN string representation
343  * @v lun               LUN to fill in
344  * @ret rc              Return status code
345  */
346 int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ) {
347         char *p;
348         int i;
349
350         memset ( lun, 0, sizeof ( *lun ) );
351         if ( lun_string ) {
352                 p = ( char * ) lun_string;
353                 for ( i = 0 ; i < 4 ; i++ ) {
354                         lun->u16[i] = htons ( strtoul ( p, &p, 16 ) );
355                         if ( *p == '\0' )
356                                 break;
357                         if ( *p != '-' )
358                                 return -EINVAL;
359                         p++;
360                 }
361                 if ( *p )
362                         return -EINVAL;
363         }
364
365         return 0;
366 }