1 /* ata.c - ATA disk access. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2007, 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/>.
22 #include <grub/disk.h>
24 #include <grub/time.h>
26 #include <grub/scsi.h>
28 /* At the moment, only two IDE ports are supported. */
29 static const int grub_ata_ioaddress
[] = { 0x1f0, 0x170 };
30 static const int grub_ata_ioaddress2
[] = { 0x3f6, 0x376 };
32 static struct grub_ata_device
*grub_ata_devices
;
36 grub_ata_wait_not_busy (struct grub_ata_device
*dev
, int milliseconds
)
38 /* ATA requires 400ns (after a write to CMD register) or
39 1 PIO cycle (after a DRQ block transfer) before
40 first check of BSY. */
45 while ((sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
))
46 & GRUB_ATA_STATUS_BUSY
)
48 if (i
>= milliseconds
)
50 grub_dprintf ("ata", "timeout: %dms, status=0x%x\n",
52 return grub_error (GRUB_ERR_TIMEOUT
, "ATA timeout");
68 /* Wait for !BSY, DRQ. */
70 grub_ata_wait_drq (struct grub_ata_device
*dev
, int rw
,
73 if (grub_ata_wait_not_busy (dev
, milliseconds
))
76 /* !DRQ implies error condition. */
77 grub_uint8_t sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
78 if ((sts
& (GRUB_ATA_STATUS_DRQ
| GRUB_ATA_STATUS_ERR
))
79 != GRUB_ATA_STATUS_DRQ
)
81 grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n",
82 sts
, grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
));
84 return grub_error (GRUB_ERR_READ_ERROR
, "ATA read error");
86 return grub_error (GRUB_ERR_WRITE_ERROR
, "ATA write error");
92 /* Byteorder has to be changed before strings can be read. */
94 grub_ata_strncpy (char *dst
, char *src
, grub_size_t len
)
96 grub_uint16_t
*src16
= (grub_uint16_t
*) src
;
97 grub_uint16_t
*dst16
= (grub_uint16_t
*) dst
;
100 for (i
= 0; i
< len
/ 2; i
++)
101 *(dst16
++) = grub_be_to_cpu16 (*(src16
++));
106 grub_ata_pio_read (struct grub_ata_device
*dev
, char *buf
, grub_size_t size
)
108 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
111 /* Read in the data, word by word. */
112 for (i
= 0; i
< size
/ 2; i
++)
113 buf16
[i
] = grub_le_to_cpu16 (grub_inw(dev
->ioaddress
+ GRUB_ATA_REG_DATA
));
117 grub_ata_pio_write (struct grub_ata_device
*dev
, char *buf
, grub_size_t size
)
119 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
122 /* Write the data, word by word. */
123 for (i
= 0; i
< size
/ 2; i
++)
124 grub_outw(grub_cpu_to_le16 (buf16
[i
]), dev
->ioaddress
+ GRUB_ATA_REG_DATA
);
128 grub_ata_dumpinfo (struct grub_ata_device
*dev
, char *info
)
132 /* The device information was read, dump it for debugging. */
133 grub_ata_strncpy (text
, info
+ 20, 20);
134 grub_dprintf ("ata", "Serial: %s\n", text
);
135 grub_ata_strncpy (text
, info
+ 46, 8);
136 grub_dprintf ("ata", "Firmware: %s\n", text
);
137 grub_ata_strncpy (text
, info
+ 54, 40);
138 grub_dprintf ("ata", "Model: %s\n", text
);
142 grub_dprintf ("ata", "Addressing: %d\n", dev
->addr
);
143 grub_dprintf ("ata", "Sectors: %lld\n", dev
->size
);
148 grub_atapi_identify (struct grub_ata_device
*dev
)
152 info
= grub_malloc (GRUB_DISK_SECTOR_SIZE
);
156 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | dev
->device
<< 4);
158 if (grub_ata_check_ready (dev
))
164 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE
);
167 if (grub_ata_wait_drq (dev
, 0, GRUB_ATA_TOUT_STD
))
172 grub_ata_pio_read (dev
, info
, GRUB_DISK_SECTOR_SIZE
);
176 grub_ata_dumpinfo (dev
, info
);
180 return GRUB_ERR_NONE
;
184 grub_atapi_wait_drq (struct grub_ata_device
*dev
,
185 grub_uint8_t ireason
,
188 /* Wait for !BSY, DRQ, ireason */
189 if (grub_ata_wait_not_busy (dev
, milliseconds
))
192 grub_uint8_t sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
193 grub_uint8_t irs
= grub_ata_regget (dev
, GRUB_ATAPI_REG_IREASON
);
195 /* OK if DRQ is asserted and interrupt reason is as expected. */
196 if ((sts
& GRUB_ATA_STATUS_DRQ
)
197 && (irs
& GRUB_ATAPI_IREASON_MASK
) == ireason
)
198 return GRUB_ERR_NONE
;
200 /* !DRQ implies error condition. */
201 grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n",
202 sts
, irs
, grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
));
204 if (! (sts
& GRUB_ATA_STATUS_DRQ
)
205 && (irs
& GRUB_ATAPI_IREASON_MASK
) == GRUB_ATAPI_IREASON_ERROR
)
207 if (ireason
== GRUB_ATAPI_IREASON_CMD_OUT
)
208 return grub_error (GRUB_ERR_READ_ERROR
, "ATA PACKET command error");
210 return grub_error (GRUB_ERR_READ_ERROR
, "ATAPI read error");
213 return grub_error (GRUB_ERR_READ_ERROR
, "ATAPI protocol error");
217 grub_atapi_packet (struct grub_ata_device
*dev
, char *packet
,
220 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, dev
->device
<< 4);
221 if (grub_ata_check_ready (dev
))
224 /* Send ATA PACKET command. */
225 grub_ata_regset (dev
, GRUB_ATA_REG_FEATURES
, 0);
226 grub_ata_regset (dev
, GRUB_ATAPI_REG_IREASON
, 0);
227 grub_ata_regset (dev
, GRUB_ATAPI_REG_CNTHIGH
, size
>> 8);
228 grub_ata_regset (dev
, GRUB_ATAPI_REG_CNTLOW
, size
& 0xFF);
230 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_PACKET
);
232 /* Wait for !BSY, DRQ, !I/O, C/D. */
233 if (grub_atapi_wait_drq (dev
, GRUB_ATAPI_IREASON_CMD_OUT
, GRUB_ATA_TOUT_STD
))
236 /* Write the packet. */
237 grub_ata_pio_write (dev
, packet
, 12);
239 return GRUB_ERR_NONE
;
243 grub_ata_identify (struct grub_ata_device
*dev
)
246 grub_uint16_t
*info16
;
248 info
= grub_malloc (GRUB_DISK_SECTOR_SIZE
);
252 info16
= (grub_uint16_t
*) info
;
254 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | dev
->device
<< 4);
256 if (grub_ata_check_ready (dev
))
262 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_IDENTIFY_DEVICE
);
265 if (grub_ata_wait_drq (dev
, 0, GRUB_ATA_TOUT_STD
))
268 grub_errno
= GRUB_ERR_NONE
;
269 grub_uint8_t sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
271 if ((sts
& (GRUB_ATA_STATUS_BUSY
| GRUB_ATA_STATUS_DRQ
272 | GRUB_ATA_STATUS_ERR
)) == GRUB_ATA_STATUS_ERR
273 && (grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
) & 0x04 /* ABRT */))
274 /* Device without ATA IDENTIFY, try ATAPI. */
275 return grub_atapi_identify (dev
);
277 else if (sts
== 0x00)
278 /* No device, return error but don't print message. */
279 return GRUB_ERR_UNKNOWN_DEVICE
;
283 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
,
284 "device can not be identified");
287 grub_ata_pio_read (dev
, info
, GRUB_DISK_SECTOR_SIZE
);
289 /* Re-check status to avoid bogus identify data due to stuck DRQ. */
290 grub_uint8_t sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
291 if (sts
& (GRUB_ATA_STATUS_BUSY
| GRUB_ATA_STATUS_DRQ
| GRUB_ATA_STATUS_ERR
))
293 grub_dprintf ("ata", "bad status=0x%x\n", sts
);
295 /* No device, return error but don't print message. */
296 grub_errno
= GRUB_ERR_NONE
;
297 return GRUB_ERR_UNKNOWN_DEVICE
;
300 /* Now it is certain that this is not an ATAPI device. */
303 /* CHS is always supported. */
304 dev
->addr
= GRUB_ATA_CHS
;
306 /* Check if LBA is supported. */
307 if (info16
[49] & (1 << 9))
309 /* Check if LBA48 is supported. */
310 if (info16
[83] & (1 << 10))
311 dev
->addr
= GRUB_ATA_LBA48
;
313 dev
->addr
= GRUB_ATA_LBA
;
316 /* Determine the amount of sectors. */
317 if (dev
->addr
!= GRUB_ATA_LBA48
)
318 dev
->size
= grub_le_to_cpu32(*((grub_uint32_t
*) &info16
[60]));
320 dev
->size
= grub_le_to_cpu64(*((grub_uint64_t
*) &info16
[100]));
322 /* Read CHS information. */
323 dev
->cylinders
= info16
[1];
324 dev
->heads
= info16
[3];
325 dev
->sectors_per_track
= info16
[6];
327 grub_ata_dumpinfo (dev
, info
);
335 grub_ata_device_initialize (int port
, int device
, int addr
, int addr2
)
337 struct grub_ata_device
*dev
;
338 struct grub_ata_device
**devp
;
340 grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
341 port
, device
, addr
, addr2
);
343 dev
= grub_malloc (sizeof(*dev
));
347 /* Setup the device information. */
349 dev
->device
= device
;
350 dev
->ioaddress
= addr
;
351 dev
->ioaddress2
= addr2
;
354 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, dev
->device
<< 4);
357 /* Try to detect if the port is in use by writing to it,
358 waiting for a while and reading it again. If the value
359 was preserved, there is a device connected. */
360 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, 0x5A);
362 grub_uint8_t sec
= grub_ata_regget (dev
, GRUB_ATA_REG_SECTORS
);
363 grub_dprintf ("ata", "sectors=0x%x\n", sec
);
370 /* The above test may detect a second (slave) device
371 connected to a SATA controller which supports only one
372 (master) device. It is not safe to use the status register
373 READY bit to check for controller channel existence. Some
374 ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
376 /* Use the IDENTIFY DEVICE command to query the device. */
377 if (grub_ata_identify (dev
))
383 /* Register the device. */
384 for (devp
= &grub_ata_devices
; *devp
; devp
= &(*devp
)->next
);
390 static int NESTED_FUNC_ATTR
391 grub_ata_pciinit (int bus
, int device
, int func
,
392 grub_pci_id_t pciid
__attribute__((unused
)))
394 static int compat_use
[2] = { 0 };
395 grub_pci_address_t addr
;
402 static int controller
= 0;
405 addr
= grub_pci_make_address (bus
, device
, func
, 2);
406 class = grub_pci_read (addr
);
408 /* Check if this class ID matches that of a PCI IDE Controller. */
409 if (class >> 16 != 0x0101)
412 for (i
= 0; i
< 2; i
++)
414 /* Set to 0 when the channel operated in compatibility mode. */
415 int compat
= (class >> (8 + 2 * i
)) & 1;
420 /* If the channel is in compatibility mode, just assign the
421 default registers. */
422 if (compat
== 0 && !compat_use
[i
])
424 rega
= grub_ata_ioaddress
[i
];
425 regb
= grub_ata_ioaddress2
[i
];
430 /* Read the BARs, which either contain a mmapped IO address
431 or the IO port address. */
432 addr
= grub_pci_make_address (bus
, device
, func
, 4 + 2 * i
);
433 bar1
= grub_pci_read (addr
);
434 addr
= grub_pci_make_address (bus
, device
, func
, 5 + 2 * i
);
435 bar2
= grub_pci_read (addr
);
437 /* Check if the BARs describe an IO region. */
438 if ((bar1
& 1) && (bar2
& 1))
446 "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
447 bus
, device
, func
, compat
, rega
, regb
);
451 grub_errno
= GRUB_ERR_NONE
;
452 grub_ata_device_initialize (controller
* 2 + i
, 0, rega
, regb
);
454 /* Most errors raised by grub_ata_device_initialize() are harmless.
455 They just indicate this particular drive is not responding, most
456 likely because it doesn't exist. We might want to ignore specific
457 error types here, instead of printing them. */
461 grub_errno
= GRUB_ERR_NONE
;
464 grub_ata_device_initialize (controller
* 2 + i
, 1, rega
, regb
);
470 grub_errno
= GRUB_ERR_NONE
;
481 grub_ata_initialize (void)
483 grub_pci_iterate (grub_ata_pciinit
);
489 grub_ata_setlba (struct grub_ata_device
*dev
, grub_disk_addr_t sector
,
492 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, size
);
493 grub_ata_regset (dev
, GRUB_ATA_REG_LBALOW
, sector
& 0xFF);
494 grub_ata_regset (dev
, GRUB_ATA_REG_LBAMID
, (sector
>> 8) & 0xFF);
495 grub_ata_regset (dev
, GRUB_ATA_REG_LBAHIGH
, (sector
>> 16) & 0xFF);
499 grub_ata_setaddress (struct grub_ata_device
*dev
,
500 grub_ata_addressing_t addressing
,
501 grub_disk_addr_t sector
,
508 unsigned int cylinder
;
512 /* Calculate the sector, cylinder and head to use. */
513 sect
= ((grub_uint32_t
) sector
% dev
->sectors_per_track
) + 1;
514 cylinder
= (((grub_uint32_t
) sector
/ dev
->sectors_per_track
)
516 head
= ((grub_uint32_t
) sector
/ dev
->sectors_per_track
) % dev
->heads
;
518 if (sect
> dev
->sectors_per_track
519 || cylinder
> dev
->cylinders
520 || head
> dev
->heads
)
521 return grub_error (GRUB_ERR_OUT_OF_RANGE
,
522 "sector %d can not be addressed "
523 "using CHS addressing", sector
);
525 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, (dev
->device
<< 4) | head
);
526 if (grub_ata_check_ready (dev
))
529 grub_ata_regset (dev
, GRUB_ATA_REG_SECTNUM
, sect
);
530 grub_ata_regset (dev
, GRUB_ATA_REG_CYLLSB
, cylinder
& 0xFF);
531 grub_ata_regset (dev
, GRUB_ATA_REG_CYLMSB
, cylinder
>> 8);
539 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
,
540 0xE0 | (dev
->device
<< 4) | ((sector
>> 24) & 0x0F));
541 if (grub_ata_check_ready (dev
))
544 grub_ata_setlba (dev
, sector
, size
);
551 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | (dev
->device
<< 4));
552 if (grub_ata_check_ready (dev
))
555 /* Set "Previous". */
556 grub_ata_setlba (dev
, sector
>> 24, size
>> 8);
558 grub_ata_setlba (dev
, sector
, size
);
563 return GRUB_ERR_NONE
;
567 grub_ata_readwrite (grub_disk_t disk
, grub_disk_addr_t sector
,
568 grub_size_t size
, char *buf
, int rw
)
570 struct grub_ata_device
*dev
= (struct grub_ata_device
*) disk
->data
;
572 grub_dprintf("ata", "grub_ata_readwrite (size=%u, rw=%d)\n", size
, rw
);
574 grub_ata_addressing_t addressing
= dev
->addr
;
578 if (addressing
== GRUB_ATA_LBA48
&& ((sector
+ size
) >> 28) != 0)
581 cmd
= GRUB_ATA_CMD_READ_SECTORS_EXT
;
582 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS_EXT
;
586 if (addressing
== GRUB_ATA_LBA48
)
587 addressing
= GRUB_ATA_LBA
;
589 cmd
= GRUB_ATA_CMD_READ_SECTORS
;
590 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS
;
593 grub_size_t nsectors
= 0;
594 while (nsectors
< size
)
596 if (size
- nsectors
< batch
)
597 batch
= size
- nsectors
;
599 grub_dprintf("ata", "rw=%d, sector=%llu, batch=%u\n", rw
, sector
, batch
);
601 /* Send read/write command. */
602 if (grub_ata_setaddress (dev
, addressing
, sector
, batch
))
605 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, (! rw
? cmd
: cmd_write
));
608 for (sect
= 0; sect
< batch
; sect
++)
610 /* Wait for !BSY, DRQ. */
611 if (grub_ata_wait_drq (dev
, rw
, GRUB_ATA_TOUT_DATA
))
616 grub_ata_pio_read (dev
, buf
, GRUB_DISK_SECTOR_SIZE
);
618 grub_ata_pio_write (dev
, buf
, GRUB_DISK_SECTOR_SIZE
);
620 buf
+= GRUB_DISK_SECTOR_SIZE
;
625 /* Check for write error. */
626 if (grub_ata_wait_not_busy (dev
, GRUB_ATA_TOUT_DATA
))
629 if (grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
)
630 & (GRUB_ATA_STATUS_DRQ
| GRUB_ATA_STATUS_ERR
))
631 return grub_error (GRUB_ERR_WRITE_ERROR
, "ATA write error");
638 return GRUB_ERR_NONE
;
644 grub_ata_iterate (int (*hook
) (const char *name
))
646 struct grub_ata_device
*dev
;
648 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
651 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
664 grub_ata_open (const char *name
, grub_disk_t disk
)
666 struct grub_ata_device
*dev
;
668 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
671 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
672 if (grub_strcmp (name
, devname
) == 0)
677 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "Can't open device");
680 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "not an ATA harddisk");
682 disk
->total_sectors
= dev
->size
;
684 disk
->id
= (unsigned long) dev
;
686 disk
->has_partitions
= 1;
693 grub_ata_close (grub_disk_t disk
__attribute__((unused
)))
699 grub_ata_read (grub_disk_t disk
, grub_disk_addr_t sector
,
700 grub_size_t size
, char *buf
)
702 return grub_ata_readwrite (disk
, sector
, size
, buf
, 0);
706 grub_ata_write (grub_disk_t disk
,
707 grub_disk_addr_t sector
,
711 return grub_ata_readwrite (disk
, sector
, size
, (char *) buf
, 1);
714 static struct grub_disk_dev grub_atadisk_dev
=
717 .id
= GRUB_DISK_DEVICE_ATA_ID
,
718 .iterate
= grub_ata_iterate
,
719 .open
= grub_ata_open
,
720 .close
= grub_ata_close
,
721 .read
= grub_ata_read
,
722 .write
= grub_ata_write
,
731 grub_atapi_iterate (int (*hook
) (const char *name
, int luns
))
733 struct grub_ata_device
*dev
;
735 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
738 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
743 if (hook (devname
, 1))
752 grub_atapi_read (struct grub_scsi
*scsi
,
753 grub_size_t cmdsize
__attribute__((unused
)),
754 char *cmd
, grub_size_t size
, char *buf
)
756 struct grub_ata_device
*dev
= (struct grub_ata_device
*) scsi
->data
;
758 grub_dprintf("ata", "grub_atapi_read (size=%u)\n", size
);
760 if (grub_atapi_packet (dev
, cmd
, size
))
763 grub_size_t nread
= 0;
766 /* Wait for !BSY, DRQ, I/O, !C/D. */
767 if (grub_atapi_wait_drq (dev
, GRUB_ATAPI_IREASON_DATA_IN
, GRUB_ATA_TOUT_DATA
))
770 /* Get byte count for this DRQ assertion. */
771 unsigned cnt
= grub_ata_regget (dev
, GRUB_ATAPI_REG_CNTHIGH
) << 8
772 | grub_ata_regget (dev
, GRUB_ATAPI_REG_CNTLOW
);
773 grub_dprintf("ata", "DRQ count=%u\n", cnt
);
775 /* Count of last transfer may be uneven. */
776 if (! (0 < cnt
&& cnt
<= size
- nread
&& (! (cnt
& 1) || cnt
== size
- nread
)))
777 return grub_error (GRUB_ERR_READ_ERROR
, "Invalid ATAPI transfer count");
780 grub_ata_pio_read (dev
, buf
+ nread
, cnt
);
783 buf
[nread
+ cnt
- 1] = (char) grub_le_to_cpu16 (grub_inw (dev
->ioaddress
+ GRUB_ATA_REG_DATA
));
788 return GRUB_ERR_NONE
;
792 grub_atapi_write (struct grub_scsi
*scsi
__attribute__((unused
)),
793 grub_size_t cmdsize
__attribute__((unused
)),
794 char *cmd
__attribute__((unused
)),
795 grub_size_t size
__attribute__((unused
)),
796 char *buf
__attribute__((unused
)))
798 // XXX: scsi.mod does not use write yet.
799 return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET
, "ATAPI write not implemented");
803 grub_atapi_open (const char *name
, struct grub_scsi
*scsi
)
805 struct grub_ata_device
*dev
;
806 struct grub_ata_device
*devfnd
= 0;
808 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
811 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
813 if (!grub_strcmp (devname
, name
))
820 grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name
);
823 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "No such ATAPI device");
827 return GRUB_ERR_NONE
;
831 grub_atapi_close (struct grub_scsi
*scsi
)
833 grub_free (scsi
->name
);
836 static struct grub_scsi_dev grub_atapi_dev
=
839 .iterate
= grub_atapi_iterate
,
840 .open
= grub_atapi_open
,
841 .close
= grub_atapi_close
,
842 .read
= grub_atapi_read
,
843 .write
= grub_atapi_write
850 /* To prevent two drivers operating on the same disks. */
851 grub_disk_firmware_is_tainted
= 1;
852 if (grub_disk_firmware_fini
)
854 grub_disk_firmware_fini ();
855 grub_disk_firmware_fini
= NULL
;
858 /* ATA initialization. */
859 grub_ata_initialize ();
861 grub_disk_dev_register (&grub_atadisk_dev
);
863 /* ATAPI devices are handled by scsi.mod. */
864 grub_scsi_dev_register (&grub_atapi_dev
);
869 grub_scsi_dev_unregister (&grub_atapi_dev
);
870 grub_disk_dev_unregister (&grub_atadisk_dev
);