Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / common / boot / grub2 / disk / ata.c
blob214a2cac7c3dacc511aca03bae0b10c9a1a96425
1 /* ata.c - ATA disk access. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2007, 2008 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 #include <grub/pci.h>
26 #include <grub/scsi.h>
27 /* XXX: For now this only works on i386. */
28 #include <grub/cpu/io.h>
30 typedef enum
32 GRUB_ATA_CHS,
33 GRUB_ATA_LBA,
34 GRUB_ATA_LBA48
35 } grub_ata_addressing_t;
37 /* At the moment, only two IDE ports are supported. */
38 static const int grub_ata_ioaddress[] = { 0x1f0, 0x170 };
39 static const int grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
41 #define GRUB_CDROM_SECTOR_SIZE 2048
43 #define GRUB_ATA_REG_DATA 0
44 #define GRUB_ATA_REG_ERROR 1
45 #define GRUB_ATA_REG_FEATURES 1
46 #define GRUB_ATA_REG_SECTORS 2
47 #define GRUB_ATA_REG_SECTNUM 3
48 #define GRUB_ATA_REG_CYLLSB 4
49 #define GRUB_ATA_REG_CYLMSB 5
50 #define GRUB_ATA_REG_LBALOW 3
51 #define GRUB_ATA_REG_LBAMID 4
52 #define GRUB_ATA_REG_LBAHIGH 5
53 #define GRUB_ATA_REG_DISK 6
54 #define GRUB_ATA_REG_CMD 7
55 #define GRUB_ATA_REG_STATUS 7
57 #define GRUB_ATA_REG2_CONTROL 0
59 #define GRUB_ATA_STATUS_ERR 0x01
60 #define GRUB_ATA_STATUS_INDEX 0x02
61 #define GRUB_ATA_STATUS_ECC 0x04
62 #define GRUB_ATA_STATUS_DRQ 0x08
63 #define GRUB_ATA_STATUS_SEEK 0x10
64 #define GRUB_ATA_STATUS_WRERR 0x20
65 #define GRUB_ATA_STATUS_READY 0x40
66 #define GRUB_ATA_STATUS_BUSY 0x80
68 enum grub_ata_commands
70 GRUB_ATA_CMD_READ_SECTORS = 0x20,
71 GRUB_ATA_CMD_READ_SECTORS_EXT = 0x24,
72 GRUB_ATA_CMD_WRITE_SECTORS = 0x30,
73 GRUB_ATA_CMD_WRITE_SECTORS_EXT = 0x34,
74 GRUB_ATA_CMD_IDENTIFY_DEVICE = 0xEC,
75 GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE = 0xA1,
76 GRUB_ATA_CMD_PACKET = 0xA0,
77 GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS = 0x90
80 struct grub_ata_device
82 /* IDE port to use. */
83 int port;
85 /* IO addresses on which the registers for this device can be
86 found. */
87 int ioaddress;
88 int ioaddress2;
90 /* Two devices can be connected to a single cable. Use this field
91 to select device 0 (commonly known as "master") or device 1
92 (commonly known as "slave"). */
93 int device;
95 /* Addressing methods available for accessing this device. If CHS
96 is only available, use that. Otherwise use LBA, except for the
97 high sectors. In that case use LBA48. */
98 grub_ata_addressing_t addr;
100 /* Sector count. */
101 grub_uint64_t size;
103 /* CHS maximums. */
104 grub_uint16_t cylinders;
105 grub_uint16_t heads;
106 grub_uint16_t sectors_per_track;
108 /* Set to 0 for ATA, set to 1 for ATAPI. */
109 int atapi;
111 struct grub_ata_device *next;
114 static struct grub_ata_device *grub_ata_devices;
116 static inline void
117 grub_ata_regset (struct grub_ata_device *dev, int reg, int val)
119 grub_outb (val, dev->ioaddress + reg);
122 static inline grub_uint8_t
123 grub_ata_regget (struct grub_ata_device *dev, int reg)
125 return grub_inb (dev->ioaddress + reg);
128 static inline void
129 grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val)
131 grub_outb (val, dev->ioaddress2 + reg);
134 static inline grub_uint8_t
135 grub_ata_regget2 (struct grub_ata_device *dev, int reg)
137 return grub_inb (dev->ioaddress2 + reg);
140 static inline grub_err_t
141 grub_ata_wait_status (struct grub_ata_device *dev,
142 grub_uint8_t maskset, grub_uint8_t maskclear)
144 int i;
146 for (i = 0; i < 1000; i++)
148 grub_uint8_t reg;
150 reg = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
151 if ((reg & maskset) == maskset && (reg & maskclear) == 0)
152 return GRUB_ERR_NONE;
154 grub_millisleep (1);
157 return grub_error (GRUB_ERR_TIMEOUT, "ata timeout");
160 static inline void
161 grub_ata_wait (void)
163 grub_millisleep (50);
166 static grub_err_t
167 grub_ata_cmd (struct grub_ata_device *dev, int cmd)
169 grub_err_t err;
171 err = grub_ata_wait_status (dev, 0,
172 GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_BUSY);
173 if (err)
174 return err;
176 grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
178 return GRUB_ERR_NONE;
181 /* Byteorder has to be changed before strings can be read. */
182 static inline void
183 grub_ata_strncpy (char *dst, char *src, grub_size_t len)
185 grub_uint16_t *src16 = (grub_uint16_t *) src;
186 grub_uint16_t *dst16 = (grub_uint16_t *) dst;
187 unsigned int i;
189 for (i = 0; i < len / 2; i++)
190 *(dst16++) = grub_be_to_cpu16 (*(src16++));
191 dst[len] = '\0';
194 static grub_err_t
195 grub_ata_pio_read (struct grub_ata_device *dev, char *buf,
196 grub_size_t size)
198 grub_uint16_t *buf16 = (grub_uint16_t *) buf;
199 unsigned int i;
201 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
202 return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
204 /* Wait until the data is available. */
205 if (grub_ata_wait_status (dev, GRUB_ATA_STATUS_DRQ, 0))
206 return grub_errno;;
208 /* Read in the data, word by word. */
209 for (i = 0; i < size / 2; i++)
210 buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
212 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
213 return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
215 return GRUB_ERR_NONE;
218 static grub_err_t
219 grub_ata_pio_write (struct grub_ata_device *dev, char *buf,
220 grub_size_t size)
222 grub_uint16_t *buf16 = (grub_uint16_t *) buf;
223 unsigned int i;
225 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
226 return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
228 /* Wait until the data is available. */
229 if (grub_ata_wait_status (dev, GRUB_ATA_STATUS_DRQ, 0))
230 return 0;
232 /* Write the data, word by word. */
233 for (i = 0; i < size / 2; i++)
234 grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
236 if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
237 return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
239 return GRUB_ERR_NONE;
242 static void
243 grub_ata_dumpinfo (struct grub_ata_device *dev, char *info)
245 char text[41];
247 /* The device information was read, dump it for debugging. */
248 grub_ata_strncpy (text, info + 20, 20);
249 grub_dprintf ("ata", "Serial: %s\n", text);
250 grub_ata_strncpy (text, info + 46, 8);
251 grub_dprintf ("ata", "Firmware: %s\n", text);
252 grub_ata_strncpy (text, info + 54, 40);
253 grub_dprintf ("ata", "Model: %s\n", text);
255 if (! dev->atapi)
257 grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
258 grub_dprintf ("ata", "Sectors: %lld\n", dev->size);
262 static grub_err_t
263 grub_atapi_identify (struct grub_ata_device *dev)
265 char *info;
267 info = grub_malloc (256);
268 if (! info)
269 return grub_errno;
271 if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
273 grub_free (info);
274 return grub_errno;
277 grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
279 if (grub_ata_cmd (dev, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE))
281 grub_free (info);
282 return grub_errno;
285 if (grub_ata_pio_read (dev, info, 256))
287 grub_free (info);
288 return grub_errno;
291 dev->atapi = 1;
293 grub_ata_dumpinfo (dev, info);
295 grub_free (info);
297 return GRUB_ERR_NONE;
300 static grub_err_t
301 grub_atapi_packet (struct grub_ata_device *dev, char *packet)
303 grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
304 grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0);
305 grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0);
306 grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, 0xFF);
307 grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, 0xFF);
309 grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET);
311 grub_ata_wait ();
313 if (grub_ata_pio_write (dev, packet, 12))
314 return grub_errno;
316 return GRUB_ERR_NONE;
319 static grub_err_t
320 grub_ata_identify (struct grub_ata_device *dev)
322 char *info;
323 grub_uint16_t *info16;
324 int ataerr = 0;
326 info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
327 if (! info)
328 return grub_errno;
330 info16 = (grub_uint16_t *) info;
332 if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
334 grub_free (info);
335 return grub_errno;
338 grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
339 if (grub_ata_cmd (dev, GRUB_ATA_CMD_IDENTIFY_DEVICE))
341 grub_free (info);
342 return grub_errno;
344 grub_ata_wait ();
346 if (grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE))
347 ataerr = grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
348 if (ataerr & 4)
350 /* ATAPI device detected. */
351 grub_free(info);
352 return grub_atapi_identify (dev);
354 else if (ataerr)
356 /* Error. */
357 grub_free(info);
358 return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
359 "device can not be identified");
362 /* Now it is certain that this is not an ATAPI device. */
363 dev->atapi = 0;
365 /* CHS is always supported. */
366 dev->addr = GRUB_ATA_CHS;
368 /* Check if LBA is supported. */
369 if (info16[49] & (1 << 9))
371 /* Check if LBA48 is supported. */
372 if (info16[83] & (1 << 10))
373 dev->addr = GRUB_ATA_LBA48;
374 else
375 dev->addr = GRUB_ATA_LBA;
378 /* Determine the amount of sectors. */
379 if (dev->addr != GRUB_ATA_LBA48)
380 dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60]));
381 else
382 dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100]));
384 /* Read CHS information. */
385 dev->cylinders = info16[1];
386 dev->heads = info16[3];
387 dev->sectors_per_track = info16[6];
389 grub_ata_dumpinfo (dev, info);
391 grub_free(info);
393 return 0;
396 static grub_err_t
397 grub_ata_device_initialize (int port, int device, int addr, int addr2)
399 struct grub_ata_device *dev;
400 struct grub_ata_device **devp;
402 grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
403 port, device, addr, addr2);
405 dev = grub_malloc (sizeof(*dev));
406 if (! dev)
407 return grub_errno;
409 /* Setup the device information. */
410 dev->port = port;
411 dev->device = device;
412 dev->ioaddress = addr;
413 dev->ioaddress2 = addr2;
414 dev->next = NULL;
416 /* Try to detect if the port is in use by writing to it,
417 waiting for a while and reading it again. If the value
418 was preserved, there is a device connected. */
419 grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
420 grub_ata_wait ();
421 grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
422 grub_ata_wait ();
423 if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) != 0x5A)
425 grub_free(dev);
426 return 0;
429 /* Detect if the device is present by issuing a EXECUTE
430 DEVICE DIAGNOSTICS command. */
431 grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
432 if (grub_ata_cmd (dev, GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS))
434 grub_free (dev);
435 return grub_errno;
437 grub_ata_wait ();
439 grub_dprintf ("ata", "Registers: %x %x %x %x\n",
440 grub_ata_regget (dev, GRUB_ATA_REG_SECTORS),
441 grub_ata_regget (dev, GRUB_ATA_REG_LBALOW),
442 grub_ata_regget (dev, GRUB_ATA_REG_LBAMID),
443 grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH));
445 /* Check some registers to see if the channel is used. */
446 if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) == 0x01
447 && grub_ata_regget (dev, GRUB_ATA_REG_LBALOW) == 0x01
448 && grub_ata_regget (dev, GRUB_ATA_REG_LBAMID) == 0x14
449 && grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH) == 0xeb)
451 grub_dprintf ("ata", "ATAPI signature detected\n");
453 else if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) == 0x01
454 && grub_ata_regget (dev, GRUB_ATA_REG_LBALOW) == 0x01
455 && grub_ata_regget (dev, GRUB_ATA_REG_LBAMID) == 0x00
456 && grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH) == 0x00)
458 grub_dprintf ("ata", "ATA detected\n");
460 else
462 grub_dprintf ("ata", "incorrect signature\n");
463 grub_free (dev);
464 return 0;
468 /* Use the IDENTIFY DEVICE command to query the device. */
469 if (grub_ata_identify (dev))
471 grub_free (dev);
472 return 0;
475 /* Register the device. */
476 for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
477 *devp = dev;
479 return 0;
482 static int
483 grub_ata_pciinit (int bus, int device, int func,
484 grub_pci_id_t pciid __attribute__((unused)))
486 static int compat_use[2] = { 0 };
487 grub_pci_address_t addr;
488 grub_uint32_t class;
489 grub_uint32_t bar1;
490 grub_uint32_t bar2;
491 int rega;
492 int regb;
493 int i;
494 static int controller = 0;
496 /* Read class. */
497 addr = grub_pci_make_address (bus, device, func, 2);
498 class = grub_pci_read (addr);
500 /* Check if this class ID matches that of a PCI IDE Controller. */
501 if (class >> 16 != 0x0101)
502 return 0;
504 for (i = 0; i < 2; i++)
506 /* Set to 0 when the channel operated in compatibility mode. */
507 int compat = (class >> (2 * i)) & 1;
509 rega = 0;
510 regb = 0;
512 /* If the channel is in compatibility mode, just assign the
513 default registers. */
514 if (compat == 0 && !compat_use[i])
516 rega = grub_ata_ioaddress[i];
517 regb = grub_ata_ioaddress2[i];
518 compat_use[i] = 0;
520 else if (compat)
522 /* Read the BARs, which either contain a mmapped IO address
523 or the IO port address. */
524 addr = grub_pci_make_address (bus, device, func, 4 + 2 * i);
525 bar1 = grub_pci_read (addr);
526 addr = grub_pci_make_address (bus, device, func, 5 + 2 * i);
527 bar2 = grub_pci_read (addr);
529 /* Check if the BARs describe an IO region. */
530 if ((bar1 & 1) && (bar2 & 1))
532 rega = bar1 & ~3;
533 regb = bar2 & ~3;
537 grub_dprintf ("ata",
538 "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
539 bus, device, func, compat, rega, regb);
541 if (rega && regb)
543 grub_ata_device_initialize (controller * 2 + i, 0, rega, regb);
544 grub_ata_device_initialize (controller * 2 + i, 1, rega, regb);
548 controller++;
550 return 0;
553 static grub_err_t
554 grub_ata_initialize (void)
556 grub_pci_iterate (grub_ata_pciinit);
557 return 0;
561 static void
562 grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
563 grub_size_t size)
565 grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size);
566 grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF);
567 grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
568 grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
571 static grub_err_t
572 grub_ata_setaddress (struct grub_ata_device *dev,
573 grub_ata_addressing_t addressing,
574 grub_disk_addr_t sector,
575 grub_size_t size)
577 if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
578 return grub_errno;
580 switch (addressing)
582 case GRUB_ATA_CHS:
584 unsigned int cylinder;
585 unsigned int head;
586 unsigned int sect;
588 /* Calculate the sector, cylinder and head to use. */
589 sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
590 cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)
591 / dev->heads);
592 head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads;
594 if (sect > dev->sectors_per_track
595 || cylinder > dev->cylinders
596 || head > dev->heads)
597 return grub_error (GRUB_ERR_OUT_OF_RANGE,
598 "sector %d can not be addressed "
599 "using CHS addressing", sector);
601 grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect);
602 grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF);
603 grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8);
604 grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head);
606 break;
609 case GRUB_ATA_LBA:
610 if (size == 256)
611 size = 0;
612 grub_ata_setlba (dev, sector, size);
613 grub_ata_regset (dev, GRUB_ATA_REG_DISK,
614 0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F));
615 break;
617 case GRUB_ATA_LBA48:
618 if (size == 65536)
619 size = 0;
621 /* Set "Previous". */
622 grub_ata_setlba (dev, sector >> 24, size >> 8);
623 /* Set "Current". */
624 grub_ata_setlba (dev, sector, size);
625 grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4));
627 break;
630 return GRUB_ERR_NONE;
633 static grub_err_t
634 grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
635 grub_size_t size, char *buf, int rw)
637 struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
638 grub_size_t cnt;
639 grub_size_t batch;
640 grub_ata_addressing_t addressing;
641 int cmd;
642 int cmd_write;
643 unsigned int sect;
645 addressing = dev->addr;
647 if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
649 batch = 65536;
650 cmd = GRUB_ATA_CMD_READ_SECTORS_EXT;
651 cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT;
653 else
655 if (addressing == GRUB_ATA_LBA48)
656 addressing = GRUB_ATA_LBA;
657 batch = 256;
658 cmd = GRUB_ATA_CMD_READ_SECTORS;
659 cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
662 cnt = size / batch;
664 /* Read/write batches of 256/65536 sectors, when more than 256/65536
665 sectors should be read/written. */
666 for (; cnt; cnt--)
668 if (grub_ata_setaddress (dev, addressing, sector, batch))
669 return grub_errno;
671 if (rw == 0)
673 /* Read 256/65536 sectors. */
674 if (grub_ata_cmd (dev, cmd))
675 return grub_errno;
677 /* Wait for the command to complete. */
678 if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
679 return grub_errno;
681 for (sect = 0; sect < batch; sect++)
683 if (grub_ata_pio_read (dev, buf,
684 GRUB_DISK_SECTOR_SIZE))
685 return grub_errno;
686 buf += GRUB_DISK_SECTOR_SIZE;
689 else
691 /* Write 256/65536 sectors. */
692 if (grub_ata_cmd (dev, cmd))
693 return grub_errno;
695 /* Wait for the command to complete. */
696 if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
697 return grub_errno;
699 for (sect = 0; sect < batch; sect++)
701 if (grub_ata_pio_write (dev, buf,
702 GRUB_DISK_SECTOR_SIZE))
703 return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
704 buf += GRUB_DISK_SECTOR_SIZE;
707 sector += batch;
710 /* Read/write just a "few" sectors. */
711 if (grub_ata_setaddress (dev, addressing, sector, size % batch))
712 return grub_errno;
714 if (rw == 0)
716 /* Read sectors. */
717 if (grub_ata_cmd (dev, cmd))
718 return grub_errno;
720 /* Wait for the command to complete. */
721 if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
722 return grub_errno;
724 for (sect = 0; sect < (size % batch); sect++)
726 if (grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE))
727 return grub_errno;
728 buf += GRUB_DISK_SECTOR_SIZE;
730 } else {
731 /* Write sectors. */
732 if (grub_ata_cmd (dev, cmd))
733 return grub_errno;
735 /* Wait for the command to complete. */
736 if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
737 return grub_errno;
739 for (sect = 0; sect < (size % batch); sect++)
741 if (grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE))
742 return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
743 buf += GRUB_DISK_SECTOR_SIZE;
747 return GRUB_ERR_NONE;
752 static int
753 grub_ata_iterate (int (*hook) (const char *name))
755 struct grub_ata_device *dev;
757 for (dev = grub_ata_devices; dev; dev = dev->next)
759 char devname[5];
760 grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
762 if (dev->atapi)
763 continue;
765 if (hook (devname))
766 return 1;
769 return 0;
772 static grub_err_t
773 grub_ata_open (const char *name, grub_disk_t disk)
775 struct grub_ata_device *dev;
777 for (dev = grub_ata_devices; dev; dev = dev->next)
779 char devname[5];
780 grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
781 if (grub_strcmp (name, devname) == 0)
782 break;
785 if (! dev)
786 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
788 if (dev->atapi)
789 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
791 disk->total_sectors = dev->size;
793 disk->id = (unsigned long) dev;
795 disk->has_partitions = 1;
796 disk->data = dev;
798 return 0;
801 static void
802 grub_ata_close (grub_disk_t disk __attribute__((unused)))
807 static grub_err_t
808 grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector,
809 grub_size_t size, char *buf)
811 return grub_ata_readwrite (disk, sector, size, buf, 0);
814 static grub_err_t
815 grub_ata_write (grub_disk_t disk,
816 grub_disk_addr_t sector,
817 grub_size_t size,
818 const char *buf)
820 return grub_ata_readwrite (disk, sector, size, (char *) buf, 1);
823 static struct grub_disk_dev grub_atadisk_dev =
825 .name = "ATA",
826 .id = GRUB_DISK_DEVICE_ATA_ID,
827 .iterate = grub_ata_iterate,
828 .open = grub_ata_open,
829 .close = grub_ata_close,
830 .read = grub_ata_read,
831 .write = grub_ata_write,
832 .next = 0
837 /* ATAPI code. */
839 static int
840 grub_atapi_iterate (int (*hook) (const char *name, int luns))
842 struct grub_ata_device *dev;
844 for (dev = grub_ata_devices; dev; dev = dev->next)
846 char devname[7];
847 grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
849 if (! dev->atapi)
850 continue;
852 if (hook (devname, 1))
853 return 1;
856 return 0;
860 static grub_err_t
861 grub_atapi_read (struct grub_scsi *scsi,
862 grub_size_t cmdsize __attribute__((unused)),
863 char *cmd, grub_size_t size, char *buf)
865 struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data;
867 if (grub_atapi_packet (dev, cmd))
868 return grub_errno;
870 grub_ata_wait (); /* XXX */
872 return grub_ata_pio_read (dev, buf, size);
875 static grub_err_t
876 grub_atapi_write (struct grub_scsi *scsi,
877 grub_size_t cmdsize __attribute__((unused)),
878 char *cmd, grub_size_t size, char *buf)
880 struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data;
882 if (grub_atapi_packet (dev, cmd))
883 return grub_errno;
885 grub_ata_wait (); /* XXX */
887 return grub_ata_pio_write (dev, buf, size);
890 static grub_err_t
891 grub_atapi_open (const char *name, struct grub_scsi *scsi)
893 struct grub_ata_device *dev;
894 struct grub_ata_device *devfnd = 0;
896 for (dev = grub_ata_devices; dev; dev = dev->next)
898 char devname[7];
899 grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
901 if (!grub_strcmp (devname, name))
903 devfnd = dev;
904 break;
908 grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name);
910 if (! devfnd)
911 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such ATAPI device");
913 scsi->data = devfnd;
915 return GRUB_ERR_NONE;
918 static void
919 grub_atapi_close (struct grub_scsi *scsi)
921 grub_free (scsi->name);
924 static struct grub_scsi_dev grub_atapi_dev =
926 .name = "ATAPI",
927 .iterate = grub_atapi_iterate,
928 .open = grub_atapi_open,
929 .close = grub_atapi_close,
930 .read = grub_atapi_read,
931 .write = grub_atapi_write
936 GRUB_MOD_INIT(ata)
938 (void) mod; /* To stop warning. */
940 /* To prevent two drivers operating on the same disks. */
941 grub_disk_firmware_is_tainted = 1;
942 if (grub_disk_firmware_fini)
944 grub_disk_firmware_fini ();
945 grub_disk_firmware_fini = NULL;
948 /* ATA initialization. */
949 grub_ata_initialize ();
951 grub_disk_dev_register (&grub_atadisk_dev);
953 /* ATAPI devices are handled by scsi.mod. */
954 grub_scsi_dev_register (&grub_atapi_dev);
957 GRUB_MOD_FINI(ata)
959 grub_scsi_dev_unregister (&grub_atapi_dev);
960 grub_disk_dev_unregister (&grub_atadisk_dev);