added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / common / grub2 / disk / ata.c
blob30dea7918163c1aba22fc57ada4e1d39ec2cb0c3
1 /* ata.c - ATA disk access. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2007 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/dl.h>
21 #include <grub/misc.h>
22 #include <grub/disk.h>
23 #include <grub/mm.h>
24 #include <grub/time.h>
25 /* XXX: For now this only works on i386. */
26 #include <grub/cpu/io.h>
28 typedef enum
30 GRUB_ATA_CHS,
31 GRUB_ATA_LBA,
32 GRUB_ATA_LBA48
33 } grub_ata_addressing_t;
35 /* At the moment, only two IDE ports are supported. */
36 static const int grub_ata_ioaddress[] = { 0x1f0, 0x170 };
37 static const int grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
39 #define GRUB_CDROM_SECTOR_SIZE 2048
41 #define GRUB_ATA_REG_DATA 0
42 #define GRUB_ATA_REG_ERROR 1
43 #define GRUB_ATA_REG_FEATURES 1
44 #define GRUB_ATA_REG_SECTORS 2
45 #define GRUB_ATA_REG_SECTNUM 3
46 #define GRUB_ATA_REG_CYLLSB 4
47 #define GRUB_ATA_REG_CYLMSB 5
48 #define GRUB_ATA_REG_LBALOW 3
49 #define GRUB_ATA_REG_LBAMID 4
50 #define GRUB_ATA_REG_LBAHIGH 5
51 #define GRUB_ATA_REG_DISK 6
52 #define GRUB_ATA_REG_CMD 7
53 #define GRUB_ATA_REG_STATUS 7
55 #define GRUB_ATA_REG2_CONTROL 0
57 enum grub_ata_commands
59 GRUB_ATA_CMD_READ_SECTORS = 0x20,
60 GRUB_ATA_CMD_READ_SECTORS_EXT = 0x24,
61 GRUB_ATA_CMD_WRITE_SECTORS = 0x30,
62 GRUB_ATA_CMD_WRITE_SECTORS_EXT = 0x34,
63 GRUB_ATA_CMD_IDENTIFY_DEVICE = 0xEC,
64 GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE = 0xA1,
65 GRUB_ATA_CMD_PACKET = 0xA0
68 struct grub_ata_device
70 /* IDE port to use. */
71 int port;
73 /* IO addresses on which the registers for this device can be
74 found. */
75 int ioaddress;
76 int ioaddress2;
78 /* Two devices can be connected to a single cable. Use this field
79 to select device 0 (commonly known as "master") or device 1
80 (commonly known as "slave"). */
81 int device;
83 /* Addressing methods available for accessing this device. If CHS
84 is only available, use that. Otherwise use LBA, except for the
85 high sectors. In that case use LBA48. */
86 grub_ata_addressing_t addr;
88 /* Sector count. */
89 grub_size_t size;
91 /* CHS maximums. */
92 grub_uint16_t cylinders;
93 grub_uint16_t heads;
94 grub_uint16_t sectors_per_track;
96 /* Set to 0 for ATA, set to 1 for ATAPI. */
97 int atapi;
99 struct grub_ata_device *next;
102 static struct grub_ata_device *grub_ata_devices;
104 static inline void
105 grub_ata_regset (struct grub_ata_device *dev, int reg, int val)
107 grub_outb (val, dev->ioaddress + reg);
110 static inline int
111 grub_ata_regget (struct grub_ata_device *dev, int reg)
113 return grub_inb (dev->ioaddress + reg);
116 static inline void
117 grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val)
119 grub_outb (val, dev->ioaddress2 + reg);
122 static inline int
123 grub_ata_regget2 (struct grub_ata_device *dev, int reg)
125 return grub_inb (dev->ioaddress2 + reg);
128 /* Wait until the device DEV has the status set to ready. */
129 static inline void
130 grub_ata_wait_busy (struct grub_ata_device *dev)
132 while ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 0x80));
135 static inline void
136 grub_ata_wait_drq (struct grub_ata_device *dev)
138 while (! (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 0x08));
141 static inline void
142 grub_ata_wait (void)
144 grub_millisleep (50);
147 /* Byteorder has to be changed before strings can be read. */
148 static inline void
149 grub_ata_strncpy (char *dst, char *src, grub_size_t len)
151 grub_uint16_t *src16 = (grub_uint16_t *) src;
152 grub_uint16_t *dst16 = (grub_uint16_t *) dst;
153 unsigned int i;
155 for (i = 0; i < len / 2; i++)
156 *(dst16++) = grub_be_to_cpu16(*(src16++));
157 dst[len] = '\0';
160 static int
161 grub_ata_pio_read (struct grub_ata_device *dev, char *buf,
162 grub_size_t size)
164 grub_uint16_t *buf16 = (grub_uint16_t *) buf;
165 unsigned int i;
167 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 1)
168 return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
170 /* Wait until the data is available. */
171 grub_ata_wait_drq (dev);
173 /* Read in the data, word by word. */
174 for (i = 0; i < size / 2; i++)
175 buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
177 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 1)
178 return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
180 return 0;
183 static grub_err_t
184 grub_ata_pio_write (struct grub_ata_device *dev, char *buf,
185 grub_size_t size)
187 grub_uint16_t *buf16 = (grub_uint16_t *) buf;
188 unsigned int i;
190 /* Wait until the device is ready to write. */
191 grub_ata_wait_drq (dev);
193 /* Write the data, word by word. */
194 for (i = 0; i < size / 2; i++)
195 grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
197 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 1)
198 return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
200 return 0;
203 static void
204 grub_ata_dumpinfo (struct grub_ata_device *dev, char *info)
206 char text[41];
208 /* The device information was read, dump it for debugging. */
209 grub_ata_strncpy (text, info + 20, 20);
210 grub_printf ("Serial: %s\n", text);
211 grub_ata_strncpy (text, info + 46, 8);
212 grub_printf ("Firmware: %s\n", text);
213 grub_ata_strncpy (text, info + 54, 40);
214 grub_printf ("Model: %s\n", text);
216 grub_printf ("Addressing: %d\n", dev->addr);
217 grub_printf ("#sectors: %d\n", dev->size);
221 static grub_err_t
222 grub_atapi_identify (struct grub_ata_device *dev)
224 char *info;
226 info = grub_malloc (256);
227 if (! info)
228 return grub_errno;
230 grub_ata_wait_busy (dev);
232 grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
233 grub_ata_regset (dev, GRUB_ATA_REG_CMD,
234 GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
235 grub_ata_wait ();
237 grub_ata_pio_read (dev, info, 256);
239 dev->atapi = 1;
241 grub_ata_dumpinfo (dev, info);
243 grub_free (info);
245 return 0;
248 static grub_err_t
249 grub_atapi_packet (struct grub_ata_device *dev, char *packet)
251 grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
252 grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0);
253 grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0);
254 grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, 0xFF);
255 grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, 0xFF);
256 grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET);
257 grub_ata_wait ();
259 grub_ata_pio_write (dev, packet, 12);
261 return 0;
264 static grub_err_t
265 grub_ata_identify (struct grub_ata_device *dev)
267 char *info;
268 grub_uint16_t *info16;
269 int ataerr;
271 info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
272 if (! info)
273 return grub_errno;
275 info16 = (grub_uint16_t *) info;
277 grub_ata_wait_busy (dev);
279 grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
280 grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
281 grub_ata_wait ();
283 ataerr = grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
284 if (ataerr & 4)
286 /* ATAPI device detected. */
287 grub_free(info);
288 return grub_atapi_identify (dev);
290 else if (ataerr)
292 /* Error. */
293 grub_free(info);
294 return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
295 "device can not be identified");
298 /* Now it is certain that this is not an ATAPI device. */
299 dev->atapi = 0;
301 /* CHS is always supported. */
302 dev->addr = GRUB_ATA_CHS;
304 /* Check if LBA is supported. */
305 if (info16[49] & (1 << 9))
307 /* Check if LBA48 is supported. */
308 if (info16[83] & (1 << 10))
309 dev->addr = GRUB_ATA_LBA48;
310 else
311 dev->addr = GRUB_ATA_LBA;
314 /* Determine the amount of sectors. */
315 if (dev->addr != GRUB_ATA_LBA48)
316 dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60]));
317 else
318 dev->size = grub_le_to_cpu64(*((grub_uint32_t *) &info16[100]));
320 /* Read CHS information. */
321 dev->cylinders = info16[1];
322 dev->heads = info16[3];
323 dev->sectors_per_track = info16[6];
325 grub_ata_dumpinfo (dev, info);
327 grub_free(info);
329 return 0;
332 static grub_err_t
333 grub_ata_initialize (void)
335 struct grub_ata_device *dev;
336 struct grub_ata_device **devp;
337 int port;
338 int device;
340 for (port = 0; port <= 1; port++)
342 for (device = 0; device <= 1; device++)
344 dev = grub_malloc (sizeof(*dev));
345 if (! dev)
346 return grub_errno;
348 /* Setup the device information. */
349 dev->port = port;
350 dev->device = device;
351 dev->ioaddress = grub_ata_ioaddress[dev->port];
352 dev->ioaddress2 = grub_ata_ioaddress2[dev->port];
353 dev->next = NULL;
355 /* Try to detect if the port is in use by writing to it,
356 waiting for a while and reading it again. If the value
357 was preserved, there is a device connected. */
358 grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
359 grub_ata_wait ();
360 grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
361 grub_ata_wait ();
362 if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) != 0x5A)
364 grub_free(dev);
365 continue;
368 /* Detect if the device is present by issuing a reset. */
369 grub_ata_regset2 (dev, GRUB_ATA_REG2_CONTROL, 6);
370 grub_ata_wait ();
371 grub_ata_regset2 (dev, GRUB_ATA_REG2_CONTROL, 2);
372 grub_ata_wait ();
373 grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
374 grub_ata_wait ();
376 /* XXX: Check some registers to see if the reset worked as
377 expected for this device. */
378 #if 1
379 /* Enable for ATAPI . */
380 if (grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0x14
381 || grub_ata_regget (dev, GRUB_ATA_REG_CYLMSB) != 0xeb)
382 #endif
383 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) == 0
384 || (grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0
385 && grub_ata_regget (dev, GRUB_ATA_REG_CYLMSB) != 0
386 && grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0x3c
387 && grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0xc3))
389 grub_free (dev);
390 continue;
393 /* Use the IDENTIFY DEVICE command to query the device. */
394 if (grub_ata_identify (dev))
396 grub_free (dev);
397 continue;
400 /* Register the device. */
401 for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
402 *devp = dev;
406 return 0;
409 static void
410 grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
411 grub_size_t size)
413 grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size);
414 grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF);
415 grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
416 grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
419 static grub_err_t
420 grub_ata_setaddress (struct grub_ata_device *dev,
421 grub_ata_addressing_t addressing,
422 grub_disk_addr_t sector,
423 grub_size_t size)
425 grub_ata_wait_busy (dev);
427 switch (addressing)
429 case GRUB_ATA_CHS:
431 unsigned int cylinder;
432 unsigned int head;
433 unsigned int sect;
435 /* Calculate the sector, cylinder and head to use. */
436 sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
437 cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)
438 / dev->heads);
439 head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads;
441 if (sect > dev->sectors_per_track
442 || cylinder > dev->cylinders
443 || head > dev->heads)
444 return grub_error (GRUB_ERR_OUT_OF_RANGE,
445 "sector %d can not be addressed "
446 "using CHS addressing", sector);
448 grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect);
449 grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF);
450 grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8);
451 grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head);
453 break;
456 case GRUB_ATA_LBA:
457 if (size == 256)
458 size = 0;
459 grub_ata_setlba (dev, sector, size);
460 grub_ata_regset (dev, GRUB_ATA_REG_DISK,
461 0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F));
462 break;
464 case GRUB_ATA_LBA48:
465 if (size == 65536)
466 size = 0;
468 /* Set "Previous". */
469 grub_ata_setlba (dev, sector >> 24, size >> 8);
470 /* Set "Current". */
471 grub_ata_setlba (dev, sector, size);
472 grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4));
474 break;
477 return GRUB_ERR_NONE;
480 static grub_err_t
481 grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
482 grub_size_t size, char *buf, int rw)
484 struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
485 grub_size_t cnt;
486 grub_size_t batch;
487 grub_ata_addressing_t addressing;
488 int cmd;
489 int cmd_write;
490 unsigned int sect;
492 addressing = dev->addr;
494 if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
496 batch = 65536;
497 cmd = GRUB_ATA_CMD_READ_SECTORS_EXT;
498 cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT;
500 else
502 if (addressing == GRUB_ATA_LBA48)
503 addressing = GRUB_ATA_LBA;
504 batch = 256;
505 cmd = GRUB_ATA_CMD_READ_SECTORS;
506 cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
509 cnt = size / batch;
511 /* Read/write batches of 256/65536 sectors, when more than 256/65536
512 sectors should be read/written. */
513 for (; cnt; cnt--)
515 if (grub_ata_setaddress (dev, addressing, sector, batch))
516 return grub_errno;
518 if (rw == 0)
520 /* Read 256/65536 sectors. */
521 grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
522 grub_ata_wait ();
523 for (sect = 0; sect < batch; sect++)
525 if (grub_ata_pio_read (dev, buf,
526 GRUB_DISK_SECTOR_SIZE))
527 return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
528 buf += GRUB_DISK_SECTOR_SIZE;
529 sector++;
532 else
534 /* Write 256/65536 sectors. */
535 grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd_write);
536 grub_ata_wait ();
537 for (sect = 0; sect < batch; sect++)
539 if (grub_ata_pio_write (dev, buf,
540 GRUB_DISK_SECTOR_SIZE))
541 return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
542 buf += GRUB_DISK_SECTOR_SIZE;
545 sector += batch;
548 /* Read/write just a "few" sectors. */
549 if (grub_ata_setaddress (dev, addressing, sector, size % batch))
550 return grub_errno;
552 if (rw == 0)
554 /* Read sectors. */
555 grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
556 grub_ata_wait ();
557 for (sect = 0; sect < (size % batch); sect++)
559 if (grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE))
560 return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
561 buf += GRUB_DISK_SECTOR_SIZE;
563 } else {
564 /* Write sectors. */
565 grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd_write);
566 grub_ata_wait ();
567 for (sect = 0; sect < batch; sect++)
569 if (grub_ata_pio_write (dev, buf,
570 (size % batch) * GRUB_DISK_SECTOR_SIZE))
571 return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
572 buf += GRUB_DISK_SECTOR_SIZE;
576 return GRUB_ERR_NONE;
581 static int
582 grub_ata_iterate (int (*hook) (const char *name))
584 struct grub_ata_device *dev;
586 for (dev = grub_ata_devices; dev; dev = dev->next)
588 char devname[5];
589 grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
591 if (hook (devname))
592 return 1;
595 return 0;
598 static grub_err_t
599 grub_ata_open (const char *name, grub_disk_t disk)
601 struct grub_ata_device *dev;
603 for (dev = grub_ata_devices; dev; dev = dev->next)
605 char devname[5];
606 grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
607 if (grub_strcmp (name, devname) == 0)
608 break;
611 if (! dev)
612 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
614 if (dev->atapi)
615 disk->total_sectors = 9000000; /* XXX */
616 else
617 disk->total_sectors = dev->size;
619 disk->id = (int) dev;
621 disk->has_partitions = !dev->atapi;
622 disk->data = dev;
624 return 0;
627 static void
628 grub_ata_close (grub_disk_t disk __attribute__((unused)))
633 struct grub_atapi_read
635 grub_uint8_t code;
636 grub_uint8_t reserved1;
637 grub_uint32_t lba;
638 grub_uint32_t length;
639 grub_uint8_t reserved2[2];
640 } __attribute__((packed));
642 static grub_err_t
643 grub_atapi_readsector (struct grub_ata_device *dev,
644 char *buf, grub_disk_addr_t sector)
646 struct grub_atapi_read readcmd;
648 readcmd.code = 0xA8;
649 readcmd.lba = grub_cpu_to_be32 (sector);
650 readcmd.length = grub_cpu_to_be32 (1);
652 grub_atapi_packet (dev, (char *) &readcmd);
653 grub_ata_wait ();
654 grub_ata_pio_read (dev, buf, GRUB_CDROM_SECTOR_SIZE);
656 return 0;
659 static grub_err_t
660 grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector,
661 grub_size_t size, char *buf)
663 struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
664 int cdsector;
665 char *sbuf;
667 if (! dev->atapi)
668 return grub_ata_readwrite (disk, sector, size, buf, 0);
670 /* ATAPI is being used, so try to read from CDROM using ATAPI. */
672 sbuf = grub_malloc (GRUB_CDROM_SECTOR_SIZE);
673 if (! sbuf)
674 return grub_errno;
676 /* CDROMs have sectors of 2048 bytes, so chop them into pieces of
677 512 bytes. */
678 while (size > 0)
680 int rsize;
681 int offset;
682 int max;
684 cdsector = sector >> 2;
685 rsize = ((size * GRUB_DISK_SECTOR_SIZE > GRUB_CDROM_SECTOR_SIZE)
686 ? GRUB_CDROM_SECTOR_SIZE : size * GRUB_DISK_SECTOR_SIZE);
687 offset = (sector & 3) * GRUB_DISK_SECTOR_SIZE;
688 max = GRUB_CDROM_SECTOR_SIZE - offset;
689 rsize = (rsize > max) ? max : rsize;
691 grub_atapi_readsector (dev, sbuf, cdsector);
692 grub_memcpy (buf + offset, sbuf, rsize);
694 buf += rsize;
695 size -= rsize / GRUB_DISK_SECTOR_SIZE;
696 sector += rsize / GRUB_DISK_SECTOR_SIZE;
699 grub_free (sbuf);
701 return 0;
704 static grub_err_t
705 grub_ata_write (grub_disk_t disk,
706 grub_disk_addr_t sector,
707 grub_size_t size,
708 const char *buf)
710 #if 1
711 return GRUB_ERR_NOT_IMPLEMENTED_YET;
712 #else
713 return grub_ata_readwrite (disk, sector, size, (char *) buf, 1);
714 #endif
717 static struct grub_disk_dev grub_atadisk_dev =
719 .name = "ATA",
720 .id = GRUB_DISK_DEVICE_ATA_ID,
721 .iterate = grub_ata_iterate,
722 .open = grub_ata_open,
723 .close = grub_ata_close,
724 .read = grub_ata_read,
725 .write = grub_ata_write,
726 .next = 0
731 GRUB_MOD_INIT(ata)
733 (void) mod; /* To stop warning. */
735 /* To prevent two drivers operating on the same disks. */
736 grub_disk_firmware_is_tainted = 1;
737 if (grub_disk_firmware_fini)
739 grub_disk_firmware_fini ();
740 grub_disk_firmware_fini = NULL;
743 /* ATA initialization. */
744 grub_ata_initialize ();
746 grub_disk_dev_register (&grub_atadisk_dev);
749 GRUB_MOD_FINI(ata)
751 grub_disk_dev_unregister (&grub_atadisk_dev);