File indexing completed on 2025-05-11 08:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <assert.h>
0013 #include <string.h>
0014
0015 #include <libchip/ide_ctrl_io.h>
0016 #include <libchip/ide_ctrl_cfg.h>
0017 #include <libchip/ata_internal.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 void
0031 ata_process_request_on_init_phase(rtems_device_minor_number ctrl_minor,
0032 ata_req_t *areq)
0033 {
0034 uint16_t byte;
0035 uint8_t i;
0036 #if 0
0037 uint8_t dev;
0038 #endif
0039 uint16_t val, val1;
0040 volatile unsigned retries;
0041
0042 assert(areq);
0043
0044 #if 0
0045 dev = areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
0046 IDE_REGISTER_DEVICE_HEAD_DEV;
0047 #endif
0048
0049 ide_controller_write_register(ctrl_minor, IDE_REGISTER_DEVICE_HEAD,
0050 areq->regs.regs[IDE_REGISTER_DEVICE_HEAD]);
0051
0052 retries = 0;
0053 do {
0054 ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
0055
0056
0057
0058
0059
0060
0061 if ( ! (byte & (IDE_REGISTER_STATUS_BSY | IDE_REGISTER_STATUS_DRDY))) {
0062 retries++;
0063 if ( 10000 == retries ) {
0064
0065 areq->breq->status = RTEMS_UNSATISFIED;
0066 return;
0067 }
0068 }
0069 } while ((byte & IDE_REGISTER_STATUS_BSY) ||
0070 (!(byte & IDE_REGISTER_STATUS_DRDY)));
0071
0072 for (i=0; i< ATA_MAX_CMD_REG_OFFSET; i++)
0073 {
0074 uint32_t reg = (1 << i);
0075 if (areq->regs.to_write & reg)
0076 ide_controller_write_register(ctrl_minor, i,
0077 areq->regs.regs[i]);
0078 }
0079
0080 do {
0081 ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
0082 } while (byte & IDE_REGISTER_STATUS_BSY);
0083
0084 ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
0085 ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &val1);
0086
0087 if (val & IDE_REGISTER_STATUS_ERR)
0088 {
0089 areq->breq->status = RTEMS_IO_ERROR;
0090 return;
0091 }
0092
0093 switch(areq->type)
0094 {
0095 case ATA_COMMAND_TYPE_PIO_IN:
0096 if (areq->cnt)
0097 {
0098 int ccbuf = areq->cbuf;
0099 ide_controller_read_data_block(ctrl_minor,
0100 areq->breq->bufs[0].length * areq->cnt,
0101 areq->breq->bufs, &areq->cbuf,
0102 &areq->pos);
0103 ccbuf = areq->cbuf - ccbuf;
0104 areq->cnt -= ccbuf;
0105 }
0106 if (areq->cnt == 0)
0107 {
0108 areq->breq->status = RTEMS_SUCCESSFUL;
0109 }
0110 else
0111 {
0112
0113
0114
0115
0116 rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
0117 }
0118 break;
0119
0120 case ATA_COMMAND_TYPE_NON_DATA:
0121 areq->breq->status = RTEMS_SUCCESSFUL;
0122 areq->info = val1;
0123 break;
0124
0125 default:
0126 areq->breq->status = RTEMS_IO_ERROR;
0127 break;
0128 }
0129 }
0130
0131 void ata_breq_init(blkdev_request1 *breq, uint16_t *sector_buffer)
0132 {
0133 memset(breq, 0, sizeof(*breq));
0134
0135 breq->req.done_arg = breq;
0136 breq->req.bufnum = 1;
0137 breq->req.bufs [0].length = ATA_SECTOR_SIZE;
0138 breq->req.bufs [0].buffer = sector_buffer;
0139 }
0140
0141 rtems_status_code ata_identify_device(
0142 rtems_device_minor_number ctrl_minor,
0143 int dev,
0144 uint16_t *sector_buffer,
0145 ata_dev_t *device_entry
0146 )
0147 {
0148 ata_req_t areq;
0149 blkdev_request1 breq;
0150
0151 ata_breq_init(&breq, sector_buffer);
0152
0153
0154
0155
0156
0157 memset(&areq, 0, sizeof(ata_req_t));
0158 areq.type = ATA_COMMAND_TYPE_PIO_IN;
0159 areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
0160 areq.regs.regs [IDE_REGISTER_COMMAND] = ATA_COMMAND_IDENTIFY_DEVICE;
0161 areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_STATUS);
0162 areq.breq = (rtems_blkdev_request *)&breq;
0163 areq.cnt = breq.req.bufnum;
0164 areq.regs.regs [IDE_REGISTER_DEVICE_HEAD] |=
0165 dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS;
0166
0167
0168
0169
0170
0171
0172 ata_process_request_on_init_phase(ctrl_minor, &areq);
0173
0174
0175 if (breq.req.status != RTEMS_SUCCESSFUL) {
0176 return RTEMS_IO_ERROR;
0177 }
0178
0179
0180
0181
0182
0183 device_entry->cylinders =
0184 CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_CLNDS]);
0185 device_entry->heads =
0186 CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_HEADS]);
0187 device_entry->sectors =
0188 CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_SECS]);
0189 device_entry->lba_sectors =
0190 CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS1]);
0191 device_entry->lba_sectors <<= 16;
0192 device_entry->lba_sectors += CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS0]);
0193 device_entry->lba_avaible =
0194 (CF_LE_W(sector_buffer[ATA_IDENT_WORD_CAPABILITIES]) >> 9) & 0x1;
0195
0196 if ((CF_LE_W(sector_buffer[ATA_IDENT_WORD_FIELD_VALIDITY]) &
0197 ATA_IDENT_BIT_VALID) == 0) {
0198
0199 device_entry->mode_active = ATA_MODES_PIO3;
0200 } else {
0201 device_entry->modes_available =
0202 ((CF_LE_W(sector_buffer[64]) & 0x1) ? ATA_MODES_PIO3 : 0) |
0203 ((CF_LE_W(sector_buffer[64]) & 0x2) ? ATA_MODES_PIO4 : 0) |
0204 ((CF_LE_W(sector_buffer[63]) & 0x1) ? ATA_MODES_DMA0 : 0) |
0205 ((CF_LE_W(sector_buffer[63]) & 0x2) ?
0206 ATA_MODES_DMA0 | ATA_MODES_DMA1 : 0) |
0207 ((CF_LE_W(sector_buffer[63]) & 0x4) ?
0208 ATA_MODES_DMA0 | ATA_MODES_DMA1 | ATA_MODES_DMA2 : 0);
0209 if (device_entry->modes_available == 0) {
0210 return RTEMS_IO_ERROR;
0211 }
0212 }
0213
0214 return RTEMS_SUCCESSFUL;
0215 }