Mercurial > ecos
comparison packages/devs/disk/ide/current/src/ide_disk.c @ 2535:6ffeb2616b4b
* cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
so that all disk drivers have unique device names.
* cdl/ide_disk.cdl:
* src/ide_diskc: Add a configurable startup delay to allow slow
disks to initialize. Add support for 8-bit data path. Remove the
identity check which are retired in the ATA standard. Optimize the
read/write functions.
| author | asl |
|---|---|
| date | Sun, 24 Aug 2008 12:55:41 +0000 |
| parents | 6d4c075d2939 |
| children | 74dbf4c3f2e1 |
comparison
equal
deleted
inserted
replaced
| 2534:41a4df71f380 | 2535:6ffeb2616b4b |
|---|---|
| 46 //####DESCRIPTIONEND#### | 46 //####DESCRIPTIONEND#### |
| 47 // | 47 // |
| 48 //========================================================================== | 48 //========================================================================== |
| 49 | 49 |
| 50 #include <pkgconf/devs_disk_ide.h> | 50 #include <pkgconf/devs_disk_ide.h> |
| 51 #include <pkgconf/io_disk.h> | |
| 51 | 52 |
| 52 #include <cyg/infra/cyg_type.h> | 53 #include <cyg/infra/cyg_type.h> |
| 53 #include <cyg/infra/cyg_ass.h> | 54 #include <cyg/infra/cyg_ass.h> |
| 54 #include <cyg/infra/diag.h> | 55 #include <cyg/infra/diag.h> |
| 55 #include <cyg/hal/hal_arch.h> | 56 #include <cyg/hal/hal_arch.h> |
| 62 | 63 |
| 63 #include "ide_disk.h" | 64 #include "ide_disk.h" |
| 64 | 65 |
| 65 // ---------------------------------------------------------------------------- | 66 // ---------------------------------------------------------------------------- |
| 66 | 67 |
| 67 //#define DEBUG 1 | 68 #ifdef CYGDBG_IO_DISK_DEBUG |
| 69 # define DEBUG 1 | |
| 70 #endif | |
| 68 | 71 |
| 69 #ifdef DEBUG | 72 #ifdef DEBUG |
| 70 # define D(fmt,args...) diag_printf(fmt, ## args) | 73 # define D(fmt,args...) diag_printf(fmt, ## args) |
| 71 #else | 74 #else |
| 72 # define D(fmt,args...) | 75 # define D(fmt,args...) |
| 92 | 95 |
| 93 #ifdef CYGVAR_DEVS_DISK_IDE_DISK3 | 96 #ifdef CYGVAR_DEVS_DISK_IDE_DISK3 |
| 94 IDE_DISK_INSTANCE(3, 1, 1, true, CYGDAT_IO_DISK_IDE_DISK3_NAME); | 97 IDE_DISK_INSTANCE(3, 1, 1, true, CYGDAT_IO_DISK_IDE_DISK3_NAME); |
| 95 #endif | 98 #endif |
| 96 | 99 |
| 100 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | |
| 101 | |
| 97 // ---------------------------------------------------------------------------- | 102 // ---------------------------------------------------------------------------- |
| 98 | 103 |
| 99 static void | 104 static void |
| 100 id_strcpy(char *dest, cyg_uint16 *src, cyg_uint16 size) | 105 id_strcpy(char *dest, cyg_uint16 *src, cyg_uint16 size) |
| 101 { | 106 { |
| 102 int i; | 107 int i; |
| 103 | 108 |
| 104 for (i = 0; i < size; i+=2) | 109 for (i=0; i<size; i+=2) { |
| 105 { | |
| 106 *dest++ = (char)(*src >> 8); | 110 *dest++ = (char)(*src >> 8); |
| 107 *dest++ = (char)(*src & 0x00FF); | 111 *dest++ = (char)(*src & 0x00FF); |
| 108 src++; | 112 src++; |
| 109 } | 113 } |
| 110 *dest = '\0'; | 114 *dest = '\0'; |
| 119 do { | 123 do { |
| 120 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); | 124 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); |
| 121 } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ)); | 125 } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ)); |
| 122 } | 126 } |
| 123 | 127 |
| 128 // ---------------------------------------------------------------------------- | |
| 124 // Wait while the device is busy with the last command | 129 // Wait while the device is busy with the last command |
| 130 | |
| 125 static inline int | 131 static inline int |
| 126 __wait_busy(int ctlr) | 132 __wait_busy(int ctlr) |
| 127 { | 133 { |
| 128 cyg_uint8 status; | 134 cyg_uint8 status; |
| 129 cyg_ucount32 tries; | 135 cyg_ucount32 tries; |
| 134 if ((status & IDE_STAT_BSY) == 0) | 140 if ((status & IDE_STAT_BSY) == 0) |
| 135 return 1; | 141 return 1; |
| 136 } | 142 } |
| 137 return 0; | 143 return 0; |
| 138 } | 144 } |
| 145 | |
| 146 // ---------------------------------------------------------------------------- | |
| 139 | 147 |
| 140 static inline int | 148 static inline int |
| 141 __wait_for_drq(int ctlr) | 149 __wait_for_drq(int ctlr) |
| 142 { | 150 { |
| 143 cyg_uint8 status; | 151 cyg_uint8 status; |
| 154 } | 162 } |
| 155 } | 163 } |
| 156 return 0; | 164 return 0; |
| 157 } | 165 } |
| 158 | 166 |
| 167 // ---------------------------------------------------------------------------- | |
| 159 // Return true if any devices attached to controller | 168 // Return true if any devices attached to controller |
| 169 | |
| 160 static int | 170 static int |
| 161 ide_presence_detect(int ctlr) | 171 ide_presence_detect(int ctlr) |
| 162 { | 172 { |
| 163 cyg_uint8 sel, val; | 173 cyg_uint8 sel, val; |
| 164 int i; | 174 int i; |
| 165 | 175 |
| 166 for (i = 0; i < 2; i++) { | 176 for (i = 0; i < HAL_IDE_NUM_CONTROLLERS; i++) { |
| 167 sel = (i << 4) | 0xA0; | 177 sel = (i << 4) | 0xA0; |
| 168 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | 178 CYGACC_CALL_IF_DELAY_US(50000U); |
| 169 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, sel); | 179 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, sel); |
| 170 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | 180 CYGACC_CALL_IF_DELAY_US(50000U); |
| 171 HAL_IDE_READ_UINT8(ctlr, IDE_REG_DEVICE, val); | 181 HAL_IDE_READ_UINT8(ctlr, IDE_REG_DEVICE, val); |
| 172 if (val == sel) { | 182 if (val == sel) { |
| 173 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE | 183 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE |
| 174 if (i) | 184 if (i) |
| 175 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, 0); | 185 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, 0); |
| 178 } | 188 } |
| 179 } | 189 } |
| 180 return 0; | 190 return 0; |
| 181 } | 191 } |
| 182 | 192 |
| 193 // ---------------------------------------------------------------------------- | |
| 194 | |
| 183 static int | 195 static int |
| 184 ide_reset(int ctlr) | 196 ide_reset(int ctlr) |
| 185 { | 197 { |
| 186 cyg_uint8 status; | 198 cyg_uint8 status; |
| 187 int delay; | 199 int delay; |
| 191 // the reset and setup functions were already done | 203 // the reset and setup functions were already done |
| 192 // by it's bios and complains if one uses reset here... | 204 // by it's bios and complains if one uses reset here... |
| 193 // | 205 // |
| 194 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE | 206 #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE |
| 195 HAL_IDE_WRITE_CONTROL(ctlr, 6); // polled mode, reset asserted | 207 HAL_IDE_WRITE_CONTROL(ctlr, 6); // polled mode, reset asserted |
| 196 CYGACC_CALL_IF_DELAY_US(5000); | 208 CYGACC_CALL_IF_DELAY_US(5000U); |
| 197 HAL_IDE_WRITE_CONTROL(ctlr, 2); // polled mode, reset cleared | 209 HAL_IDE_WRITE_CONTROL(ctlr, 2); // polled mode, reset cleared |
| 198 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | 210 CYGACC_CALL_IF_DELAY_US(50000U); |
| 199 #endif | 211 #endif |
| 200 | 212 |
| 201 // wait 30 seconds max for not busy and drive ready | 213 // wait 30 seconds max for not busy and drive ready |
| 202 for (delay = 0; delay < 300; ++delay) { | 214 for (delay=0; delay<300; ++delay) { |
| 203 CYGACC_CALL_IF_DELAY_US((cyg_uint32)100000); | 215 CYGACC_CALL_IF_DELAY_US(100000U); |
| 204 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); | 216 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); |
| 205 if (!(status & IDE_STAT_BSY)) { | 217 if (!(status & IDE_STAT_BSY)) { |
| 206 if (status & IDE_STAT_DRDY) { | 218 if (status & IDE_STAT_DRDY) { |
| 207 return 1; | 219 return 1; |
| 208 } | 220 } |
| 209 } | 221 } |
| 210 } | 222 } |
| 211 return 0; | 223 return 0; |
| 212 } | 224 } |
| 213 | 225 |
| 226 // ---------------------------------------------------------------------------- | |
| 227 | |
| 214 static int | 228 static int |
| 215 ide_ident(int ctlr, int dev, cyg_uint16 *buf) | 229 ide_ident(int ctlr, int dev, cyg_uint16 *buf) |
| 216 { | 230 { |
| 217 int i; | 231 int i; |
| 218 | 232 |
| 219 if (!__wait_busy(ctlr)) { | 233 if (!__wait_busy(ctlr)) |
| 220 return 0; | 234 return 0; |
| 221 } | 235 |
| 222 | |
| 223 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4); | 236 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4); |
| 224 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEC); | 237 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEC); |
| 225 CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); | 238 CYGACC_CALL_IF_DELAY_US(50000U); |
| 226 | 239 |
| 227 if (!__wait_for_drq(ctlr)) { | 240 if (!__wait_for_drq(ctlr)) |
| 228 return 0; | 241 return 0; |
| 229 } | 242 |
| 230 | 243 for (i=0; i<(CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint16)); |
| 231 for (i = 0; i < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); | 244 i++, buf++) { |
| 232 i++, buf++) | 245 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf); |
| 233 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf); | 246 } |
| 234 | |
| 235 return 1; | 247 return 1; |
| 236 } | 248 } |
| 249 | |
| 250 // ---------------------------------------------------------------------------- | |
| 251 // Requests the disk to use an 8-bit data path. This is probably ignored by | |
| 252 // most modern drives, but is supported by compact flash devices. | |
| 253 | |
| 254 #ifdef CYGDAT_DEVS_DISK_IDE_8_BIT_DATA_PATH | |
| 255 static int | |
| 256 ide_8bit_mode(int ctlr, int dev, cyg_bool on) | |
| 257 { | |
| 258 cyg_uint8 stat; | |
| 259 | |
| 260 if (!__wait_busy(ctlr)) | |
| 261 return 0; | |
| 262 | |
| 263 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4); | |
| 264 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_FEATURES, 0x01); | |
| 265 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEF); | |
| 266 | |
| 267 if (!__wait_busy(ctlr)) | |
| 268 return 0; | |
| 269 | |
| 270 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, stat); | |
| 271 return (stat & 1) ? 0 : 1; | |
| 272 } | |
| 273 #endif | |
| 274 | |
| 275 // ---------------------------------------------------------------------------- | |
| 276 // Reads a group of contiguous sectors from the drive. | |
| 277 // It can read up to 256 sectors. | |
| 237 | 278 |
| 238 static int | 279 static int |
| 239 ide_read_sector(int ctlr, int dev, cyg_uint32 start, | 280 ide_read_sector(int ctlr, int dev, cyg_uint32 start, |
| 240 cyg_uint8 *buf, cyg_uint32 len) | 281 cyg_uint8 *buf, cyg_uint32 len) |
| 241 { | 282 { |
| 242 int j, c; | 283 int i, nword; |
| 243 cyg_uint16 p; | 284 cyg_uint8 lenb; |
| 244 cyg_uint8 * b=buf; | 285 cyg_uint16 w; |
| 245 | 286 |
| 246 if(!__wait_busy(ctlr)) { | 287 if (len==0 || !__wait_busy(ctlr)) |
| 247 return 0; | 288 return 0; |
| 248 } | 289 |
| 249 | 290 len = MIN(len, 256); |
| 250 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 1); // count =1 | 291 lenb = (len == 256) ? 0 : ((cyg_uint8) len); |
| 292 | |
| 293 nword = len * CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16); | |
| 294 | |
| 295 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, lenb); | |
| 251 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); | 296 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); |
| 252 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); | 297 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); |
| 253 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); | 298 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); |
| 254 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, | 299 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, |
| 255 ((start >> 24) & 0xf) | (dev << 4) | 0x40); | 300 ((start >> 24) & 0xf) | (dev << 4) | 0x40); |
| 256 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x20); | 301 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x20); |
| 257 | 302 |
| 258 if (!__wait_for_drq(ctlr)) | 303 if (!__wait_for_drq(ctlr)) |
| 259 return 0; | 304 return 0; |
| 260 // | 305 |
| 261 // It would be fine if all buffers were word aligned, | 306 if ((int) buf & 1) { |
| 262 // but who knows | 307 // Unaligned buffer, so split each word manually |
| 263 // | 308 for (i=0; i<nword; i++) { |
| 264 for (j = 0, c=0 ; j < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); | 309 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, w); |
| 265 j++) { | 310 *buf++ = w & 0xff; |
| 266 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, p); | 311 *buf++ = (w>>8) & 0xff; |
| 267 if (c++<(len*512)) *b++=p&0xff; | 312 } |
| 268 if (c++<(len*512)) *b++=(p>>8)&0xff; | 313 } |
| 269 } | 314 else { |
| 270 return 1; | 315 cyg_uint16* wbuf = (cyg_uint16*) buf; |
| 271 } | 316 for (i=0; i<nword; i++, wbuf++) |
| 317 HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *wbuf); | |
| 318 } | |
| 319 return (int) len; | |
| 320 } | |
| 321 | |
| 322 // ---------------------------------------------------------------------------- | |
| 323 // Writes a group of contiguous sectors to the drive. | |
| 324 // It can write up to 256 sectors. | |
| 272 | 325 |
| 273 static int | 326 static int |
| 274 ide_write_sector(int ctlr, int dev, cyg_uint32 start, | 327 ide_write_sector(int ctlr, int dev, cyg_uint32 start, |
| 275 cyg_uint8 *buf, cyg_uint32 len) | 328 cyg_uint8 *buf, cyg_uint32 len) |
| 276 { | 329 { |
| 277 int j, c; | 330 int i, nword; |
| 278 cyg_uint16 p; | 331 cyg_uint8 lenb; |
| 279 cyg_uint8 * b=buf; | 332 cyg_uint16 w; |
| 280 | 333 |
| 281 if(!__wait_busy(ctlr)) { | 334 if (len==0 || !__wait_busy(ctlr)) |
| 282 return 0; | 335 return 0; |
| 283 } | 336 |
| 284 | 337 len = MIN(len, 256); |
| 285 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 1); // count =1 | 338 lenb = (len == 256) ? 0 : ((cyg_uint8) len); |
| 339 | |
| 340 nword = len * CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16); | |
| 341 | |
| 342 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, lenb); | |
| 286 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); | 343 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); |
| 287 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); | 344 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); |
| 288 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); | 345 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); |
| 289 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, | 346 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, |
| 290 ((start >> 24) & 0xf) | (dev << 4) | 0x40); | 347 ((start >> 24) & 0xf) | (dev << 4) | 0x40); |
| 291 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x30); | 348 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x30); |
| 292 | 349 |
| 293 if (!__wait_for_drq(ctlr)) | 350 if (!__wait_for_drq(ctlr)) |
| 294 return 0; | 351 return 0; |
| 295 // | 352 |
| 296 // It would be fine if all buffers were word aligned, | 353 if ((int) buf & 1) { |
| 297 // but who knows | 354 // Unaligned buffer, so assemble each word manually |
| 298 // | 355 for (i=0; i<nword; ++i) { |
| 299 for (j = 0, c=0 ; j < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); | 356 w = *buf++; |
| 300 j++) { | 357 w |= (cyg_uint16) (*buf++) << 8; |
| 301 p = (c++<(len*512)) ? *b++ : 0; | 358 HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, w); |
| 302 p |= (c++<(len*512)) ? (*b++<<8) : 0; | 359 } |
| 303 HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, p); | 360 } |
| 304 } | 361 else { |
| 305 return 1; | 362 cyg_uint16* wbuf = (cyg_uint16*) buf; |
| 363 for (i=0; i<nword; ++i) | |
| 364 HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, *wbuf++); | |
| 365 } | |
| 366 return (int) len; | |
| 306 } | 367 } |
| 307 | 368 |
| 308 // ---------------------------------------------------------------------------- | 369 // ---------------------------------------------------------------------------- |
| 309 | 370 |
| 310 static cyg_bool | 371 static cyg_bool |
| 326 if (!num_controllers) num_controllers=HAL_IDE_INIT(); | 387 if (!num_controllers) num_controllers=HAL_IDE_INIT(); |
| 327 if (info->chan>=num_controllers) { | 388 if (info->chan>=num_controllers) { |
| 328 D("No IDE controller for channel %d:%d\n", info->port, info->chan); | 389 D("No IDE controller for channel %d:%d\n", info->port, info->chan); |
| 329 return false; | 390 return false; |
| 330 } | 391 } |
| 392 | |
| 393 #if CYGDAT_DEVS_DISK_IDE_STARTUP_DELAY | |
| 394 CYGACC_CALL_IF_DELAY_US(CYGDAT_DEVS_DISK_IDE_STARTUP_DELAY*1000U); | |
| 395 #endif | |
| 396 | |
| 331 if (!ide_present[info->port]) { | 397 if (!ide_present[info->port]) { |
| 332 ide_present[info->port]=ide_presence_detect(info->port); | 398 ide_present[info->port]=ide_presence_detect(info->port); |
| 333 if (!ide_present[info->port]) { | 399 if (!ide_present[info->port]) { |
| 334 diag_printf("No devices on IDE controller #%d\n",info->port); | 400 diag_printf("No devices on IDE controller #%d\n",info->port); |
| 335 return false; | 401 return false; |
| 340 if (!ide_reset_done[info->port]) { | 406 if (!ide_reset_done[info->port]) { |
| 341 D("Controller #%d reset failure\n",info->port); | 407 D("Controller #%d reset failure\n",info->port); |
| 342 return false; | 408 return false; |
| 343 } | 409 } |
| 344 } | 410 } |
| 411 | |
| 412 #ifdef CYGDAT_DEVS_DISK_IDE_8_BIT_DATA_PATH | |
| 413 if (!ide_8bit_mode(info->port, info->chan, true)) { | |
| 414 D("IDE disk %d:%d failed to enter 8-bit mode\n", | |
| 415 info->port, info->chan); | |
| 416 } | |
| 417 #endif | |
| 345 | 418 |
| 346 D("IDE %d:%d identify drive\n", info->port, info->chan); | 419 D("IDE %d:%d identify drive\n", info->port, info->chan); |
| 347 | 420 |
| 348 if (!ide_ident(info->port, info->chan, (cyg_uint16 *)id_buf)) { | 421 if (!ide_ident(info->port, info->chan, (cyg_uint16 *)id_buf)) { |
| 349 diag_printf("IDE %d:%d ident DRQ error\n", info->port, info->chan); | 422 diag_printf("IDE %d:%d ident DRQ error\n", info->port, info->chan); |
| 350 return false; | 423 return false; |
| 351 } | 424 } |
| 352 | 425 |
| 353 id_strcpy(ident.serial, ide_idData->serial, 20); | 426 id_strcpy(ident.serial, ide_idData->serial, 20); |
| 354 id_strcpy(ident.firmware_rev, ide_idData->firmware_rev, 8); | 427 id_strcpy(ident.firmware_rev, ide_idData->firmware_rev, 8); |
| 355 id_strcpy(ident.model_num, ide_idData->model_num, 40); | 428 id_strcpy(ident.model_num, ide_idData->model_num, 40); |
| 356 | 429 |
| 357 ident.cylinders_num = ide_idData->num_cylinders; | 430 ident.cylinders_num = ide_idData->num_cylinders; |
| 358 ident.heads_num = ide_idData->num_heads; | 431 ident.heads_num = ide_idData->num_heads; |
| 359 ident.sectors_num = ide_idData->num_sectors; | 432 ident.sectors_num = ide_idData->num_sectors; |
| 360 ident.lba_sectors_num = ide_idData->lba_total_sectors[1] << 16 | | 433 ident.lba_sectors_num = ide_idData->lba_total_sectors[1] << 16 | |
| 361 ide_idData->lba_total_sectors[0]; | 434 ide_idData->lba_total_sectors[0]; |
| 362 ident.phys_block_size = 1; | 435 ident.phys_block_size = 1; |
| 436 | |
| 437 // TODO: Should this be CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE? | |
| 363 ident.max_transfer = 512; | 438 ident.max_transfer = 512; |
| 364 | 439 |
| 365 D("\tSerial : %s\n", ident.serial); | 440 D("\tSerial : %s\n", ident.serial); |
| 366 D("\tFirmware rev. : %s\n", ident.firmware_rev); | 441 D("\tFirmware rev. : %s\n", ident.firmware_rev); |
| 367 D("\tModel : %s\n", ident.model_num); | 442 D("\tModel : %s\n", ident.model_num); |
| 368 D("\tC/H/S : %d/%d/%d\n", ident.cylinders_num, | 443 D("\tC/H/S : %d/%d/%d\n", ident.cylinders_num, |
| 369 ident.heads_num, ident.sectors_num); | 444 ident.heads_num, ident.sectors_num); |
| 370 D("\tKind : %x\n", (ide_idData->general_conf>>8)&0x1f); | 445 |
| 371 | |
| 372 if (((ide_idData->general_conf>>8)&0x1f)!=2) { | |
| 373 diag_printf("IDE device %d:%d is not a hard disk!\n", | |
| 374 info->port, info->chan); | |
| 375 return false; | |
| 376 } | |
| 377 if (!(chan->callbacks->disk_init)(tab)) | 446 if (!(chan->callbacks->disk_init)(tab)) |
| 378 return false; | 447 return false; |
| 379 | 448 |
| 380 if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident)) | 449 if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident)) |
| 381 return false; | 450 return false; |
