Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/ata_bd/ata_bd.c

    r8a81a73a ra7de7907  
    3636 *
    3737 * This driver currently works only with CHS addressing and uses PIO.
    38  * Currently based on the (now obsolete) ANSI X3.221-1994 (ATA-1) standard.
    39  * At this point only reading is possible, not writing.
     38 * Currently based on the (now obsolete) ATA-1, ATA-2 standards.
    4039 *
    4140 * The driver services a single controller which can have up to two disks
     
    9695                return -1;
    9796
    98         /* Put drives to reset, disable interrupts. */
    99         printf("Reset drives... ");
    100         fflush(stdout);
    101 
    102         pio_write_8(&ctl->device_control, DCR_SRST);
    103         /* FIXME: Find out how to do this properly. */
    104         async_usleep(100);
    105         pio_write_8(&ctl->device_control, 0);
    106 
    107         do {
    108                 status = pio_read_8(&cmd->status);
    109         } while ((status & SR_BSY) != 0);
    110         printf("Done\n");
    111 
    11297        (void) drive_identify(0, &disk[0]);
    11398        (void) drive_identify(1, &disk[1]);
     
    148133        uint16_t data;
    149134        uint8_t status;
     135        uint8_t drv_head;
    150136        size_t i;
    151137
     
    153139        fflush(stdout);
    154140
    155         pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0));
    156         async_usleep(100);
    157         pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
    158 
    159         status = pio_read_8(&cmd->status);
    160 
     141        drv_head = ((disk_id != 0) ? DHR_DRV : 0);
    161142        d->present = false;
     143
     144        do {
     145                status = pio_read_8(&cmd->status);
     146        } while ((status & SR_BSY) != 0);
     147
     148        pio_write_8(&cmd->drive_head, drv_head);
    162149
    163150        /*
     
    165152         * do the right thing to work with real drives.
    166153         */
     154        do {
     155                status = pio_read_8(&cmd->status);
     156        } while ((status & SR_BSY) != 0);
     157
    167158        if ((status & SR_DRDY) == 0) {
    168159                printf("None attached.\n");
    169160                return ENOENT;
    170161        }
    171 
    172         for (i = 0; i < block_size / 2; i++) {
    173                 do {
    174                         status = pio_read_8(&cmd->status);
    175                 } while ((status & SR_DRDY) == 0);
    176 
    177                 data = pio_read_16(&cmd->data_port);
    178 
    179                 switch (i) {
    180                 case 1: d->cylinders = data; break;
    181                 case 3: d->heads = data; break;
    182                 case 6: d->sectors = data; break;
     162        /***/
     163
     164        do {
     165                status = pio_read_8(&cmd->status);
     166        } while ((status & SR_BSY) != 0 || (status & SR_DRDY) == 0);
     167
     168        pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
     169
     170        do {
     171                status = pio_read_8(&cmd->status);
     172        } while ((status & SR_BSY) != 0);
     173
     174        /* Read data from the disk buffer. */
     175
     176        if ((status & SR_DRQ) != 0) {
     177//              for (i = 0; i < block_size / 2; i++) {
     178//                      data = pio_read_16(&cmd->data_port);
     179//                      ((uint16_t *) buf)[i] = data;
     180//              }
     181
     182                for (i = 0; i < block_size / 2; i++) {
     183                        data = pio_read_16(&cmd->data_port);
     184
     185                        switch (i) {
     186                        case 1: d->cylinders = data; break;
     187                        case 3: d->heads = data; break;
     188                        case 6: d->sectors = data; break;
     189                        }
    183190                }
    184191        }
     192
     193        if ((status & SR_ERR) != 0)
     194                return EIO;
    185195
    186196        d->blocks = d->cylinders * d->heads * d->sectors;
     
    361371        /* Program a Read Sectors operation. */
    362372
     373        do {
     374                status = pio_read_8(&cmd->status);
     375        } while ((status & SR_BSY) != 0);
     376
    363377        pio_write_8(&cmd->drive_head, drv_head);
     378
     379        do {
     380                status = pio_read_8(&cmd->status);
     381        } while ((status & SR_BSY) != 0 || (status & SR_DRDY) == 0);
     382
    364383        pio_write_8(&cmd->sector_count, 1);
    365384        pio_write_8(&cmd->sector_number, s);
    366385        pio_write_8(&cmd->cylinder_low, c & 0xff);
    367386        pio_write_8(&cmd->cylinder_high, c >> 16);
     387
    368388        pio_write_8(&cmd->command, CMD_READ_SECTORS);
    369389
     390        do {
     391                status = pio_read_8(&cmd->status);
     392        } while ((status & SR_BSY) != 0);
     393
    370394        /* Read data from the disk buffer. */
    371395
    372         for (i = 0; i < block_size / 2; i++) {
    373                 do {
    374                         status = pio_read_8(&cmd->status);
    375                 } while ((status & SR_DRDY) == 0);
    376 
    377                 data = pio_read_16(&cmd->data_port);
    378                 ((uint16_t *) buf)[i] = data;
    379         }
     396        if ((status & SR_DRQ) != 0) {
     397                for (i = 0; i < block_size / 2; i++) {
     398                        data = pio_read_16(&cmd->data_port);
     399                        ((uint16_t *) buf)[i] = data;
     400                }
     401        }
     402
     403        if ((status & SR_ERR) != 0)
     404                return EIO;
    380405
    381406        fibril_mutex_unlock(&d->lock);
     
    415440        /* Program a Read Sectors operation. */
    416441
     442        do {
     443                status = pio_read_8(&cmd->status);
     444        } while ((status & SR_BSY) != 0);
     445       
    417446        pio_write_8(&cmd->drive_head, drv_head);
     447
     448        do {
     449                status = pio_read_8(&cmd->status);
     450        } while ((status & SR_BSY) != 0 || (status & SR_DRDY) == 0);
     451
    418452        pio_write_8(&cmd->sector_count, 1);
    419453        pio_write_8(&cmd->sector_number, s);
    420454        pio_write_8(&cmd->cylinder_low, c & 0xff);
    421455        pio_write_8(&cmd->cylinder_high, c >> 16);
     456
    422457        pio_write_8(&cmd->command, CMD_WRITE_SECTORS);
    423458
     459        do {
     460                status = pio_read_8(&cmd->status);
     461        } while ((status & SR_BSY) != 0);
     462
    424463        /* Write data to the disk buffer. */
    425464
    426         for (i = 0; i < block_size / 2; i++) {
    427                 do {
    428                         status = pio_read_8(&cmd->status);
    429                 } while ((status & SR_DRDY) == 0);
    430 
    431                 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
     465        if ((status & SR_DRQ) != 0) {
     466                for (i = 0; i < block_size / 2; i++) {
     467                        pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
     468                }
    432469        }
    433470
    434471        fibril_mutex_unlock(&d->lock);
     472
     473        if (status & SR_ERR)
     474                return EIO;
     475
    435476        return EOK;
    436477}
    437 
    438478
    439479/**
Note: See TracChangeset for help on using the changeset viewer.