Mercurial > ecos
annotate packages/devs/disk/ide/current/src/ide_disk.c @ 1889:a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
command to the device.
| author | asl |
|---|---|
| date | Tue, 08 Feb 2005 10:08:00 +0000 |
| parents | 728b82c53914 |
| children | 04006a2b020d |
| rev | line source |
|---|---|
| 1814 | 1 //========================================================================== |
| 2 // | |
| 3 // ide_disk.c | |
| 4 // | |
| 5 // IDE polled mode disk driver | |
| 6 // | |
| 7 //========================================================================== | |
| 8 //####ECOSGPLCOPYRIGHTBEGIN#### | |
| 9 // ------------------------------------------- | |
| 10 // This file is part of eCos, the Embedded Configurable Operating System. | |
| 11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc. | |
| 12 // Copyright (C) 2004 eCosCentric, Ltd. | |
| 13 // | |
| 14 // eCos is free software; you can redistribute it and/or modify it under | |
| 15 // the terms of the GNU General Public License as published by the Free | |
| 16 // Software Foundation; either version 2 or (at your option) any later version. | |
| 17 // | |
| 18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 21 // for more details. | |
| 22 // | |
| 23 // You should have received a copy of the GNU General Public License along | |
| 24 // with eCos; if not, write to the Free Software Foundation, Inc., | |
| 25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
| 26 // | |
| 27 // As a special exception, if other files instantiate templates or use macros | |
| 28 // or inline functions from this file, or you compile this file and link it | |
| 29 // with other works to produce a work based on this file, this file does not | |
| 30 // by itself cause the resulting work to be covered by the GNU General Public | |
| 31 // License. However the source code for this file must still be made available | |
| 32 // in accordance with section (3) of the GNU General Public License. | |
| 33 // | |
| 34 // This exception does not invalidate any other reasons why a work based on | |
| 35 // this file might be covered by the GNU General Public License. | |
| 36 // | |
| 37 // ------------------------------------------- | |
| 38 //####ECOSGPLCOPYRIGHTEND#### | |
| 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> | |
| 51 | |
| 52 #include <cyg/infra/cyg_type.h> | |
| 53 #include <cyg/infra/cyg_ass.h> | |
| 54 #include <cyg/infra/diag.h> | |
| 55 #include <cyg/hal/hal_arch.h> | |
| 56 #include <cyg/hal/hal_io.h> | |
| 57 #include <cyg/hal/hal_if.h> // delays | |
| 58 #include <cyg/hal/drv_api.h> | |
| 59 #include <cyg/io/io.h> | |
| 60 #include <cyg/io/devtab.h> | |
| 61 #include <cyg/io/disk.h> | |
| 62 | |
| 63 #include "ide_disk.h" | |
| 64 | |
| 65 // ---------------------------------------------------------------------------- | |
| 66 | |
| 67 //#define DEBUG 1 | |
| 68 | |
| 69 #ifdef DEBUG | |
| 70 # define D(fmt,args...) diag_printf(fmt, ## args) | |
| 71 #else | |
| 72 # define D(fmt,args...) | |
| 73 #endif | |
| 74 | |
| 75 // ---------------------------------------------------------------------------- | |
| 76 | |
| 77 #ifdef CYGVAR_DEVS_DISK_IDE_DISK0 | |
| 78 IDE_DISK_INSTANCE(0, 0, 0, true, CYGDAT_IO_DISK_IDE_DISK0_NAME); | |
| 79 #endif | |
| 80 | |
| 81 #ifdef CYGVAR_DEVS_DISK_IDE_DISK1 | |
| 82 IDE_DISK_INSTANCE(1, 0, 1, true, CYGDAT_IO_DISK_IDE_DISK1_NAME); | |
| 83 #endif | |
| 84 | |
| 85 #ifdef CYGVAR_DEVS_DISK_IDE_DISK2 | |
| 86 IDE_DISK_INSTANCE(2, 1, 0, true, CYGDAT_IO_DISK_IDE_DISK2_NAME); | |
| 87 #endif | |
| 88 | |
| 89 #ifdef CYGVAR_DEVS_DISK_IDE_DISK3 | |
| 90 IDE_DISK_INSTANCE(3, 1, 1, true, CYGDAT_IO_DISK_IDE_DISK3_NAME); | |
| 91 #endif | |
| 92 | |
| 93 // ---------------------------------------------------------------------------- | |
| 94 | |
| 95 static void | |
| 96 id_strcpy(char *dest, cyg_uint16 *src, cyg_uint16 size) | |
| 97 { | |
| 98 int i; | |
| 99 | |
| 100 for (i = 0; i < size; i+=2) | |
| 101 { | |
| 102 *dest++ = (char)(*src >> 8); | |
| 103 *dest++ = (char)(*src & 0x00FF); | |
| 104 src++; | |
| 105 } | |
| 106 *dest = '\0'; | |
| 107 } | |
| 108 | |
| 109 // ---------------------------------------------------------------------------- | |
| 110 | |
| 111 static inline void | |
| 112 __wait_for_ready(int ctlr) | |
| 113 { | |
| 114 cyg_uint8 status; | |
| 115 do { | |
| 116 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); | |
| 117 } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ)); | |
| 118 } | |
| 119 | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
120 // Wait while the device is busy with the last command |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
121 static inline int |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
122 __wait_busy(int ctlr) |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
123 { |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
124 cyg_uint8 status; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
125 cyg_ucount32 tries; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
126 |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
127 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
|
128 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
|
129 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
|
130 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
|
131 return 1; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
132 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
133 return 0; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
134 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
135 |
| 1814 | 136 static inline int |
| 137 __wait_for_drq(int ctlr) | |
| 138 { | |
| 139 cyg_uint8 status; | |
| 140 cyg_ucount32 tries; | |
| 141 | |
| 142 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
|
143 CYGACC_CALL_IF_DELAY_US(10); |
| 1814 | 144 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); |
| 145 if (!(status & IDE_STAT_BSY)) { | |
| 146 if (status & IDE_STAT_DRQ) | |
| 147 return 1; | |
| 148 else | |
| 149 return 0; | |
| 150 } | |
| 151 } | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
152 return 0; |
| 1814 | 153 } |
| 154 | |
| 155 // Return true if any devices attached to controller | |
| 156 static int | |
| 157 ide_presence_detect(int ctlr) | |
| 158 { | |
| 159 cyg_uint8 sel, val; | |
| 160 int i; | |
| 161 | |
| 162 for (i = 0; i < 2; i++) { | |
| 163 sel = (i << 4) | 0xA0; | |
| 164 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | |
| 165 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, sel); | |
| 166 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | |
| 167 HAL_IDE_READ_UINT8(ctlr, IDE_REG_DEVICE, val); | |
| 168 if (val == sel) { | |
| 169 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE | |
| 170 if (i) | |
| 171 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, 0); | |
| 172 #endif | |
| 173 return 1; | |
| 174 } | |
| 175 } | |
| 176 return 0; | |
| 177 } | |
| 178 | |
| 179 static int | |
| 180 ide_reset(int ctlr) | |
| 181 { | |
| 182 cyg_uint8 status; | |
| 183 int delay; | |
| 184 // | |
| 185 // VMware note: | |
| 186 // VMware virtual IDE device handler obviously expects that | |
| 187 // the reset and setup functions were already done | |
| 188 // by it's bios and complains if one uses reset here... | |
| 189 // | |
| 190 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE | |
| 191 HAL_IDE_WRITE_CONTROL(ctlr, 6); // polled mode, reset asserted | |
| 192 CYGACC_CALL_IF_DELAY_US(5000); | |
| 193 HAL_IDE_WRITE_CONTROL(ctlr, 2); // polled mode, reset cleared | |
| 194 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | |
| 195 #endif | |
| 196 | |
| 197 // wait 30 seconds max for not busy and drive ready | |
| 198 for (delay = 0; delay < 300; ++delay) { | |
| 199 CYGACC_CALL_IF_DELAY_US((cyg_uint32)100000); | |
| 200 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); | |
| 201 if (!(status & IDE_STAT_BSY)) { | |
| 202 if (status & IDE_STAT_DRDY) { | |
| 203 return 1; | |
| 204 } | |
| 205 } | |
| 206 } | |
| 207 return 0; | |
| 208 } | |
| 209 | |
| 210 static int | |
| 211 ide_ident(int ctlr, int dev, cyg_uint16 *buf) | |
| 212 { | |
| 213 int i; | |
| 214 | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
215 if (!__wait_busy(ctlr)) { |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
216 return 0; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
217 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
218 |
| 1814 | 219 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4); |
| 220 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEC); | |
| 221 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | |
| 222 | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
223 if (!__wait_for_drq(ctlr)) { |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
224 return 0; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
225 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
226 |
| 1814 | 227 for (i = 0; i < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); |
| 228 i++, buf++) | |
| 229 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf); | |
| 230 | |
| 231 return 1; | |
| 232 } | |
| 233 | |
| 234 static int | |
| 235 ide_read_sector(int ctlr, int dev, cyg_uint32 start, | |
| 236 cyg_uint8 *buf, cyg_uint32 len) | |
| 237 { | |
| 238 int j, c; | |
| 239 cyg_uint16 p; | |
| 240 cyg_uint8 * b=buf; | |
| 241 | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
242 if(!__wait_busy(ctlr)) { |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
243 return 0; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
244 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
245 |
| 1814 | 246 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 1); // count =1 |
| 247 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); | |
| 248 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); | |
| 249 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); | |
| 250 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, | |
| 251 ((start >> 24) & 0xf) | (dev << 4) | 0x40); | |
| 252 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x20); | |
| 253 | |
| 254 if (!__wait_for_drq(ctlr)) | |
| 255 return 0; | |
| 256 // | |
| 257 // It would be fine if all buffers were word aligned, | |
| 258 // but who knows | |
| 259 // | |
| 260 for (j = 0, c=0 ; j < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); | |
| 261 j++) { | |
| 262 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, p); | |
| 263 if (c++<len) *b++=p&0xff; | |
| 264 if (c++<len) *b++=(p>>8)&0xff; | |
| 265 } | |
| 266 return 1; | |
| 267 } | |
| 268 | |
| 269 static int | |
| 270 ide_write_sector(int ctlr, int dev, cyg_uint32 start, | |
| 271 cyg_uint8 *buf, cyg_uint32 len) | |
| 272 { | |
| 273 int j, c; | |
| 274 cyg_uint16 p; | |
| 275 cyg_uint8 * b=buf; | |
| 276 | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
277 if(!__wait_busy(ctlr)) { |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
278 return 0; |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
279 } |
|
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
280 |
| 1814 | 281 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 1); // count =1 |
| 282 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); | |
| 283 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); | |
| 284 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); | |
| 285 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, | |
| 286 ((start >> 24) & 0xf) | (dev << 4) | 0x40); | |
| 287 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x30); | |
| 288 | |
| 289 if (!__wait_for_drq(ctlr)) | |
| 290 return 0; | |
| 291 // | |
| 292 // It would be fine if all buffers were word aligned, | |
| 293 // but who knows | |
| 294 // | |
| 295 for (j = 0, c=0 ; j < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); | |
| 296 j++) { | |
| 297 p = (c++<len) ? *b++ : 0; | |
| 298 p |= (c++<len) ? (*b++<<8) : 0; | |
| 299 HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, p); | |
| 300 } | |
| 301 return 1; | |
| 302 } | |
| 303 | |
| 304 // ---------------------------------------------------------------------------- | |
| 305 | |
| 306 static cyg_bool | |
| 307 ide_disk_init(struct cyg_devtab_entry *tab) | |
| 308 { | |
| 309 disk_channel *chan = (disk_channel *) tab->priv; | |
| 310 ide_disk_info_t *info = (ide_disk_info_t *) chan->dev_priv; | |
| 311 cyg_uint32 id_buf[CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint32)]; | |
| 312 static int num_controllers; | |
| 313 static int ide_present[4], ide_reset_done[4]; | |
| 314 cyg_disk_identify_t ident; | |
| 315 ide_identify_data_t *ide_idData=(ide_identify_data_t*)id_buf; | |
| 316 | |
| 317 if (chan->init) | |
| 318 return true; | |
| 319 | |
| 320 D("IDE(%d:%d) hw init\n", info->port, info->chan); | |
| 321 | |
| 322 if (!num_controllers) num_controllers=HAL_IDE_INIT(); | |
| 323 if (info->chan>=num_controllers) { | |
| 324 D("No IDE controller for channel %d:%d\n", info->port, info->chan); | |
| 325 return false; | |
| 326 } | |
| 327 if (!ide_present[info->port]) { | |
| 328 ide_present[info->port]=ide_presence_detect(info->port); | |
| 329 if (!ide_present[info->port]) { | |
| 330 diag_printf("No devices on IDE controller #%d\n",info->port); | |
| 331 return false; | |
| 332 } | |
| 333 } | |
| 334 if (!ide_reset_done[info->port]) { | |
| 335 ide_reset_done[info->port]=ide_reset(info->port); | |
| 336 if (!ide_reset_done[info->port]) { | |
| 337 D("Controller #%d reset failure\n",info->port); | |
| 338 return false; | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 D("IDE %d:%d identify drive\n", info->port, info->chan); | |
| 343 | |
| 344 if (!ide_ident(info->port, info->chan, (cyg_uint16 *)id_buf)) { | |
| 345 diag_printf("IDE %d:%d ident DRQ error\n", info->port, info->chan); | |
| 346 return false; | |
| 347 } | |
| 348 | |
| 349 id_strcpy(ident.serial, ide_idData->serial, 20); | |
| 350 id_strcpy(ident.firmware_rev, ide_idData->firmware_rev, 8); | |
| 351 id_strcpy(ident.model_num, ide_idData->model_num, 40); | |
| 352 | |
| 353 ident.cylinders_num = ide_idData->num_cylinders; | |
| 354 ident.heads_num = ide_idData->num_heads; | |
| 355 ident.sectors_num = ide_idData->num_sectors; | |
| 356 ident.lba_sectors_num = ide_idData->lba_total_sectors[1] << 16 | | |
| 357 ide_idData->lba_total_sectors[0]; | |
| 358 | |
| 359 D("\tSerial : %s\n", ident.serial); | |
| 360 D("\tFirmware rev. : %s\n", ident.firmware_rev); | |
| 361 D("\tModel : %s\n", ident.model_num); | |
| 362 D("\tC/H/S : %d/%d/%d\n", ident.cylinders_num, | |
| 363 ident.heads_num, ident.sectors_num); | |
| 364 D("\tKind : %x\n", (ide_idData->general_conf>>8)&0x1f); | |
|
1889
a06d718514f8
* src/ide_disk.c: Check the device is not busy before sending a
asl
parents:
1814
diff
changeset
|
365 |
| 1814 | 366 if (((ide_idData->general_conf>>8)&0x1f)!=2) { |
| 367 diag_printf("IDE device %d:%d is not a hard disk!\n", | |
| 368 info->port, info->chan); | |
| 369 return false; | |
| 370 } | |
| 371 if (!(chan->callbacks->disk_init)(tab)) | |
| 372 return false; | |
| 373 | |
| 374 if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident)) | |
| 375 return false; | |
| 376 | |
| 377 return true; | |
| 378 } | |
| 379 | |
| 380 // ---------------------------------------------------------------------------- | |
| 381 | |
| 382 static Cyg_ErrNo | |
| 383 ide_disk_lookup(struct cyg_devtab_entry **tab, | |
| 384 struct cyg_devtab_entry *sub_tab, | |
| 385 const char *name) | |
| 386 { | |
| 387 disk_channel *chan = (disk_channel *) (*tab)->priv; | |
| 388 return (chan->callbacks->disk_lookup)(tab, sub_tab, name); | |
| 389 } | |
| 390 | |
| 391 // ---------------------------------------------------------------------------- | |
| 392 | |
| 393 static Cyg_ErrNo | |
| 394 ide_disk_read(disk_channel *chan, | |
| 395 void *buf, | |
| 396 cyg_uint32 len, | |
| 397 cyg_uint32 block_num) | |
| 398 { | |
| 399 ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv; | |
| 400 | |
| 401 D("IDE %d:%d read block %d\n", info->port, info->chan, block_num); | |
| 402 | |
| 403 if (!ide_read_sector(info->port, info->chan, block_num, | |
| 404 (cyg_uint8 *)buf, len)) { | |
| 405 diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan); | |
| 406 return -EIO; | |
| 407 } | |
| 408 | |
| 409 return ENOERR; | |
| 410 } | |
| 411 | |
| 412 // ---------------------------------------------------------------------------- | |
| 413 | |
| 414 static Cyg_ErrNo | |
| 415 ide_disk_write(disk_channel *chan, | |
| 416 const void *buf, | |
| 417 cyg_uint32 len, | |
| 418 cyg_uint32 block_num) | |
| 419 { | |
| 420 ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv; | |
| 421 | |
| 422 D("IDE %d:%d write block %d\n", info->port, info->chan, block_num); | |
| 423 | |
| 424 if (!ide_write_sector(info->port, info->chan, block_num, | |
| 425 (cyg_uint8 *)buf, len)) { | |
| 426 diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan); | |
| 427 return -EIO; | |
| 428 } | |
| 429 | |
| 430 return ENOERR; | |
| 431 } | |
| 432 | |
| 433 // ---------------------------------------------------------------------------- | |
| 434 | |
| 435 static Cyg_ErrNo | |
| 436 ide_disk_get_config(disk_channel *chan, | |
| 437 cyg_uint32 key, | |
| 438 const void *xbuf, | |
| 439 cyg_uint32 *len) | |
| 440 { | |
| 441 return -EINVAL; | |
| 442 } | |
| 443 | |
| 444 // ---------------------------------------------------------------------------- | |
| 445 | |
| 446 static Cyg_ErrNo | |
| 447 ide_disk_set_config(disk_channel *chan, | |
| 448 cyg_uint32 key, | |
| 449 const void *xbuf, | |
| 450 cyg_uint32 *len) | |
| 451 { | |
| 452 return -EINVAL; | |
| 453 } | |
| 454 | |
| 455 //EOF ide_disk.c |
