Mercurial > nand-ecoscentric
annotate packages/devs/disk/ide/current/src/ide_disk.c @ 3403:8c8767bb9a62 default tip
devs/nand/micron_mt29: Remove defunct references (in comments) to mt29f2g08_oob_ecc.
| author | Ross Younger <wry@ecoscentric.com> |
|---|---|
| date | Sun, 18 Jan 2015 17:59:01 +1300 |
| parents | 74dbf4c3f2e1 |
| children |
| rev | line source |
|---|---|
| 1814 | 1 //========================================================================== |
| 2 // | |
| 3 // ide_disk.c | |
| 4 // | |
| 5 // IDE polled mode disk driver | |
| 6 // | |
| 7 //========================================================================== | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
8 // ####ECOSGPLCOPYRIGHTBEGIN#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
9 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc. |
| 1814 | 12 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
16 // version. |
| 1814 | 17 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
18 // eCos is distributed in the hope that it will be useful, but WITHOUT |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
19 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
21 // for more details. |
| 1814 | 22 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
23 // You should have received a copy of the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
24 // along with eCos; if not, write to the Free Software Foundation, Inc., |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
25 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 1814 | 26 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
27 // As a special exception, if other files instantiate templates or use |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
28 // macros or inline functions from this file, or you compile this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
29 // and link it with other works to produce a work based on this file, |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
30 // this file does not by itself cause the resulting work to be covered by |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
31 // the GNU General Public License. However the source code for this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
32 // must still be made available in accordance with section (3) of the GNU |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
33 // General Public License v2. |
| 1814 | 34 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
35 // This exception does not invalidate any other reasons why a work based |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
36 // on this file might be covered by the GNU General Public License. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
37 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2535
diff
changeset
|
38 // ####ECOSGPLCOPYRIGHTEND#### |
| 1814 | 39 //========================================================================== |
| 40 //#####DESCRIPTIONBEGIN#### | |
| 41 // | |
| 42 // Author(s): iz | |
| 43 // Contributors: | |
| 44 // Date: 2004-10-16 | |
| 45 // | |
| 46 //####DESCRIPTIONEND#### | |
| 47 // | |
| 48 //========================================================================== | |
| 49 | |
| 50 #include <pkgconf/devs_disk_ide.h> | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
51 #include <pkgconf/io_disk.h> |
| 1814 | 52 |
| 53 #include <cyg/infra/cyg_type.h> | |
| 54 #include <cyg/infra/cyg_ass.h> | |
| 55 #include <cyg/infra/diag.h> | |
| 56 #include <cyg/hal/hal_arch.h> | |
| 57 #include <cyg/hal/hal_io.h> | |
| 58 #include <cyg/hal/hal_if.h> // delays | |
| 59 #include <cyg/hal/drv_api.h> | |
| 60 #include <cyg/io/io.h> | |
| 61 #include <cyg/io/devtab.h> | |
| 62 #include <cyg/io/disk.h> | |
| 63 | |
| 64 #include "ide_disk.h" | |
| 65 | |
| 66 // ---------------------------------------------------------------------------- | |
| 67 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
68 #ifdef CYGDBG_IO_DISK_DEBUG |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
69 # define DEBUG 1 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
70 #endif |
| 1814 | 71 |
| 72 #ifdef DEBUG | |
| 73 # define D(fmt,args...) diag_printf(fmt, ## args) | |
| 74 #else | |
| 75 # define D(fmt,args...) | |
| 76 #endif | |
| 77 | |
| 78 // ---------------------------------------------------------------------------- | |
| 79 | |
|
2299
04006a2b020d
* src/ide_disk.h: DISK_FUNS is now implicitly static.
jlarmour
parents:
1889
diff
changeset
|
80 // No h/w controller structure is needed in this driver, but the address of the |
|
04006a2b020d
* src/ide_disk.h: DISK_FUNS is now implicitly static.
jlarmour
parents:
1889
diff
changeset
|
81 // second argument is taken anyway. |
|
04006a2b020d
* src/ide_disk.h: DISK_FUNS is now implicitly static.
jlarmour
parents:
1889
diff
changeset
|
82 DISK_CONTROLLER(ide_disk_controller, ide_disk_controller); |
|
04006a2b020d
* src/ide_disk.h: DISK_FUNS is now implicitly static.
jlarmour
parents:
1889
diff
changeset
|
83 |
| 1814 | 84 #ifdef CYGVAR_DEVS_DISK_IDE_DISK0 |
| 85 IDE_DISK_INSTANCE(0, 0, 0, true, CYGDAT_IO_DISK_IDE_DISK0_NAME); | |
| 86 #endif | |
| 87 | |
| 88 #ifdef CYGVAR_DEVS_DISK_IDE_DISK1 | |
| 89 IDE_DISK_INSTANCE(1, 0, 1, true, CYGDAT_IO_DISK_IDE_DISK1_NAME); | |
| 90 #endif | |
| 91 | |
| 92 #ifdef CYGVAR_DEVS_DISK_IDE_DISK2 | |
| 93 IDE_DISK_INSTANCE(2, 1, 0, true, CYGDAT_IO_DISK_IDE_DISK2_NAME); | |
| 94 #endif | |
| 95 | |
| 96 #ifdef CYGVAR_DEVS_DISK_IDE_DISK3 | |
| 97 IDE_DISK_INSTANCE(3, 1, 1, true, CYGDAT_IO_DISK_IDE_DISK3_NAME); | |
| 98 #endif | |
| 99 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
100 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
101 |
| 1814 | 102 // ---------------------------------------------------------------------------- |
| 103 | |
| 104 static void | |
| 105 id_strcpy(char *dest, cyg_uint16 *src, cyg_uint16 size) | |
| 106 { | |
| 107 int i; | |
| 108 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
109 for (i=0; i<size; i+=2) { |
| 1814 | 110 *dest++ = (char)(*src >> 8); |
| 111 *dest++ = (char)(*src & 0x00FF); | |
| 112 src++; | |
| 113 } | |
| 114 *dest = '\0'; | |
| 115 } | |
| 116 | |
| 117 // ---------------------------------------------------------------------------- | |
| 118 | |
| 119 static inline void | |
| 120 __wait_for_ready(int ctlr) | |
| 121 { | |
| 122 cyg_uint8 status; | |
| 123 do { | |
| 124 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); | |
| 125 } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ)); | |
| 126 } | |
| 127 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
128 // ---------------------------------------------------------------------------- |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
129 // Wait while the device is busy with the last command |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
130 |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
131 static inline int |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
132 __wait_busy(int ctlr) |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
133 { |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
134 cyg_uint8 status; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
135 cyg_ucount32 tries; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
136 |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
137 for (tries=0; tries < 1000000; tries++) { |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
138 CYGACC_CALL_IF_DELAY_US(10); |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
139 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
140 if ((status & IDE_STAT_BSY) == 0) |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
141 return 1; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
142 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
143 return 0; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
144 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
145 |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
146 // ---------------------------------------------------------------------------- |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
147 |
| 1814 | 148 static inline int |
| 149 __wait_for_drq(int ctlr) | |
| 150 { | |
| 151 cyg_uint8 status; | |
| 152 cyg_ucount32 tries; | |
| 153 | |
| 154 for (tries=0; tries<1000000; tries++) { | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
155 CYGACC_CALL_IF_DELAY_US(10); |
| 1814 | 156 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); |
| 157 if (!(status & IDE_STAT_BSY)) { | |
| 158 if (status & IDE_STAT_DRQ) | |
| 159 return 1; | |
| 160 else | |
| 161 return 0; | |
| 162 } | |
| 163 } | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
164 return 0; |
| 1814 | 165 } |
| 166 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
167 // ---------------------------------------------------------------------------- |
| 1814 | 168 // Return true if any devices attached to controller |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
169 |
| 1814 | 170 static int |
| 171 ide_presence_detect(int ctlr) | |
| 172 { | |
| 173 cyg_uint8 sel, val; | |
| 174 int i; | |
| 175 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
176 for (i = 0; i < HAL_IDE_NUM_CONTROLLERS; i++) { |
| 1814 | 177 sel = (i << 4) | 0xA0; |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
178 CYGACC_CALL_IF_DELAY_US(50000U); |
| 1814 | 179 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, sel); |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
180 CYGACC_CALL_IF_DELAY_US(50000U); |
| 1814 | 181 HAL_IDE_READ_UINT8(ctlr, IDE_REG_DEVICE, val); |
| 182 if (val == sel) { | |
| 183 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE | |
| 184 if (i) | |
| 185 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, 0); | |
| 186 #endif | |
| 187 return 1; | |
| 188 } | |
| 189 } | |
| 190 return 0; | |
| 191 } | |
| 192 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
193 // ---------------------------------------------------------------------------- |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
194 |
| 1814 | 195 static int |
| 196 ide_reset(int ctlr) | |
| 197 { | |
| 198 cyg_uint8 status; | |
| 199 int delay; | |
| 200 // | |
| 201 // VMware note: | |
| 202 // VMware virtual IDE device handler obviously expects that | |
| 203 // the reset and setup functions were already done | |
| 204 // by it's bios and complains if one uses reset here... | |
| 205 // | |
| 206 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE | |
| 207 HAL_IDE_WRITE_CONTROL(ctlr, 6); // polled mode, reset asserted | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
208 CYGACC_CALL_IF_DELAY_US(5000U); |
| 1814 | 209 HAL_IDE_WRITE_CONTROL(ctlr, 2); // polled mode, reset cleared |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
210 CYGACC_CALL_IF_DELAY_US(50000U); |
| 1814 | 211 #endif |
| 212 | |
| 213 // wait 30 seconds max for not busy and drive ready | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
214 for (delay=0; delay<300; ++delay) { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
215 CYGACC_CALL_IF_DELAY_US(100000U); |
| 1814 | 216 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); |
| 217 if (!(status & IDE_STAT_BSY)) { | |
| 218 if (status & IDE_STAT_DRDY) { | |
| 219 return 1; | |
| 220 } | |
| 221 } | |
| 222 } | |
| 223 return 0; | |
| 224 } | |
| 225 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
226 // ---------------------------------------------------------------------------- |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
227 |
| 1814 | 228 static int |
| 229 ide_ident(int ctlr, int dev, cyg_uint16 *buf) | |
| 230 { | |
| 231 int i; | |
| 232 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
233 if (!__wait_busy(ctlr)) |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
234 return 0; |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
235 |
| 1814 | 236 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4); |
| 237 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEC); | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
238 CYGACC_CALL_IF_DELAY_US(50000U); |
| 1814 | 239 |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
240 if (!__wait_for_drq(ctlr)) |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
241 return 0; |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
242 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
243 for (i=0; i<(CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint16)); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
244 i++, buf++) { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
245 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf); |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
246 } |
| 1814 | 247 return 1; |
| 248 } | |
| 249 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
250 // ---------------------------------------------------------------------------- |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
251 // Requests the disk to use an 8-bit data path. This is probably ignored by |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
252 // most modern drives, but is supported by compact flash devices. |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
253 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
254 #ifdef CYGDAT_DEVS_DISK_IDE_8_BIT_DATA_PATH |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
255 static int |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
256 ide_8bit_mode(int ctlr, int dev, cyg_bool on) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
257 { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
258 cyg_uint8 stat; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
259 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
260 if (!__wait_busy(ctlr)) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
261 return 0; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
262 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
263 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
264 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_FEATURES, 0x01); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
265 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEF); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
266 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
267 if (!__wait_busy(ctlr)) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
268 return 0; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
269 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
270 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, stat); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
271 return (stat & 1) ? 0 : 1; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
272 } |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
273 #endif |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
274 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
275 // ---------------------------------------------------------------------------- |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
276 // Reads a group of contiguous sectors from the drive. |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
277 // It can read up to 256 sectors. |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
278 |
| 1814 | 279 static int |
| 280 ide_read_sector(int ctlr, int dev, cyg_uint32 start, | |
| 281 cyg_uint8 *buf, cyg_uint32 len) | |
| 282 { | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
283 int i, nword; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
284 cyg_uint8 lenb; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
285 cyg_uint16 w; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
286 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
287 if (len==0 || !__wait_busy(ctlr)) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
288 return 0; |
| 1814 | 289 |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
290 len = MIN(len, 256); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
291 lenb = (len == 256) ? 0 : ((cyg_uint8) len); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
292 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
293 nword = len * CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
294 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
295 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, lenb); |
| 1814 | 296 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); |
| 297 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); | |
| 298 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); | |
| 299 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, | |
| 300 ((start >> 24) & 0xf) | (dev << 4) | 0x40); | |
| 301 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x20); | |
| 302 | |
| 303 if (!__wait_for_drq(ctlr)) | |
| 304 return 0; | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
305 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
306 if ((int) buf & 1) { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
307 // Unaligned buffer, so split each word manually |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
308 for (i=0; i<nword; i++) { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
309 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, w); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
310 *buf++ = w & 0xff; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
311 *buf++ = (w>>8) & 0xff; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
312 } |
| 1814 | 313 } |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
314 else { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
315 cyg_uint16* wbuf = (cyg_uint16*) buf; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
316 for (i=0; i<nword; i++, wbuf++) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
317 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *wbuf); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
318 } |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
319 return (int) len; |
| 1814 | 320 } |
| 321 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
322 // ---------------------------------------------------------------------------- |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
323 // Writes a group of contiguous sectors to the drive. |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
324 // It can write up to 256 sectors. |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
325 |
| 1814 | 326 static int |
| 327 ide_write_sector(int ctlr, int dev, cyg_uint32 start, | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
328 cyg_uint8 *buf, cyg_uint32 len) |
| 1814 | 329 { |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
330 int i, nword; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
331 cyg_uint8 lenb; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
332 cyg_uint16 w; |
| 1814 | 333 |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
334 if (len==0 || !__wait_busy(ctlr)) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
335 return 0; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
336 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
337 len = MIN(len, 256); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
338 lenb = (len == 256) ? 0 : ((cyg_uint8) len); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
339 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
340 nword = len * CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
341 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
342 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, lenb); |
| 1814 | 343 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); |
| 344 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); | |
| 345 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); | |
| 346 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
347 ((start >> 24) & 0xf) | (dev << 4) | 0x40); |
| 1814 | 348 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x30); |
| 349 | |
| 350 if (!__wait_for_drq(ctlr)) | |
| 351 return 0; | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
352 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
353 if ((int) buf & 1) { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
354 // Unaligned buffer, so assemble each word manually |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
355 for (i=0; i<nword; ++i) { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
356 w = *buf++; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
357 w |= (cyg_uint16) (*buf++) << 8; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
358 HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, w); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
359 } |
| 1814 | 360 } |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
361 else { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
362 cyg_uint16* wbuf = (cyg_uint16*) buf; |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
363 for (i=0; i<nword; ++i) |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
364 HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, *wbuf++); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
365 } |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
366 return (int) len; |
| 1814 | 367 } |
| 368 | |
| 369 // ---------------------------------------------------------------------------- | |
| 370 | |
| 371 static cyg_bool | |
| 372 ide_disk_init(struct cyg_devtab_entry *tab) | |
| 373 { | |
| 374 disk_channel *chan = (disk_channel *) tab->priv; | |
| 375 ide_disk_info_t *info = (ide_disk_info_t *) chan->dev_priv; | |
| 376 cyg_uint32 id_buf[CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint32)]; | |
| 377 static int num_controllers; | |
| 378 static int ide_present[4], ide_reset_done[4]; | |
| 379 cyg_disk_identify_t ident; | |
| 380 ide_identify_data_t *ide_idData=(ide_identify_data_t*)id_buf; | |
| 381 | |
| 382 if (chan->init) | |
| 383 return true; | |
| 384 | |
| 385 D("IDE(%d:%d) hw init\n", info->port, info->chan); | |
| 386 | |
| 387 if (!num_controllers) num_controllers=HAL_IDE_INIT(); | |
| 388 if (info->chan>=num_controllers) { | |
| 389 D("No IDE controller for channel %d:%d\n", info->port, info->chan); | |
| 390 return false; | |
| 391 } | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
392 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
393 #if CYGDAT_DEVS_DISK_IDE_STARTUP_DELAY |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
394 CYGACC_CALL_IF_DELAY_US(CYGDAT_DEVS_DISK_IDE_STARTUP_DELAY*1000U); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
395 #endif |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
396 |
| 1814 | 397 if (!ide_present[info->port]) { |
| 398 ide_present[info->port]=ide_presence_detect(info->port); | |
| 399 if (!ide_present[info->port]) { | |
| 400 diag_printf("No devices on IDE controller #%d\n",info->port); | |
| 401 return false; | |
| 402 } | |
| 403 } | |
| 404 if (!ide_reset_done[info->port]) { | |
| 405 ide_reset_done[info->port]=ide_reset(info->port); | |
| 406 if (!ide_reset_done[info->port]) { | |
| 407 D("Controller #%d reset failure\n",info->port); | |
| 408 return false; | |
| 409 } | |
| 410 } | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
411 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
412 #ifdef CYGDAT_DEVS_DISK_IDE_8_BIT_DATA_PATH |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
413 if (!ide_8bit_mode(info->port, info->chan, true)) { |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
414 D("IDE disk %d:%d failed to enter 8-bit mode\n", |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
415 info->port, info->chan); |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
416 } |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
417 #endif |
| 1814 | 418 |
| 419 D("IDE %d:%d identify drive\n", info->port, info->chan); | |
| 420 | |
| 421 if (!ide_ident(info->port, info->chan, (cyg_uint16 *)id_buf)) { | |
| 422 diag_printf("IDE %d:%d ident DRQ error\n", info->port, info->chan); | |
| 423 return false; | |
| 424 } | |
| 425 | |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
426 id_strcpy(ident.serial, ide_idData->serial, 20); |
| 1814 | 427 id_strcpy(ident.firmware_rev, ide_idData->firmware_rev, 8); |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
428 id_strcpy(ident.model_num, ide_idData->model_num, 40); |
| 1814 | 429 |
| 430 ident.cylinders_num = ide_idData->num_cylinders; | |
| 431 ident.heads_num = ide_idData->num_heads; | |
| 432 ident.sectors_num = ide_idData->num_sectors; | |
| 433 ident.lba_sectors_num = ide_idData->lba_total_sectors[1] << 16 | | |
| 434 ide_idData->lba_total_sectors[0]; | |
|
2299
04006a2b020d
* src/ide_disk.h: DISK_FUNS is now implicitly static.
jlarmour
parents:
1889
diff
changeset
|
435 ident.phys_block_size = 1; |
|
2535
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
436 |
|
6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
asl
parents:
2318
diff
changeset
|
437 // TODO: Should this be CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE? |
|
2299
04006a2b020d
* src/ide_disk.h: DISK_FUNS is now implicitly static.
jlarmour
parents:
1889
diff
changeset
|
438 ident.max_transfer = 512; |
| 1814 | 439 |
| 440 D("\tSerial : %s\n", ident.serial); | |
| 441 D("\tFirmware rev. : %s\n", ident.firmware_rev); | |
| 442 D("\tModel : %s\n", ident.model_num); | |
| 443 D("\tC/H/S : %d/%d/%d\n", ident.cylinders_num, | |
| 444 ident.heads_num, ident.sectors_num); | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
445 |
| 1814 | 446 if (!(chan->callbacks->disk_init)(tab)) |
| 447 return false; | |
| 448 | |
| 449 if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident)) | |
| 450 return false; | |
| 451 | |
| 452 return true; | |
| 453 } | |
| 454 | |
| 455 // ---------------------------------------------------------------------------- | |
| 456 | |
| 457 static Cyg_ErrNo | |
| 458 ide_disk_lookup(struct cyg_devtab_entry **tab, | |
| 459 struct cyg_devtab_entry *sub_tab, | |
| 460 const char *name) | |
| 461 { | |
| 462 disk_channel *chan = (disk_channel *) (*tab)->priv; | |
| 463 return (chan->callbacks->disk_lookup)(tab, sub_tab, name); | |
| 464 } | |
| 465 | |
| 466 // ---------------------------------------------------------------------------- | |
| 467 | |
| 468 static Cyg_ErrNo | |
| 469 ide_disk_read(disk_channel *chan, | |
| 470 void *buf, | |
| 471 cyg_uint32 len, | |
| 472 cyg_uint32 block_num) | |
| 473 { | |
| 474 ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv; | |
| 475 | |
| 476 D("IDE %d:%d read block %d\n", info->port, info->chan, block_num); | |
| 477 | |
| 478 if (!ide_read_sector(info->port, info->chan, block_num, | |
| 479 (cyg_uint8 *)buf, len)) { | |
| 480 diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan); | |
| 481 return -EIO; | |
| 482 } | |
| 483 | |
| 484 return ENOERR; | |
| 485 } | |
| 486 | |
| 487 // ---------------------------------------------------------------------------- | |
| 488 | |
| 489 static Cyg_ErrNo | |
| 490 ide_disk_write(disk_channel *chan, | |
| 491 const void *buf, | |
| 492 cyg_uint32 len, | |
| 493 cyg_uint32 block_num) | |
| 494 { | |
| 495 ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv; | |
| 496 | |
| 497 D("IDE %d:%d write block %d\n", info->port, info->chan, block_num); | |
| 498 | |
| 499 if (!ide_write_sector(info->port, info->chan, block_num, | |
| 500 (cyg_uint8 *)buf, len)) { | |
| 501 diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan); | |
| 502 return -EIO; | |
| 503 } | |
| 504 | |
| 505 return ENOERR; | |
| 506 } | |
| 507 | |
| 508 // ---------------------------------------------------------------------------- | |
| 509 | |
| 510 static Cyg_ErrNo | |
| 511 ide_disk_get_config(disk_channel *chan, | |
| 512 cyg_uint32 key, | |
| 513 const void *xbuf, | |
| 514 cyg_uint32 *len) | |
| 515 { | |
| 516 return -EINVAL; | |
| 517 } | |
| 518 | |
| 519 // ---------------------------------------------------------------------------- | |
| 520 | |
| 521 static Cyg_ErrNo | |
| 522 ide_disk_set_config(disk_channel *chan, | |
| 523 cyg_uint32 key, | |
| 524 const void *xbuf, | |
| 525 cyg_uint32 *len) | |
| 526 { | |
| 527 return -EINVAL; | |
| 528 } | |
| 529 | |
| 530 //EOF ide_disk.c |
