1 /* ata.c - ATA disk access. */
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/>.
21 #include <grub/misc.h>
22 #include <grub/disk.h>
24 #include <grub/time.h>
26 #include <grub/scsi.h>
27 /* XXX: For now this only works on i386. */
28 #include <grub/cpu/io.h>
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. */
85 /* IO addresses on which the registers for this device can be
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"). */
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
;
104 grub_uint16_t cylinders
;
106 grub_uint16_t sectors_per_track
;
108 /* Set to 0 for ATA, set to 1 for ATAPI. */
111 struct grub_ata_device
*next
;
114 static struct grub_ata_device
*grub_ata_devices
;
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
);
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
)
146 for (i
= 0; i
< 1000; i
++)
150 reg
= grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
);
151 if ((reg
& maskset
) == maskset
&& (reg
& maskclear
) == 0)
152 return GRUB_ERR_NONE
;
157 return grub_error (GRUB_ERR_TIMEOUT
, "ata timeout");
163 grub_millisleep (50);
167 grub_ata_cmd (struct grub_ata_device
*dev
, int cmd
)
171 err
= grub_ata_wait_status (dev
, 0,
172 GRUB_ATA_STATUS_DRQ
| GRUB_ATA_STATUS_BUSY
);
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. */
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
;
189 for (i
= 0; i
< len
/ 2; i
++)
190 *(dst16
++) = grub_be_to_cpu16 (*(src16
++));
195 grub_ata_pio_read (struct grub_ata_device
*dev
, char *buf
,
198 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
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))
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
;
219 grub_ata_pio_write (struct grub_ata_device
*dev
, char *buf
,
222 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
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))
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
;
243 grub_ata_dumpinfo (struct grub_ata_device
*dev
, char *info
)
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
);
257 grub_dprintf ("ata", "Addressing: %d\n", dev
->addr
);
258 grub_dprintf ("ata", "Sectors: %lld\n", dev
->size
);
263 grub_atapi_identify (struct grub_ata_device
*dev
)
267 info
= grub_malloc (256);
271 if (grub_ata_wait_status (dev
, 0, GRUB_ATA_STATUS_BUSY
))
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
))
285 if (grub_ata_pio_read (dev
, info
, 256))
293 grub_ata_dumpinfo (dev
, info
);
297 return GRUB_ERR_NONE
;
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
);
313 if (grub_ata_pio_write (dev
, packet
, 12))
316 return GRUB_ERR_NONE
;
320 grub_ata_identify (struct grub_ata_device
*dev
)
323 grub_uint16_t
*info16
;
326 info
= grub_malloc (GRUB_DISK_SECTOR_SIZE
);
330 info16
= (grub_uint16_t
*) info
;
332 if (grub_ata_wait_status (dev
, 0, GRUB_ATA_STATUS_BUSY
))
338 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | dev
->device
<< 4);
339 if (grub_ata_cmd (dev
, GRUB_ATA_CMD_IDENTIFY_DEVICE
))
346 if (grub_ata_pio_read (dev
, info
, GRUB_DISK_SECTOR_SIZE
))
347 ataerr
= grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
);
350 /* ATAPI device detected. */
352 return grub_atapi_identify (dev
);
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. */
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
;
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]));
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
);
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
));
409 /* Setup the device information. */
411 dev
->device
= device
;
412 dev
->ioaddress
= addr
;
413 dev
->ioaddress2
= addr2
;
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);
421 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, 0x5A);
423 if (grub_ata_regget (dev
, GRUB_ATA_REG_SECTORS
) != 0x5A)
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
))
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");
462 grub_dprintf ("ata", "incorrect signature\n");
468 /* Use the IDENTIFY DEVICE command to query the device. */
469 if (grub_ata_identify (dev
))
475 /* Register the device. */
476 for (devp
= &grub_ata_devices
; *devp
; devp
= &(*devp
)->next
);
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
;
494 static int controller
= 0;
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)
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;
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
];
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))
538 "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
539 bus
, device
, func
, compat
, rega
, regb
);
543 grub_ata_device_initialize (controller
* 2 + i
, 0, rega
, regb
);
544 grub_ata_device_initialize (controller
* 2 + i
, 1, rega
, regb
);
554 grub_ata_initialize (void)
556 grub_pci_iterate (grub_ata_pciinit
);
562 grub_ata_setlba (struct grub_ata_device
*dev
, grub_disk_addr_t sector
,
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);
572 grub_ata_setaddress (struct grub_ata_device
*dev
,
573 grub_ata_addressing_t addressing
,
574 grub_disk_addr_t sector
,
577 if (grub_ata_wait_status (dev
, 0, GRUB_ATA_STATUS_BUSY
))
584 unsigned int cylinder
;
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
)
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
);
612 grub_ata_setlba (dev
, sector
, size
);
613 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
,
614 0xE0 | (dev
->device
<< 4) | ((sector
>> 24) & 0x0F));
621 /* Set "Previous". */
622 grub_ata_setlba (dev
, sector
>> 24, size
>> 8);
624 grub_ata_setlba (dev
, sector
, size
);
625 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | (dev
->device
<< 4));
630 return GRUB_ERR_NONE
;
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
;
640 grub_ata_addressing_t addressing
;
645 addressing
= dev
->addr
;
647 if (addressing
== GRUB_ATA_LBA48
&& ((sector
+ size
) >> 28) != 0)
650 cmd
= GRUB_ATA_CMD_READ_SECTORS_EXT
;
651 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS_EXT
;
655 if (addressing
== GRUB_ATA_LBA48
)
656 addressing
= GRUB_ATA_LBA
;
658 cmd
= GRUB_ATA_CMD_READ_SECTORS
;
659 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS
;
664 /* Read/write batches of 256/65536 sectors, when more than 256/65536
665 sectors should be read/written. */
668 if (grub_ata_setaddress (dev
, addressing
, sector
, batch
))
673 /* Read 256/65536 sectors. */
674 if (grub_ata_cmd (dev
, cmd
))
677 /* Wait for the command to complete. */
678 if (grub_ata_wait_status (dev
, 0, GRUB_ATA_STATUS_BUSY
))
681 for (sect
= 0; sect
< batch
; sect
++)
683 if (grub_ata_pio_read (dev
, buf
,
684 GRUB_DISK_SECTOR_SIZE
))
686 buf
+= GRUB_DISK_SECTOR_SIZE
;
691 /* Write 256/65536 sectors. */
692 if (grub_ata_cmd (dev
, cmd
))
695 /* Wait for the command to complete. */
696 if (grub_ata_wait_status (dev
, 0, GRUB_ATA_STATUS_BUSY
))
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
;
710 /* Read/write just a "few" sectors. */
711 if (grub_ata_setaddress (dev
, addressing
, sector
, size
% batch
))
717 if (grub_ata_cmd (dev
, cmd
))
720 /* Wait for the command to complete. */
721 if (grub_ata_wait_status (dev
, 0, GRUB_ATA_STATUS_BUSY
))
724 for (sect
= 0; sect
< (size
% batch
); sect
++)
726 if (grub_ata_pio_read (dev
, buf
, GRUB_DISK_SECTOR_SIZE
))
728 buf
+= GRUB_DISK_SECTOR_SIZE
;
732 if (grub_ata_cmd (dev
, cmd
))
735 /* Wait for the command to complete. */
736 if (grub_ata_wait_status (dev
, 0, GRUB_ATA_STATUS_BUSY
))
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
;
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
)
760 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
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
)
780 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
781 if (grub_strcmp (name
, devname
) == 0)
786 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "Can't open device");
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;
802 grub_ata_close (grub_disk_t disk
__attribute__((unused
)))
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);
815 grub_ata_write (grub_disk_t disk
,
816 grub_disk_addr_t sector
,
820 return grub_ata_readwrite (disk
, sector
, size
, (char *) buf
, 1);
823 static struct grub_disk_dev grub_atadisk_dev
=
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
,
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
)
847 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
852 if (hook (devname
, 1))
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
))
870 grub_ata_wait (); /* XXX */
872 return grub_ata_pio_read (dev
, buf
, size
);
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
))
885 grub_ata_wait (); /* XXX */
887 return grub_ata_pio_write (dev
, buf
, size
);
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
)
899 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
901 if (!grub_strcmp (devname
, name
))
908 grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name
);
911 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "No such ATAPI device");
915 return GRUB_ERR_NONE
;
919 grub_atapi_close (struct grub_scsi
*scsi
)
921 grub_free (scsi
->name
);
924 static struct grub_scsi_dev grub_atapi_dev
=
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
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
);
959 grub_scsi_dev_unregister (&grub_atapi_dev
);
960 grub_disk_dev_unregister (&grub_atadisk_dev
);