=== 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; |