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
)
41 /* ATA requires 400ns (after a write to CMD register) or
42 1 PIO cycle (after a DRQ block transfer) before
43 first check of BSY. */
46 while ((sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
))
47 & GRUB_ATA_STATUS_BUSY
)
49 if (i
>= milliseconds
)
51 grub_dprintf ("ata", "timeout: %dms, status=0x%x\n",
53 return grub_error (GRUB_ERR_TIMEOUT
, "ATA timeout");
69 /* Wait for !BSY, DRQ. */
71 grub_ata_wait_drq (struct grub_ata_device
*dev
, int rw
,
76 if (grub_ata_wait_not_busy (dev
, milliseconds
))
79 /* !DRQ implies error condition. */
80 sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
81 if ((sts
& (GRUB_ATA_STATUS_DRQ
| GRUB_ATA_STATUS_ERR
))
82 != GRUB_ATA_STATUS_DRQ
)
84 grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n",
85 sts
, grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
));
87 return grub_error (GRUB_ERR_READ_ERROR
, "ATA read error");
89 return grub_error (GRUB_ERR_WRITE_ERROR
, "ATA write error");
95 /* Byteorder has to be changed before strings can be read. */
97 grub_ata_strncpy (char *dst
, char *src
, grub_size_t len
)
99 grub_uint16_t
*src16
= (grub_uint16_t
*) src
;
100 grub_uint16_t
*dst16
= (grub_uint16_t
*) dst
;
103 for (i
= 0; i
< len
/ 2; i
++)
104 *(dst16
++) = grub_be_to_cpu16 (*(src16
++));
109 grub_ata_pio_read (struct grub_ata_device
*dev
, char *buf
, grub_size_t size
)
111 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
114 /* Read in the data, word by word. */
115 for (i
= 0; i
< size
/ 2; i
++)
116 buf16
[i
] = grub_le_to_cpu16 (grub_inw(dev
->ioaddress
+ GRUB_ATA_REG_DATA
));
120 grub_ata_pio_write (struct grub_ata_device
*dev
, char *buf
, grub_size_t size
)
122 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
125 /* Write the data, word by word. */
126 for (i
= 0; i
< size
/ 2; i
++)
127 grub_outw(grub_cpu_to_le16 (buf16
[i
]), dev
->ioaddress
+ GRUB_ATA_REG_DATA
);
131 grub_ata_dumpinfo (struct grub_ata_device
*dev
, char *info
)
135 /* The device information was read, dump it for debugging. */
136 grub_ata_strncpy (text
, info
+ 20, 20);
137 grub_dprintf ("ata", "Serial: %s\n", text
);
138 grub_ata_strncpy (text
, info
+ 46, 8);
139 grub_dprintf ("ata", "Firmware: %s\n", text
);
140 grub_ata_strncpy (text
, info
+ 54, 40);
141 grub_dprintf ("ata", "Model: %s\n", text
);
145 grub_dprintf ("ata", "Addressing: %d\n", dev
->addr
);
146 grub_dprintf ("ata", "Sectors: %lld\n", dev
->size
);
151 grub_atapi_identify (struct grub_ata_device
*dev
)
155 info
= grub_malloc (GRUB_DISK_SECTOR_SIZE
);
159 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | dev
->device
<< 4);
161 if (grub_ata_check_ready (dev
))
167 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE
);
170 if (grub_ata_wait_drq (dev
, 0, GRUB_ATA_TOUT_STD
))
175 grub_ata_pio_read (dev
, info
, GRUB_DISK_SECTOR_SIZE
);
179 grub_ata_dumpinfo (dev
, info
);
183 return GRUB_ERR_NONE
;
187 grub_atapi_wait_drq (struct grub_ata_device
*dev
,
188 grub_uint8_t ireason
,
194 /* Wait for !BSY, DRQ, ireason */
195 if (grub_ata_wait_not_busy (dev
, milliseconds
))
198 sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
199 irs
= grub_ata_regget (dev
, GRUB_ATAPI_REG_IREASON
);
201 /* OK if DRQ is asserted and interrupt reason is as expected. */
202 if ((sts
& GRUB_ATA_STATUS_DRQ
)
203 && (irs
& GRUB_ATAPI_IREASON_MASK
) == ireason
)
204 return GRUB_ERR_NONE
;
206 /* !DRQ implies error condition. */
207 grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n",
208 sts
, irs
, grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
));
210 if (! (sts
& GRUB_ATA_STATUS_DRQ
)
211 && (irs
& GRUB_ATAPI_IREASON_MASK
) == GRUB_ATAPI_IREASON_ERROR
)
213 if (ireason
== GRUB_ATAPI_IREASON_CMD_OUT
)
214 return grub_error (GRUB_ERR_READ_ERROR
, "ATA PACKET command error");
216 return grub_error (GRUB_ERR_READ_ERROR
, "ATAPI read error");
219 return grub_error (GRUB_ERR_READ_ERROR
, "ATAPI protocol error");
223 grub_atapi_packet (struct grub_ata_device
*dev
, char *packet
,
226 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, dev
->device
<< 4);
227 if (grub_ata_check_ready (dev
))
230 /* Send ATA PACKET command. */
231 grub_ata_regset (dev
, GRUB_ATA_REG_FEATURES
, 0);
232 grub_ata_regset (dev
, GRUB_ATAPI_REG_IREASON
, 0);
233 grub_ata_regset (dev
, GRUB_ATAPI_REG_CNTHIGH
, size
>> 8);
234 grub_ata_regset (dev
, GRUB_ATAPI_REG_CNTLOW
, size
& 0xFF);
236 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_PACKET
);
238 /* Wait for !BSY, DRQ, !I/O, C/D. */
239 if (grub_atapi_wait_drq (dev
, GRUB_ATAPI_IREASON_CMD_OUT
, GRUB_ATA_TOUT_STD
))
242 /* Write the packet. */
243 grub_ata_pio_write (dev
, packet
, 12);
245 return GRUB_ERR_NONE
;
249 grub_ata_identify (struct grub_ata_device
*dev
)
252 grub_uint16_t
*info16
;
255 info
= grub_malloc (GRUB_DISK_SECTOR_SIZE
);
259 info16
= (grub_uint16_t
*) info
;
261 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | dev
->device
<< 4);
263 if (grub_ata_check_ready (dev
))
269 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_IDENTIFY_DEVICE
);
272 if (grub_ata_wait_drq (dev
, 0, GRUB_ATA_TOUT_STD
))
274 sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
277 grub_errno
= GRUB_ERR_NONE
;
279 if ((sts
& (GRUB_ATA_STATUS_BUSY
| GRUB_ATA_STATUS_DRQ
280 | GRUB_ATA_STATUS_ERR
)) == GRUB_ATA_STATUS_ERR
281 && (grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
) & 0x04 /* ABRT */))
282 /* Device without ATA IDENTIFY, try ATAPI. */
283 return grub_atapi_identify (dev
);
285 else if (sts
== 0x00)
286 /* No device, return error but don't print message. */
287 return GRUB_ERR_UNKNOWN_DEVICE
;
291 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
,
292 "device can not be identified");
295 grub_ata_pio_read (dev
, info
, GRUB_DISK_SECTOR_SIZE
);
297 /* Re-check status to avoid bogus identify data due to stuck DRQ. */
298 sts
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
299 if (sts
& (GRUB_ATA_STATUS_BUSY
| GRUB_ATA_STATUS_DRQ
| GRUB_ATA_STATUS_ERR
))
301 grub_dprintf ("ata", "bad status=0x%x\n", sts
);
303 /* No device, return error but don't print message. */
304 grub_errno
= GRUB_ERR_NONE
;
305 return GRUB_ERR_UNKNOWN_DEVICE
;
308 /* Now it is certain that this is not an ATAPI device. */
311 /* CHS is always supported. */
312 dev
->addr
= GRUB_ATA_CHS
;
314 /* Check if LBA is supported. */
315 if (info16
[49] & (1 << 9))
317 /* Check if LBA48 is supported. */
318 if (info16
[83] & (1 << 10))
319 dev
->addr
= GRUB_ATA_LBA48
;
321 dev
->addr
= GRUB_ATA_LBA
;
324 /* Determine the amount of sectors. */
325 if (dev
->addr
!= GRUB_ATA_LBA48
)
326 dev
->size
= grub_le_to_cpu32(*((grub_uint32_t
*) &info16
[60]));
328 dev
->size
= grub_le_to_cpu64(*((grub_uint64_t
*) &info16
[100]));
330 /* Read CHS information. */
331 dev
->cylinders
= info16
[1];
332 dev
->heads
= info16
[3];
333 dev
->sectors_per_track
= info16
[6];
335 grub_ata_dumpinfo (dev
, info
);
343 grub_ata_device_initialize (int port
, int device
, int addr
, int addr2
)
345 struct grub_ata_device
*dev
;
346 struct grub_ata_device
**devp
;
349 grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
350 port
, device
, addr
, addr2
);
352 dev
= grub_malloc (sizeof(*dev
));
356 /* Setup the device information. */
358 dev
->device
= device
;
359 dev
->ioaddress
= addr
;
360 dev
->ioaddress2
= addr2
;
363 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, dev
->device
<< 4);
366 /* Try to detect if the port is in use by writing to it,
367 waiting for a while and reading it again. If the value
368 was preserved, there is a device connected. */
369 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, 0x5A);
371 sec
= grub_ata_regget (dev
, GRUB_ATA_REG_SECTORS
);
372 grub_dprintf ("ata", "sectors=0x%x\n", sec
);
379 /* The above test may detect a second (slave) device
380 connected to a SATA controller which supports only one
381 (master) device. It is not safe to use the status register
382 READY bit to check for controller channel existence. Some
383 ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
385 /* Use the IDENTIFY DEVICE command to query the device. */
386 if (grub_ata_identify (dev
))
392 /* Register the device. */
393 for (devp
= &grub_ata_devices
; *devp
; devp
= &(*devp
)->next
);
399 static int NESTED_FUNC_ATTR
400 grub_ata_pciinit (int bus
, int device
, int func
,
401 grub_pci_id_t pciid
__attribute__((unused
)))
403 static int compat_use
[2] = { 0 };
404 grub_pci_address_t addr
;
411 static int controller
= 0;
414 addr
= grub_pci_make_address (bus
, device
, func
, 2);
415 class = grub_pci_read (addr
);
417 /* Check if this class ID matches that of a PCI IDE Controller. */
418 if (class >> 16 != 0x0101)
421 for (i
= 0; i
< 2; i
++)
423 /* Set to 0 when the channel operated in compatibility mode. */
424 int compat
= (class >> (8 + 2 * i
)) & 1;
429 /* If the channel is in compatibility mode, just assign the
430 default registers. */
431 if (compat
== 0 && !compat_use
[i
])
433 rega
= grub_ata_ioaddress
[i
];
434 regb
= grub_ata_ioaddress2
[i
];
439 /* Read the BARs, which either contain a mmapped IO address
440 or the IO port address. */
441 addr
= grub_pci_make_address (bus
, device
, func
, 4 + 2 * i
);
442 bar1
= grub_pci_read (addr
);
443 addr
= grub_pci_make_address (bus
, device
, func
, 5 + 2 * i
);
444 bar2
= grub_pci_read (addr
);
446 /* Check if the BARs describe an IO region. */
447 if ((bar1
& 1) && (bar2
& 1))
455 "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
456 bus
, device
, func
, compat
, rega
, regb
);
460 grub_errno
= GRUB_ERR_NONE
;
461 grub_ata_device_initialize (controller
* 2 + i
, 0, rega
, regb
);
463 /* Most errors raised by grub_ata_device_initialize() are harmless.
464 They just indicate this particular drive is not responding, most
465 likely because it doesn't exist. We might want to ignore specific
466 error types here, instead of printing them. */
470 grub_errno
= GRUB_ERR_NONE
;
473 grub_ata_device_initialize (controller
* 2 + i
, 1, rega
, regb
);
479 grub_errno
= GRUB_ERR_NONE
;
490 grub_ata_initialize (void)
492 grub_pci_iterate (grub_ata_pciinit
);
498 grub_ata_setlba (struct grub_ata_device
*dev
, grub_disk_addr_t sector
,
501 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, size
);
502 grub_ata_regset (dev
, GRUB_ATA_REG_LBALOW
, sector
& 0xFF);
503 grub_ata_regset (dev
, GRUB_ATA_REG_LBAMID
, (sector
>> 8) & 0xFF);
504 grub_ata_regset (dev
, GRUB_ATA_REG_LBAHIGH
, (sector
>> 16) & 0xFF);
508 grub_ata_setaddress (struct grub_ata_device
*dev
,
509 grub_ata_addressing_t addressing
,
510 grub_disk_addr_t sector
,
517 unsigned int cylinder
;
521 /* Calculate the sector, cylinder and head to use. */
522 sect
= ((grub_uint32_t
) sector
% dev
->sectors_per_track
) + 1;
523 cylinder
= (((grub_uint32_t
) sector
/ dev
->sectors_per_track
)
525 head
= ((grub_uint32_t
) sector
/ dev
->sectors_per_track
) % dev
->heads
;
527 if (sect
> dev
->sectors_per_track
528 || cylinder
> dev
->cylinders
529 || head
> dev
->heads
)
530 return grub_error (GRUB_ERR_OUT_OF_RANGE
,
531 "sector %d can not be addressed "
532 "using CHS addressing", sector
);
534 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, (dev
->device
<< 4) | head
);
535 if (grub_ata_check_ready (dev
))
538 grub_ata_regset (dev
, GRUB_ATA_REG_SECTNUM
, sect
);
539 grub_ata_regset (dev
, GRUB_ATA_REG_CYLLSB
, cylinder
& 0xFF);
540 grub_ata_regset (dev
, GRUB_ATA_REG_CYLMSB
, cylinder
>> 8);
548 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
,
549 0xE0 | (dev
->device
<< 4) | ((sector
>> 24) & 0x0F));
550 if (grub_ata_check_ready (dev
))
553 grub_ata_setlba (dev
, sector
, size
);
560 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | (dev
->device
<< 4));
561 if (grub_ata_check_ready (dev
))
564 /* Set "Previous". */
565 grub_ata_setlba (dev
, sector
>> 24, size
>> 8);
567 grub_ata_setlba (dev
, sector
, size
);
572 return GRUB_ERR_NONE
;
576 grub_ata_readwrite (grub_disk_t disk
, grub_disk_addr_t sector
,
577 grub_size_t size
, char *buf
, int rw
)
579 struct grub_ata_device
*dev
= (struct grub_ata_device
*) disk
->data
;
580 grub_ata_addressing_t addressing
= dev
->addr
;
583 grub_size_t nsectors
= 0;
585 grub_dprintf("ata", "grub_ata_readwrite (size=%u, rw=%d)\n", size
, rw
);
587 if (addressing
== GRUB_ATA_LBA48
&& ((sector
+ size
) >> 28) != 0)
590 cmd
= GRUB_ATA_CMD_READ_SECTORS_EXT
;
591 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS_EXT
;
595 if (addressing
== GRUB_ATA_LBA48
)
596 addressing
= GRUB_ATA_LBA
;
598 cmd
= GRUB_ATA_CMD_READ_SECTORS
;
599 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS
;
602 while (nsectors
< size
)
606 if (size
- nsectors
< batch
)
607 batch
= size
- nsectors
;
609 grub_dprintf("ata", "rw=%d, sector=%llu, batch=%u\n", rw
, sector
, batch
);
611 /* Send read/write command. */
612 if (grub_ata_setaddress (dev
, addressing
, sector
, batch
))
615 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, (! rw
? cmd
: cmd_write
));
617 for (sect
= 0; sect
< batch
; sect
++)
619 /* Wait for !BSY, DRQ. */
620 if (grub_ata_wait_drq (dev
, rw
, GRUB_ATA_TOUT_DATA
))
625 grub_ata_pio_read (dev
, buf
, GRUB_DISK_SECTOR_SIZE
);
627 grub_ata_pio_write (dev
, buf
, GRUB_DISK_SECTOR_SIZE
);
629 buf
+= GRUB_DISK_SECTOR_SIZE
;
634 /* Check for write error. */
635 if (grub_ata_wait_not_busy (dev
, GRUB_ATA_TOUT_DATA
))
638 if (grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
)
639 & (GRUB_ATA_STATUS_DRQ
| GRUB_ATA_STATUS_ERR
))
640 return grub_error (GRUB_ERR_WRITE_ERROR
, "ATA write error");
647 return GRUB_ERR_NONE
;
653 grub_ata_iterate (int (*hook
) (const char *name
))
655 struct grub_ata_device
*dev
;
657 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
660 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
673 grub_ata_open (const char *name
, grub_disk_t disk
)
675 struct grub_ata_device
*dev
;
677 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
680 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
681 if (grub_strcmp (name
, devname
) == 0)
686 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "Can't open device");
689 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "not an ATA harddisk");
691 disk
->total_sectors
= dev
->size
;
693 disk
->id
= (unsigned long) dev
;
695 disk
->has_partitions
= 1;
702 grub_ata_close (grub_disk_t disk
__attribute__((unused
)))
708 grub_ata_read (grub_disk_t disk
, grub_disk_addr_t sector
,
709 grub_size_t size
, char *buf
)
711 return grub_ata_readwrite (disk
, sector
, size
, buf
, 0);
715 grub_ata_write (grub_disk_t disk
,
716 grub_disk_addr_t sector
,
720 return grub_ata_readwrite (disk
, sector
, size
, (char *) buf
, 1);
723 static struct grub_disk_dev grub_atadisk_dev
=
726 .id
= GRUB_DISK_DEVICE_ATA_ID
,
727 .iterate
= grub_ata_iterate
,
728 .open
= grub_ata_open
,
729 .close
= grub_ata_close
,
730 .read
= grub_ata_read
,
731 .write
= grub_ata_write
,
740 grub_atapi_iterate (int (*hook
) (const char *name
, int luns
))
742 struct grub_ata_device
*dev
;
744 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
747 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
752 if (hook (devname
, 1))
761 grub_atapi_read (struct grub_scsi
*scsi
,
762 grub_size_t cmdsize
__attribute__((unused
)),
763 char *cmd
, grub_size_t size
, char *buf
)
765 struct grub_ata_device
*dev
= (struct grub_ata_device
*) scsi
->data
;
766 grub_size_t nread
= 0;
768 grub_dprintf("ata", "grub_atapi_read (size=%u)\n", size
);
770 if (grub_atapi_packet (dev
, cmd
, size
))
777 /* Wait for !BSY, DRQ, I/O, !C/D. */
778 if (grub_atapi_wait_drq (dev
, GRUB_ATAPI_IREASON_DATA_IN
, GRUB_ATA_TOUT_DATA
))
781 /* Get byte count for this DRQ assertion. */
782 cnt
= grub_ata_regget (dev
, GRUB_ATAPI_REG_CNTHIGH
) << 8
783 | grub_ata_regget (dev
, GRUB_ATAPI_REG_CNTLOW
);
784 grub_dprintf("ata", "DRQ count=%u\n", cnt
);
786 /* Count of last transfer may be uneven. */
787 if (! (0 < cnt
&& cnt
<= size
- nread
&& (! (cnt
& 1) || cnt
== size
- nread
)))
788 return grub_error (GRUB_ERR_READ_ERROR
, "Invalid ATAPI transfer count");
791 grub_ata_pio_read (dev
, buf
+ nread
, cnt
);
794 buf
[nread
+ cnt
- 1] = (char) grub_le_to_cpu16 (grub_inw (dev
->ioaddress
+ GRUB_ATA_REG_DATA
));
799 return GRUB_ERR_NONE
;
803 grub_atapi_write (struct grub_scsi
*scsi
__attribute__((unused
)),
804 grub_size_t cmdsize
__attribute__((unused
)),
805 char *cmd
__attribute__((unused
)),
806 grub_size_t size
__attribute__((unused
)),
807 char *buf
__attribute__((unused
)))
809 // XXX: scsi.mod does not use write yet.
810 return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET
, "ATAPI write not implemented");
814 grub_atapi_open (const char *name
, struct grub_scsi
*scsi
)
816 struct grub_ata_device
*dev
;
817 struct grub_ata_device
*devfnd
= 0;
819 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
822 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
824 if (!grub_strcmp (devname
, name
))
831 grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name
);
834 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "No such ATAPI device");
838 return GRUB_ERR_NONE
;
842 grub_atapi_close (struct grub_scsi
*scsi
)
844 grub_free (scsi
->name
);
847 static struct grub_scsi_dev grub_atapi_dev
=
850 .iterate
= grub_atapi_iterate
,
851 .open
= grub_atapi_open
,
852 .close
= grub_atapi_close
,
853 .read
= grub_atapi_read
,
854 .write
= grub_atapi_write
861 /* To prevent two drivers operating on the same disks. */
862 grub_disk_firmware_is_tainted
= 1;
863 if (grub_disk_firmware_fini
)
865 grub_disk_firmware_fini ();
866 grub_disk_firmware_fini
= NULL
;
869 /* ATA initialization. */
870 grub_ata_initialize ();
872 grub_disk_dev_register (&grub_atadisk_dev
);
874 /* ATAPI devices are handled by scsi.mod. */
875 grub_scsi_dev_register (&grub_atapi_dev
);
880 grub_scsi_dev_unregister (&grub_atapi_dev
);
881 grub_disk_dev_unregister (&grub_atadisk_dev
);