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 { |
| 15 | u16 segment; |
| 16 | u16 offset; |
| 17 | u8 biosid; |
| 18 | |
| 19 | u8 feature; |
| 20 | u8 sector_count; |
| 21 | u8 lba_low; |
| 22 | u8 lba_mid; |
| 23 | u8 lba_high; |
| 24 | u8 device; |
| 25 | u8 command; |
| 26 | |
| 27 | u8 sector_count2; |
| 28 | u8 lba_low2; |
| 29 | u8 lba_mid2; |
| 30 | u8 lba_high2; |
| 31 | }; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 32 | |
| 33 | // Function definitions |
| 34 | void ata_reset(u16 device); |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 35 | int ata_transfer(struct ata_pio_command *cmd); |
| 36 | int ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen |
| 37 | , u16 header, u32 length, u16 bufseg, u16 bufoff); |
| 38 | int cdrom_read(u16 device, u32 lba, u32 count |
Kevin O'Connor | 180a959 | 2008-03-04 22:50:53 -0500 | [diff] [blame] | 39 | , u16 segment, u16 offset, u16 skip); |
Kevin O'Connor | 15aee2e | 2008-03-01 13:34:04 -0500 | [diff] [blame] | 40 | void ata_detect(); |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 41 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 42 | static inline int |
| 43 | ata_cmd_data(u16 biosid, u16 command, u32 lba, u16 count |
| 44 | , u16 segment, u16 offset) |
| 45 | { |
| 46 | u8 slave = biosid % 2; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 47 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 48 | struct ata_pio_command cmd; |
| 49 | cmd.biosid = biosid; |
| 50 | cmd.segment = segment; |
| 51 | cmd.offset = offset; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 52 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 53 | if (count >= (1<<8) || lba + count >= (1<<28)) { |
| 54 | cmd.sector_count2 = count >> 8; |
| 55 | cmd.lba_low2 = lba >> 24; |
| 56 | cmd.lba_mid2 = 0; |
| 57 | cmd.lba_high2 = 0; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 58 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 59 | command |= 0x04; |
| 60 | lba &= 0xffffff; |
| 61 | } |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 62 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 63 | cmd.feature = 0; |
| 64 | cmd.sector_count = count; |
| 65 | cmd.lba_low = lba; |
| 66 | cmd.lba_mid = lba >> 8; |
| 67 | cmd.lba_high = lba >> 16; |
| 68 | cmd.device = ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) |
| 69 | | ((lba >> 24) & 0xf) | ATA_CB_DH_LBA); |
| 70 | cmd.command = command; |
| 71 | return ata_transfer(&cmd); |
| 72 | } |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 73 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 74 | static inline int |
| 75 | ata_cmd_data_chs(u16 biosid, u16 command, u16 cyl, u16 head, u16 sect, u16 count |
| 76 | , u16 segment, u16 offset) |
| 77 | { |
| 78 | u8 slave = biosid % 2; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 79 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 80 | struct ata_pio_command cmd; |
| 81 | cmd.biosid = biosid; |
| 82 | cmd.segment = segment; |
| 83 | cmd.offset = offset; |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 84 | |
Kevin O'Connor | 1fcf144 | 2008-03-11 19:42:41 -0400 | [diff] [blame] | 85 | cmd.sector_count = count & 0xff; |
| 86 | cmd.feature = 0; |
| 87 | cmd.lba_low = sect; |
| 88 | cmd.lba_mid = cyl; |
| 89 | cmd.lba_high = cyl >> 8; |
| 90 | cmd.device = (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (head & 0xff); |
| 91 | cmd.command = command; |
| 92 | return ata_transfer(&cmd); |
| 93 | } |
Kevin O'Connor | 3491e8b | 2008-02-29 00:22:27 -0500 | [diff] [blame] | 94 | |
Kevin O'Connor | 6eee8ca | 2008-03-03 20:14:12 -0500 | [diff] [blame] | 95 | #endif /* __ATA_H */ |