Indentation fix, cleanup.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / disk / scsi.c
blob92084d0f8edb20b4f5a5d463698fa98b956a943a
1 /* scsi.c - scsi support. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008,2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/disk.h>
21 #include <grub/dl.h>
22 #include <grub/kernel.h>
23 #include <grub/misc.h>
24 #include <grub/mm.h>
25 #include <grub/types.h>
26 #include <grub/scsi.h>
27 #include <grub/scsicmd.h>
28 #include <grub/time.h>
29 #include <grub/i18n.h>
31 GRUB_MOD_LICENSE ("GPLv3+");
34 static grub_scsi_dev_t grub_scsi_dev_list;
36 const char grub_scsi_names[GRUB_SCSI_NUM_SUBSYSTEMS][5] = {
37 [GRUB_SCSI_SUBSYSTEM_USBMS] = "usb",
38 [GRUB_SCSI_SUBSYSTEM_PATA] = "ata",
39 [GRUB_SCSI_SUBSYSTEM_AHCI] = "ahci"
42 void
43 grub_scsi_dev_register (grub_scsi_dev_t dev)
45 dev->next = grub_scsi_dev_list;
46 grub_scsi_dev_list = dev;
49 void
50 grub_scsi_dev_unregister (grub_scsi_dev_t dev)
52 grub_scsi_dev_t *p, q;
54 for (p = &grub_scsi_dev_list, q = *p; q; p = &(q->next), q = q->next)
55 if (q == dev)
57 *p = q->next;
58 break;
63 /* Check result of previous operation. */
64 static grub_err_t
65 grub_scsi_request_sense (grub_scsi_t scsi)
67 struct grub_scsi_request_sense rs;
68 struct grub_scsi_request_sense_data rsd;
69 grub_err_t err;
71 rs.opcode = grub_scsi_cmd_request_sense;
72 rs.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
73 rs.reserved1 = 0;
74 rs.reserved2 = 0;
75 rs.alloc_length = 0x12; /* XXX: Hardcoded for now */
76 rs.control = 0;
77 grub_memset (rs.pad, 0, sizeof(rs.pad));
79 err = scsi->dev->read (scsi, sizeof (rs), (char *) &rs,
80 sizeof (rsd), (char *) &rsd);
81 if (err)
82 return err;
84 return GRUB_ERR_NONE;
86 /* Self commenting... */
87 static grub_err_t
88 grub_scsi_test_unit_ready (grub_scsi_t scsi)
90 struct grub_scsi_test_unit_ready tur;
91 grub_err_t err;
92 grub_err_t err_sense;
94 tur.opcode = grub_scsi_cmd_test_unit_ready;
95 tur.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
96 tur.reserved1 = 0;
97 tur.reserved2 = 0;
98 tur.reserved3 = 0;
99 tur.control = 0;
100 grub_memset (tur.pad, 0, sizeof(tur.pad));
102 err = scsi->dev->read (scsi, sizeof (tur), (char *) &tur,
103 0, NULL);
105 /* Each SCSI command should be followed by Request Sense.
106 If not so, many devices STALLs or definitely freezes. */
107 err_sense = grub_scsi_request_sense (scsi);
108 if (err_sense != GRUB_ERR_NONE)
109 grub_errno = err;
110 /* err_sense is ignored for now and Request Sense Data also... */
112 if (err)
113 return err;
115 return GRUB_ERR_NONE;
118 /* Determine if the device is removable and the type of the device
119 SCSI. */
120 static grub_err_t
121 grub_scsi_inquiry (grub_scsi_t scsi)
123 struct grub_scsi_inquiry iq;
124 struct grub_scsi_inquiry_data iqd;
125 grub_err_t err;
126 grub_err_t err_sense;
128 iq.opcode = grub_scsi_cmd_inquiry;
129 iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
130 iq.page = 0;
131 iq.reserved = 0;
132 iq.alloc_length = 0x24; /* XXX: Hardcoded for now */
133 iq.control = 0;
134 grub_memset (iq.pad, 0, sizeof(iq.pad));
136 err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq,
137 sizeof (iqd), (char *) &iqd);
139 /* Each SCSI command should be followed by Request Sense.
140 If not so, many devices STALLs or definitely freezes. */
141 err_sense = grub_scsi_request_sense (scsi);
142 if (err_sense != GRUB_ERR_NONE)
143 grub_errno = err;
144 /* err_sense is ignored for now and Request Sense Data also... */
146 if (err)
147 return err;
149 scsi->devtype = iqd.devtype & GRUB_SCSI_DEVTYPE_MASK;
150 scsi->removable = iqd.rmb >> GRUB_SCSI_REMOVABLE_BIT;
152 return GRUB_ERR_NONE;
155 /* Read the capacity and block size of SCSI. */
156 static grub_err_t
157 grub_scsi_read_capacity10 (grub_scsi_t scsi)
159 struct grub_scsi_read_capacity10 rc;
160 struct grub_scsi_read_capacity10_data rcd;
161 grub_err_t err;
162 grub_err_t err_sense;
164 rc.opcode = grub_scsi_cmd_read_capacity10;
165 rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
166 rc.logical_block_addr = 0;
167 rc.reserved1 = 0;
168 rc.reserved2 = 0;
169 rc.PMI = 0;
170 rc.control = 0;
171 rc.pad = 0;
173 err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc,
174 sizeof (rcd), (char *) &rcd);
176 /* Each SCSI command should be followed by Request Sense.
177 If not so, many devices STALLs or definitely freezes. */
178 err_sense = grub_scsi_request_sense (scsi);
179 if (err_sense != GRUB_ERR_NONE)
180 grub_errno = err;
181 /* err_sense is ignored for now and Request Sense Data also... */
183 if (err)
184 return err;
186 scsi->last_block = grub_be_to_cpu32 (rcd.last_block);
187 scsi->blocksize = grub_be_to_cpu32 (rcd.blocksize);
189 return GRUB_ERR_NONE;
192 /* Read the capacity and block size of SCSI. */
193 static grub_err_t
194 grub_scsi_read_capacity16 (grub_scsi_t scsi)
196 struct grub_scsi_read_capacity16 rc;
197 struct grub_scsi_read_capacity16_data rcd;
198 grub_err_t err;
199 grub_err_t err_sense;
201 rc.opcode = grub_scsi_cmd_read_capacity16;
202 rc.lun = (scsi->lun << GRUB_SCSI_LUN_SHIFT) | 0x10;
203 rc.logical_block_addr = 0;
204 rc.alloc_len = grub_cpu_to_be32_compile_time (sizeof (rcd));
205 rc.PMI = 0;
206 rc.control = 0;
208 err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc,
209 sizeof (rcd), (char *) &rcd);
211 /* Each SCSI command should be followed by Request Sense.
212 If not so, many devices STALLs or definitely freezes. */
213 err_sense = grub_scsi_request_sense (scsi);
214 if (err_sense != GRUB_ERR_NONE)
215 grub_errno = err;
216 /* err_sense is ignored for now and Request Sense Data also... */
218 if (err)
219 return err;
221 scsi->last_block = grub_be_to_cpu64 (rcd.last_block);
222 scsi->blocksize = grub_be_to_cpu32 (rcd.blocksize);
224 return GRUB_ERR_NONE;
227 /* Send a SCSI request for DISK: read SIZE sectors starting with
228 sector SECTOR to BUF. */
229 static grub_err_t
230 grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
231 grub_size_t size, char *buf)
233 grub_scsi_t scsi;
234 struct grub_scsi_read10 rd;
235 grub_err_t err;
236 grub_err_t err_sense;
238 scsi = disk->data;
240 rd.opcode = grub_scsi_cmd_read10;
241 rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
242 rd.lba = grub_cpu_to_be32 (sector);
243 rd.reserved = 0;
244 rd.size = grub_cpu_to_be16 (size);
245 rd.reserved2 = 0;
246 rd.pad = 0;
248 err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
250 /* Each SCSI command should be followed by Request Sense.
251 If not so, many devices STALLs or definitely freezes. */
252 err_sense = grub_scsi_request_sense (scsi);
253 if (err_sense != GRUB_ERR_NONE)
254 grub_errno = err;
255 /* err_sense is ignored for now and Request Sense Data also... */
257 return err;
260 /* Send a SCSI request for DISK: read SIZE sectors starting with
261 sector SECTOR to BUF. */
262 static grub_err_t
263 grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
264 grub_size_t size, char *buf)
266 grub_scsi_t scsi;
267 struct grub_scsi_read12 rd;
268 grub_err_t err;
269 grub_err_t err_sense;
271 scsi = disk->data;
273 rd.opcode = grub_scsi_cmd_read12;
274 rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
275 rd.lba = grub_cpu_to_be32 (sector);
276 rd.size = grub_cpu_to_be32 (size);
277 rd.reserved = 0;
278 rd.control = 0;
280 err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
282 /* Each SCSI command should be followed by Request Sense.
283 If not so, many devices STALLs or definitely freezes. */
284 err_sense = grub_scsi_request_sense (scsi);
285 if (err_sense != GRUB_ERR_NONE)
286 grub_errno = err;
287 /* err_sense is ignored for now and Request Sense Data also... */
289 return err;
292 /* Send a SCSI request for DISK: read SIZE sectors starting with
293 sector SECTOR to BUF. */
294 static grub_err_t
295 grub_scsi_read16 (grub_disk_t disk, grub_disk_addr_t sector,
296 grub_size_t size, char *buf)
298 grub_scsi_t scsi;
299 struct grub_scsi_read16 rd;
300 grub_err_t err;
301 grub_err_t err_sense;
303 scsi = disk->data;
305 rd.opcode = grub_scsi_cmd_read16;
306 rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
307 rd.lba = grub_cpu_to_be64 (sector);
308 rd.size = grub_cpu_to_be32 (size);
309 rd.reserved = 0;
310 rd.control = 0;
312 err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
314 /* Each SCSI command should be followed by Request Sense.
315 If not so, many devices STALLs or definitely freezes. */
316 err_sense = grub_scsi_request_sense (scsi);
317 if (err_sense != GRUB_ERR_NONE)
318 grub_errno = err;
319 /* err_sense is ignored for now and Request Sense Data also... */
321 return err;
324 /* Send a SCSI request for DISK: write the data stored in BUF to SIZE
325 sectors starting with SECTOR. */
326 static grub_err_t
327 grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
328 grub_size_t size, const char *buf)
330 grub_scsi_t scsi;
331 struct grub_scsi_write10 wr;
332 grub_err_t err;
333 grub_err_t err_sense;
335 scsi = disk->data;
337 wr.opcode = grub_scsi_cmd_write10;
338 wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
339 wr.lba = grub_cpu_to_be32 (sector);
340 wr.reserved = 0;
341 wr.size = grub_cpu_to_be16 (size);
342 wr.reserved2 = 0;
343 wr.pad = 0;
345 err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
347 /* Each SCSI command should be followed by Request Sense.
348 If not so, many devices STALLs or definitely freezes. */
349 err_sense = grub_scsi_request_sense (scsi);
350 if (err_sense != GRUB_ERR_NONE)
351 grub_errno = err;
352 /* err_sense is ignored for now and Request Sense Data also... */
354 return err;
357 #if 0
359 /* Send a SCSI request for DISK: write the data stored in BUF to SIZE
360 sectors starting with SECTOR. */
361 static grub_err_t
362 grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
363 grub_size_t size, char *buf)
365 grub_scsi_t scsi;
366 struct grub_scsi_write12 wr;
367 grub_err_t err;
368 grub_err_t err_sense;
370 scsi = disk->data;
372 wr.opcode = grub_scsi_cmd_write12;
373 wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
374 wr.lba = grub_cpu_to_be32 (sector);
375 wr.size = grub_cpu_to_be32 (size);
376 wr.reserved = 0;
377 wr.control = 0;
379 err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
381 /* Each SCSI command should be followed by Request Sense.
382 If not so, many devices STALLs or definitely freezes. */
383 err_sense = grub_scsi_request_sense (scsi);
384 if (err_sense != GRUB_ERR_NONE)
385 grub_errno = err;
386 /* err_sense is ignored for now and Request Sense Data also... */
388 return err;
390 #endif
392 /* Send a SCSI request for DISK: write the data stored in BUF to SIZE
393 sectors starting with SECTOR. */
394 static grub_err_t
395 grub_scsi_write16 (grub_disk_t disk, grub_disk_addr_t sector,
396 grub_size_t size, const char *buf)
398 grub_scsi_t scsi;
399 struct grub_scsi_write16 wr;
400 grub_err_t err;
401 grub_err_t err_sense;
403 scsi = disk->data;
405 wr.opcode = grub_scsi_cmd_write16;
406 wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
407 wr.lba = grub_cpu_to_be64 (sector);
408 wr.size = grub_cpu_to_be32 (size);
409 wr.reserved = 0;
410 wr.control = 0;
412 err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
414 /* Each SCSI command should be followed by Request Sense.
415 If not so, many devices STALLs or definitely freezes. */
416 err_sense = grub_scsi_request_sense (scsi);
417 if (err_sense != GRUB_ERR_NONE)
418 grub_errno = err;
419 /* err_sense is ignored for now and Request Sense Data also... */
421 return err;
426 /* Context for grub_scsi_iterate. */
427 struct grub_scsi_iterate_ctx
429 grub_disk_dev_iterate_hook_t hook;
430 void *hook_data;
433 /* Helper for grub_scsi_iterate. */
434 static int
435 scsi_iterate (int id, int bus, int luns, void *data)
437 struct grub_scsi_iterate_ctx *ctx = data;
438 int i;
440 /* In case of a single LUN, just return `usbX'. */
441 if (luns == 1)
443 char *sname;
444 int ret;
445 sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus);
446 if (!sname)
447 return 1;
448 ret = ctx->hook (sname, ctx->hook_data);
449 grub_free (sname);
450 return ret;
453 /* In case of multiple LUNs, every LUN will get a prefix to
454 distinguish it. */
455 for (i = 0; i < luns; i++)
457 char *sname;
458 int ret;
459 sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i);
460 if (!sname)
461 return 1;
462 ret = ctx->hook (sname, ctx->hook_data);
463 grub_free (sname);
464 if (ret)
465 return 1;
467 return 0;
470 static int
471 grub_scsi_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
472 grub_disk_pull_t pull)
474 struct grub_scsi_iterate_ctx ctx = { hook, hook_data };
475 grub_scsi_dev_t p;
477 for (p = grub_scsi_dev_list; p; p = p->next)
478 if (p->iterate && (p->iterate) (scsi_iterate, &ctx, pull))
479 return 1;
481 return 0;
484 static grub_err_t
485 grub_scsi_open (const char *name, grub_disk_t disk)
487 grub_scsi_dev_t p;
488 grub_scsi_t scsi;
489 grub_err_t err;
490 int lun, bus;
491 grub_uint64_t maxtime;
492 const char *nameend;
493 unsigned id;
495 nameend = name + grub_strlen (name) - 1;
496 /* Try to detect a LUN ('a'-'z'), otherwise just use the first
497 LUN. */
498 if (nameend >= name && *nameend >= 'a' && *nameend <= 'z')
500 lun = *nameend - 'a';
501 nameend--;
503 else
504 lun = 0;
506 while (nameend >= name && grub_isdigit (*nameend))
507 nameend--;
509 if (!nameend[1] || !grub_isdigit (nameend[1]))
510 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
512 bus = grub_strtoul (nameend + 1, 0, 0);
514 scsi = grub_malloc (sizeof (*scsi));
515 if (! scsi)
516 return grub_errno;
518 for (id = 0; id < ARRAY_SIZE (grub_scsi_names); id++)
519 if (grub_strncmp (grub_scsi_names[id], name, nameend - name) == 0)
520 break;
522 if (id == ARRAY_SIZE (grub_scsi_names))
524 grub_free (scsi);
525 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
528 for (p = grub_scsi_dev_list; p; p = p->next)
530 if (p->open (id, bus, scsi))
532 grub_errno = GRUB_ERR_NONE;
533 continue;
536 disk->id = grub_make_scsi_id (id, bus, lun);
537 disk->data = scsi;
538 scsi->dev = p;
539 scsi->lun = lun;
540 scsi->bus = bus;
542 grub_dprintf ("scsi", "dev opened\n");
544 err = grub_scsi_inquiry (scsi);
545 if (err)
547 grub_free (scsi);
548 grub_dprintf ("scsi", "inquiry failed\n");
549 return err;
552 grub_dprintf ("scsi", "inquiry: devtype=0x%02x removable=%d\n",
553 scsi->devtype, scsi->removable);
555 /* Try to be conservative about the device types
556 supported. */
557 if (scsi->devtype != grub_scsi_devtype_direct
558 && scsi->devtype != grub_scsi_devtype_cdrom)
560 grub_free (scsi);
561 return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
562 "unknown SCSI device");
565 /* According to USB MS tests specification, issue Test Unit Ready
566 * until OK */
567 maxtime = grub_get_time_ms () + 5000; /* It is safer value */
570 /* Timeout is necessary - for example in case when we have
571 * universal card reader with more LUNs and we have only
572 * one card inserted (or none), so only one LUN (or none)
573 * will be ready - and we want not to hang... */
574 if (grub_get_time_ms () > maxtime)
576 err = GRUB_ERR_READ_ERROR;
577 grub_free (scsi);
578 grub_dprintf ("scsi", "LUN is not ready - timeout\n");
579 return err;
581 err = grub_scsi_test_unit_ready (scsi);
583 while (err == GRUB_ERR_READ_ERROR);
584 /* Reset grub_errno !
585 * It is set to some error code in loop before... */
586 grub_errno = GRUB_ERR_NONE;
588 /* Read capacity of media */
589 err = grub_scsi_read_capacity10 (scsi);
590 if (err)
592 grub_free (scsi);
593 grub_dprintf ("scsi", "READ CAPACITY10 failed\n");
594 return err;
597 if (scsi->last_block == 0xffffffff)
599 err = grub_scsi_read_capacity16 (scsi);
600 if (err)
602 grub_free (scsi);
603 grub_dprintf ("scsi", "READ CAPACITY16 failed\n");
604 return err;
608 disk->total_sectors = scsi->last_block + 1;
609 /* PATA doesn't support more than 32K reads.
610 Not sure about AHCI and USB. If it's confirmed that either of
611 them can do bigger reads reliably this value can be moved to 'scsi'
612 structure. */
613 disk->max_agglomerate = 32768 >> (GRUB_DISK_SECTOR_BITS
614 + GRUB_DISK_CACHE_BITS);
616 if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize)
618 grub_free (scsi);
619 return grub_error (GRUB_ERR_IO, "invalid sector size %d",
620 scsi->blocksize);
622 for (disk->log_sector_size = 0;
623 (1U << disk->log_sector_size) < scsi->blocksize;
624 disk->log_sector_size++);
626 grub_dprintf ("scsi", "last_block=%" PRIuGRUB_UINT64_T ", blocksize=%u\n",
627 scsi->last_block, scsi->blocksize);
628 grub_dprintf ("scsi", "Disk total sectors = %llu\n",
629 (unsigned long long) disk->total_sectors);
631 return GRUB_ERR_NONE;
634 grub_free (scsi);
635 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
638 static void
639 grub_scsi_close (grub_disk_t disk)
641 grub_scsi_t scsi;
643 scsi = disk->data;
644 if (scsi->dev->close)
645 scsi->dev->close (scsi);
646 grub_free (scsi);
649 static grub_err_t
650 grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
651 grub_size_t size, char *buf)
653 grub_scsi_t scsi;
655 scsi = disk->data;
657 grub_err_t err;
658 /* Depending on the type, select a read function. */
659 switch (scsi->devtype)
661 case grub_scsi_devtype_direct:
662 if (sector >> 32)
663 err = grub_scsi_read16 (disk, sector, size, buf);
664 else
665 err = grub_scsi_read10 (disk, sector, size, buf);
666 if (err)
667 return err;
668 break;
670 case grub_scsi_devtype_cdrom:
671 if (sector >> 32)
672 err = grub_scsi_read16 (disk, sector, size, buf);
673 else
674 err = grub_scsi_read12 (disk, sector, size, buf);
675 if (err)
676 return err;
677 break;
680 return GRUB_ERR_NONE;
682 #if 0 /* Workaround - it works - but very slowly, from some reason
683 * unknown to me (specially on OHCI). Do not use it. */
684 /* Split transfer requests to device sector size because */
685 /* some devices are not able to transfer more than 512-1024 bytes */
686 grub_err_t err = GRUB_ERR_NONE;
688 for ( ; size; size--)
690 /* Depending on the type, select a read function. */
691 switch (scsi->devtype)
693 case grub_scsi_devtype_direct:
694 err = grub_scsi_read10 (disk, sector, 1, buf);
695 break;
697 case grub_scsi_devtype_cdrom:
698 err = grub_scsi_read12 (disk, sector, 1, buf);
699 break;
701 default: /* This should not happen */
702 return GRUB_ERR_READ_ERROR;
704 if (err)
705 return err;
706 sector++;
707 buf += scsi->blocksize;
710 return err;
711 #endif
714 static grub_err_t
715 grub_scsi_write (grub_disk_t disk,
716 grub_disk_addr_t sector,
717 grub_size_t size,
718 const char *buf)
720 grub_scsi_t scsi;
722 scsi = disk->data;
724 if (scsi->devtype == grub_scsi_devtype_cdrom)
725 return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM"));
727 grub_err_t err;
728 /* Depending on the type, select a read function. */
729 switch (scsi->devtype)
731 case grub_scsi_devtype_direct:
732 if (sector >> 32)
733 err = grub_scsi_write16 (disk, sector, size, buf);
734 else
735 err = grub_scsi_write10 (disk, sector, size, buf);
736 if (err)
737 return err;
738 break;
741 return GRUB_ERR_NONE;
745 static struct grub_disk_dev grub_scsi_dev =
747 .name = "scsi",
748 .id = GRUB_DISK_DEVICE_SCSI_ID,
749 .iterate = grub_scsi_iterate,
750 .open = grub_scsi_open,
751 .close = grub_scsi_close,
752 .read = grub_scsi_read,
753 .write = grub_scsi_write,
754 .next = 0
757 GRUB_MOD_INIT(scsi)
759 grub_disk_dev_register (&grub_scsi_dev);
762 GRUB_MOD_FINI(scsi)
764 grub_disk_dev_unregister (&grub_scsi_dev);