Kevin O'Connor | c09492e | 2008-03-01 13:38:07 -0500 | [diff] [blame] | 1 | // Low level ATA disk definitions |
| 2 | // |
| 3 | // Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net> |
| 4 | // Copyright (C) 2002 MandrakeSoft S.A. |
| 5 | // |
| 6 | // This file may be distributed under the terms of the GNU GPLv3 license. |
| 7 | |
Kevin O'Connor | 6eee8ca | 2008-03-03 20:14:12 -0500 | [diff] [blame] | 8 | #ifndef __ATA_H |
| 9 | #define __ATA_H |
| 10 | |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 11 | #include "types.h" // u16 |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 12 | #include "atabits.h" |
| 13 | |
| 14 | struct ata_pio_command { |
Kevin O'Connor | efde609 | 2008-03-12 20:33:15 -0400 | [diff] [blame^] | 15 | void *far_buffer; |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 16 | u8 biosid; |
| 17 | |
| 18 | u8 feature; |
| 19 | u8 sector_count; |
| 20 | u8 lba_low; |
| 21 | u8 lba_mid; |
| 22 | u8 lba_high; |
| 23 | u8 device; |
| 24 | u8 command; |
| 25 | |
| 26 | u8 sector_count2; |
| 27 | u8 lba_low2; |
| 28 | u8 lba_mid2; |
| 29 | u8 lba_high2; |
| 30 | }; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 31 | |
| 32 | // Function definitions |
| 33 | void ata_reset(u16 device); |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 34 | int ata_transfer(struct ata_pio_command *cmd); |
| 35 | int ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen |
Kevin O'Connor | efde609 | 2008-03-12 20:33:15 -0400 | [diff] [blame^] | 36 | , u16 header, u32 length, void *far_buffer); |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 37 | int cdrom_read(u16 device, u32 lba, u32 count |
Kevin O'Connor | efde609 | 2008-03-12 20:33:15 -0400 | [diff] [blame^] | 38 | , void *far_buffer, u16 skip); |
Kevin O'Connor | 15aee2e | 2008-03-01 13:34:04 -0500 | [diff] [blame] | 39 | void ata_detect(); |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 40 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 41 | static inline int |
Kevin O'Connor | efde609 | 2008-03-12 20:33:15 -0400 | [diff] [blame^] | 42 | ata_cmd_data(u16 biosid, u16 command, u32 lba, u16 count, void *far_buffer) |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 43 | { |
| 44 | u8 slave = biosid % 2; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 45 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 46 | struct ata_pio_command cmd; |
Kevin O'Connor | efde609 | 2008-03-12 20:33:15 -0400 | [diff] [blame^] | 47 | cmd.far_buffer = far_buffer; |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 48 | cmd.biosid = biosid; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 49 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 50 | if (count >= (1<<8) || lba + count >= (1<<28)) { |
| 51 | cmd.sector_count2 = count >> 8; |
| 52 | cmd.lba_low2 = lba >> 24; |
| 53 | cmd.lba_mid2 = 0; |
| 54 | cmd.lba_high2 = 0; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 55 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 56 | command |= 0x04; |
| 57 | lba &= 0xffffff; |
| 58 | } |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 59 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 60 | cmd.feature = 0; |
| 61 | cmd.sector_count = count; |
| 62 | cmd.lba_low = lba; |
| 63 | cmd.lba_mid = lba >> 8; |
| 64 | cmd.lba_high = lba >> 16; |
| 65 | cmd.device = ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) |
| 66 | | ((lba >> 24) & 0xf) | ATA_CB_DH_LBA); |
| 67 | cmd.command = command; |
| 68 | return ata_transfer(&cmd); |
| 69 | } |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 70 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 71 | static inline int |
| 72 | ata_cmd_data_chs(u16 biosid, u16 command, u16 cyl, u16 head, u16 sect, u16 count |
Kevin O'Connor | efde609 | 2008-03-12 20:33:15 -0400 | [diff] [blame^] | 73 | , void *far_buffer) |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 74 | { |
| 75 | u8 slave = biosid % 2; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 76 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 77 | struct ata_pio_command cmd; |
Kevin O'Connor | efde609 | 2008-03-12 20:33:15 -0400 | [diff] [blame^] | 78 | cmd.far_buffer = far_buffer; |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 79 | cmd.biosid = biosid; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 80 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 81 | cmd.sector_count = count & 0xff; |
| 82 | cmd.feature = 0; |
| 83 | cmd.lba_low = sect; |
| 84 | cmd.lba_mid = cyl; |
| 85 | cmd.lba_high = cyl >> 8; |
| 86 | cmd.device = (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (head & 0xff); |
| 87 | cmd.command = command; |
| 88 | return ata_transfer(&cmd); |
| 89 | } |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 90 | |
Kevin O'Connor | 6eee8ca | 2008-03-03 20:14:12 -0500 | [diff] [blame] | 91 | #endif /* __ATA_H */ |