=== modified file 'uspace/srv/bd/ata_bd/ata_bd.c'
|
|
|
370 | 370 | uint8_t model[40]; |
371 | 371 | ata_inquiry_data_t inq_data; |
372 | 372 | uint16_t w; |
373 | | uint8_t c; |
| 373 | uint8_t c, bc_high, bc_low; |
374 | 374 | size_t pos, len; |
375 | 375 | int rc; |
376 | 376 | unsigned i; |
… |
… |
|
386 | 386 | d->dev_type = ata_reg_dev; |
387 | 387 | } else if (rc == EIO) { |
388 | 388 | /* |
389 | | * There is something, but not a register device. |
390 | | * It could be a packet device. |
| 389 | * There is something, but not a register device. Check to see |
| 390 | * whether the IDENTIFY command left the packet signature in |
| 391 | * the registers in case this is a packet device. |
| 392 | * |
| 393 | * According to the ATA specification, the LBA low and |
| 394 | * interrupt reason registers should be set to 0x01. However, |
| 395 | * there are many devices that do not follow this and only set |
| 396 | * the byte count registers. So, only check these. |
391 | 397 | */ |
392 | | rc = identify_pkt_dev(disk_id, &idata); |
393 | | if (rc == EOK) { |
394 | | /* We have a packet device. */ |
395 | | d->dev_type = ata_pkt_dev; |
| 398 | bc_high = pio_read_8(&cmd->cylinder_high); |
| 399 | bc_low = pio_read_8(&cmd->cylinder_low); |
| 400 | |
| 401 | if (bc_high == 0xEB && bc_low == 0x14) { |
| 402 | rc = identify_pkt_dev(disk_id, &idata); |
| 403 | if (rc == EOK) { |
| 404 | /* We have a packet device. */ |
| 405 | d->dev_type = ata_pkt_dev; |
| 406 | } else { |
| 407 | return EIO; |
| 408 | } |
396 | 409 | } else { |
397 | 410 | /* Nope. Something's there, but not recognized. */ |
398 | 411 | return EIO; |
… |
… |
|
565 | 578 | pio_write_8(&cmd->drive_head, drv_head); |
566 | 579 | |
567 | 580 | /* |
568 | | * This is where we would most likely expect a non-existing device to |
569 | | * show up by not setting SR_DRDY. |
| 581 | * Do not wait for DRDY to be set in case this is a packet device. |
| 582 | * We determine whether the device is present by waiting for DRQ to be |
| 583 | * set after issuing the command. |
570 | 584 | */ |
571 | | if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) |
| 585 | if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) |
572 | 586 | return ETIMEOUT; |
573 | 587 | |
574 | 588 | pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE); |
… |
… |
|
576 | 590 | if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) |
577 | 591 | return ETIMEOUT; |
578 | 592 | |
| 593 | /* |
| 594 | * If ERR is set, this may be a packet device, so return EIO to cause |
| 595 | * the caller to check for one. |
| 596 | */ |
| 597 | if ((status & SR_ERR) != 0) { |
| 598 | return EIO; |
| 599 | } |
| 600 | |
| 601 | if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) |
| 602 | return ETIMEOUT; |
| 603 | |
579 | 604 | /* Read data from the disk buffer. */ |
580 | 605 | |
581 | | if ((status & SR_DRQ) != 0) { |
582 | | for (i = 0; i < identify_data_size / 2; i++) { |
583 | | data = pio_read_16(&cmd->data_port); |
584 | | ((uint16_t *) buf)[i] = data; |
585 | | } |
586 | | } |
587 | | |
588 | | if ((status & SR_ERR) != 0) { |
589 | | return EIO; |
| 606 | for (i = 0; i < identify_data_size / 2; i++) { |
| 607 | data = pio_read_16(&cmd->data_port); |
| 608 | ((uint16_t *) buf)[i] = data; |
590 | 609 | } |
591 | 610 | |
592 | 611 | return EOK; |