blob: 0ad35900367413ff551614b8201e6b2d3074653f [file] [log] [blame]
Kevin O'Connorc09492e2008-03-01 13:38:07 -05001// 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'Connor6eee8ca2008-03-03 20:14:12 -05008#ifndef __ATA_H
9#define __ATA_H
10
Kevin O'Connor3491e8b2008-02-29 00:22:27 -050011#include "types.h" // u16
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040012#include "atabits.h"
13
14struct 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'Connor3491e8b2008-02-29 00:22:27 -050032
33// Function definitions
34void ata_reset(u16 device);
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040035int ata_transfer(struct ata_pio_command *cmd);
36int ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen
37 , u16 header, u32 length, u16 bufseg, u16 bufoff);
38int cdrom_read(u16 device, u32 lba, u32 count
Kevin O'Connor180a9592008-03-04 22:50:53 -050039 , u16 segment, u16 offset, u16 skip);
Kevin O'Connor15aee2e2008-03-01 13:34:04 -050040void ata_detect();
Kevin O'Connor3491e8b2008-02-29 00:22:27 -050041
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040042static inline int
43ata_cmd_data(u16 biosid, u16 command, u32 lba, u16 count
44 , u16 segment, u16 offset)
45{
46 u8 slave = biosid % 2;
Kevin O'Connor3491e8b2008-02-29 00:22:27 -050047
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040048 struct ata_pio_command cmd;
49 cmd.biosid = biosid;
50 cmd.segment = segment;
51 cmd.offset = offset;
Kevin O'Connor3491e8b2008-02-29 00:22:27 -050052
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040053 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'Connor3491e8b2008-02-29 00:22:27 -050058
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040059 command |= 0x04;
60 lba &= 0xffffff;
61 }
Kevin O'Connor3491e8b2008-02-29 00:22:27 -050062
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040063 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'Connor3491e8b2008-02-29 00:22:27 -050073
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040074static inline int
75ata_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'Connor3491e8b2008-02-29 00:22:27 -050079
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040080 struct ata_pio_command cmd;
81 cmd.biosid = biosid;
82 cmd.segment = segment;
83 cmd.offset = offset;
Kevin O'Connor3491e8b2008-02-29 00:22:27 -050084
Kevin O'Connor1fcf1442008-03-11 19:42:41 -040085 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'Connor3491e8b2008-02-29 00:22:27 -050094
Kevin O'Connor6eee8ca2008-03-03 20:14:12 -050095#endif /* __ATA_H */