Changes in uspace/lib/ata/src/ata.c [07039850:3d2d455b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ata/src/ata.c
r07039850 r3d2d455b 1 1 /* 2 * Copyright (c) 202 5Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 84 84 static uint8_t ata_read_cmd_8(ata_channel_t *, uint16_t); 85 85 static void ata_write_cmd_8(ata_channel_t *, uint16_t, uint8_t); 86 static void ata_write_ctl_8(ata_channel_t *, uint16_t, uint8_t);87 86 88 87 static errno_t ata_bd_init_irq(ata_channel_t *); … … 97 96 static errno_t ata_bd_get_block_size(bd_srv_t *, size_t *); 98 97 static errno_t ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 99 static errno_t ata_bd_eject(bd_srv_t *);100 98 static errno_t ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t); 101 99 … … 107 105 static errno_t ata_identify_dev(ata_device_t *, void *); 108 106 static errno_t ata_identify_pkt_dev(ata_device_t *, void *); 109 static errno_t ata_cmd_packet_nondata(ata_device_t *, const void *, size_t); 110 static errno_t ata_cmd_packet_din(ata_device_t *, const void *, size_t, void *, 107 static errno_t ata_cmd_packet(ata_device_t *, const void *, size_t, void *, 111 108 size_t, size_t *); 112 109 static errno_t ata_pcmd_inquiry(ata_device_t *, void *, size_t, size_t *); … … 114 111 static errno_t ata_pcmd_read_capacity(ata_device_t *, uint64_t *, size_t *); 115 112 static errno_t ata_pcmd_read_toc(ata_device_t *, uint8_t, void *, size_t); 116 static errno_t ata_pcmd_start_stop_unit(ata_device_t *, uint8_t);117 113 static void disk_print_summary(ata_device_t *); 118 114 static size_t ata_disk_maxnb(ata_device_t *); … … 133 129 .get_block_size = ata_bd_get_block_size, 134 130 .get_num_blocks = ata_bd_get_num_blocks, 135 .sync_cache = ata_bd_sync_cache, 136 .eject = ata_bd_eject 131 .sync_cache = ata_bd_sync_cache 137 132 }; 138 133 … … 262 257 263 258 for (i = 0; i < MAX_DEVICES; i++) { 264 if (chan->device[i].present == false)265 continue;266 267 259 rc = ata_device_remove(&chan->device[i]); 268 260 if (rc != EOK) { 269 261 ata_msg_error(chan, "Unable to remove device %d.", i); 270 fibril_mutex_unlock(&chan->lock); 271 return rc; 262 break; 272 263 } 273 264 } … … 275 266 ata_bd_fini_irq(chan); 276 267 fibril_mutex_unlock(&chan->lock); 277 free(chan);278 268 279 269 return rc; 280 }281 282 /** Quiesce ATA channel. */283 void ata_channel_quiesce(ata_channel_t *chan)284 {285 ata_msg_debug(chan, ": ata_channel_quiesce()");286 287 fibril_mutex_lock(&chan->lock);288 ata_write_ctl_8(chan, REG_DEVCTL, DCR_SRST | DCR_nIEN);289 fibril_mutex_unlock(&chan->lock);290 270 } 291 271 … … 359 339 { 360 340 return chan->params.write_cmd_8(chan->params.arg, port, value); 361 }362 363 /** Write 8 bits to 8-bit control port.364 *365 * @param chan ATA channel366 * @param port Port number367 * @param value Register value368 */369 static void ata_write_ctl_8(ata_channel_t *chan, uint16_t port, uint8_t value)370 {371 return chan->params.write_ctl_8(chan->params.arg, port, value);372 341 } 373 342 … … 784 753 } 785 754 786 /** Eject medium. */787 static errno_t ata_bd_eject(bd_srv_t *bd)788 {789 ata_device_t *device = bd_srv_device(bd);790 791 ata_msg_debug(device->chan, "ata_bd_eject()");792 return ata_pcmd_start_stop_unit(device, ssf_pc_no_change |793 ssf_loej);794 }795 796 755 /** PIO data-in command protocol. */ 797 756 static errno_t ata_pio_data_in(ata_device_t *device, void *obuf, size_t obuf_size, … … 1124 1083 } 1125 1084 1126 /** Issue packet command (i. e. write a command packet to the device) 1127 * with no data transfer. 1085 /** Issue packet command (i. e. write a command packet to the device). 1086 * 1087 * Only data-in commands are supported (e.g. inquiry, read). 1128 1088 * 1129 1089 * @param device Device 1130 * @param cpkt Command packet1131 * @param cpkt_size Command packet size in bytes1132 *1133 * @return EOK on success, EIO on error.1134 */1135 static errno_t ata_cmd_packet_nondata(ata_device_t *device, const void *cpkt,1136 size_t cpkt_size)1137 {1138 ata_channel_t *chan = device->chan;1139 uint8_t status;1140 uint8_t drv_head;1141 errno_t rc;1142 1143 ata_msg_debug(chan, "ata_cmd_packet_nondata()");1144 1145 fibril_mutex_lock(&chan->lock);1146 1147 /* New value for Drive/Head register */1148 drv_head =1149 ((disk_dev_idx(device) != 0) ? DHR_DRV : 0);1150 1151 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {1152 fibril_mutex_unlock(&chan->lock);1153 return EIO;1154 }1155 1156 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);1157 1158 if (wait_status(chan, 0, ~(SR_BSY | SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {1159 fibril_mutex_unlock(&chan->lock);1160 return EIO;1161 }1162 1163 ata_write_cmd_8(chan, REG_COMMAND, CMD_PACKET);1164 1165 if (wait_status(chan, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {1166 if (chan->params.use_dma)1167 ata_dma_chan_teardown(device);1168 fibril_mutex_unlock(&chan->lock);1169 return EIO;1170 }1171 1172 /* Write command packet. */1173 ata_write_data_16(chan, ((uint16_t *) cpkt), (cpkt_size + 1) / 2);1174 1175 rc = ata_pio_nondata(device);1176 1177 fibril_mutex_unlock(&chan->lock);1178 1179 return rc;1180 }1181 1182 /** Issue packet command (i. e. write a command packet to the device)1183 * performing data-in transfer.1184 *1185 * @param device Device1186 * @param cpkt Command packet1187 * @param cpkt_size Command packet size in bytes1188 1090 * @param obuf Buffer for storing data read from device 1189 1091 * @param obuf_size Size of obuf in bytes … … 1192 1094 * @return EOK on success, EIO on error. 1193 1095 */ 1194 static errno_t ata_cmd_packet _din(ata_device_t *device, const void *cpkt,1195 size_t cpkt_size,void *obuf, size_t obuf_size, size_t *rcvd_size)1096 static errno_t ata_cmd_packet(ata_device_t *device, const void *cpkt, size_t cpkt_size, 1097 void *obuf, size_t obuf_size, size_t *rcvd_size) 1196 1098 { 1197 1099 ata_channel_t *chan = device->chan; … … 1288 1190 cp->alloc_len = host2uint16_t_be(min(obuf_size, 0xff)); 1289 1191 1290 rc = ata_cmd_packet_din(device, cpb, sizeof(cpb), obuf, obuf_size, 1291 rcvd_size); 1192 rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, rcvd_size); 1292 1193 if (rc != EOK) 1293 1194 return rc; … … 1315 1216 cdb.op_code = SCSI_CMD_READ_CAPACITY_10; 1316 1217 1317 rc = ata_cmd_packet_din(device, &cdb, sizeof(cdb), &data, sizeof(data), 1318 &rsize); 1218 rc = ata_cmd_packet(device, &cdb, sizeof(cdb), &data, sizeof(data), &rsize); 1319 1219 if (rc != EOK) 1320 1220 return rc; … … 1357 1257 cp.xfer_len = host2uint32_t_be(cnt); 1358 1258 1359 rc = ata_cmd_packet _din(device, &cp, sizeof(cp), obuf, obuf_size, NULL);1259 rc = ata_cmd_packet(device, &cp, sizeof(cp), obuf, obuf_size, NULL); 1360 1260 if (rc != EOK) 1361 1261 return rc; … … 1397 1297 cp->control = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */ 1398 1298 1399 rc = ata_cmd_packet_din(device, cpb, sizeof(cpb), obuf, obuf_size, 1400 NULL); 1299 rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, NULL); 1401 1300 if (rc != EOK) 1402 1301 return rc; 1403 1404 return EOK;1405 }1406 1407 /** Issue Start Stop Unit command.1408 *1409 * @param device Device1410 * @param flags Flags field of Start Stop Unit command (ssf_*)1411 * @return EOK on success, EIO on error.1412 */1413 static errno_t ata_pcmd_start_stop_unit(ata_device_t *device, uint8_t flags)1414 {1415 uint8_t cpb[12];1416 scsi_cdb_start_stop_unit_t *cp = (scsi_cdb_start_stop_unit_t *)cpb;1417 errno_t rc;1418 1419 ata_msg_debug(device->chan, "ata_pcmd_start_stop_unit(device, 0x%x)",1420 flags);1421 1422 memset(cpb, 0, sizeof(cpb));1423 1424 /*1425 * For SFF 8020 compliance the command must be padded to 12 bytes.1426 */1427 cp->op_code = SCSI_CMD_START_STOP_UNIT;1428 cp->immed = 0;1429 cp->flags = flags;1430 cp->control = 0;1431 1432 rc = ata_cmd_packet_nondata(device, cpb, sizeof(cpb));1433 if (rc != EOK)1434 return rc;1435 1436 ata_msg_debug(device->chan, "ata_pcmd_start_stop_unit(): "1437 "ata_cmd_packet_nondata -> %d", rc);1438 1302 1439 1303 return EOK; … … 1668 1532 * exceed DMA buffer size. 1669 1533 */ 1670 if (d->chan->params.use_dma) { 1671 dma_maxnb = d->chan->params.max_dma_xfer / d->block_size; 1672 if (dma_maxnb < maxnb) 1673 maxnb = dma_maxnb; 1674 } 1534 dma_maxnb = d->chan->params.max_dma_xfer / d->block_size; 1535 if (dma_maxnb < maxnb) 1536 maxnb = dma_maxnb; 1675 1537 1676 1538 return maxnb;
Note:
See TracChangeset
for help on using the changeset viewer.