Changeset d30e067 in mainline for uspace/lib/ata/src/ata.c
- Timestamp:
- 2025-03-02T20:02:33Z (5 months ago)
- Children:
- 8cdf360
- Parents:
- 7debda3 (diff), 4285f384 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ata/src/ata.c
r7debda3 rd30e067 1 1 /* 2 * Copyright (c) 202 4Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 96 96 static errno_t ata_bd_get_block_size(bd_srv_t *, size_t *); 97 97 static errno_t ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 98 static errno_t ata_bd_eject(bd_srv_t *); 98 99 static errno_t ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t); 99 100 … … 105 106 static errno_t ata_identify_dev(ata_device_t *, void *); 106 107 static errno_t ata_identify_pkt_dev(ata_device_t *, void *); 107 static errno_t ata_cmd_packet(ata_device_t *, const void *, size_t, void *, 108 static errno_t ata_cmd_packet_nondata(ata_device_t *, const void *, size_t); 109 static errno_t ata_cmd_packet_din(ata_device_t *, const void *, size_t, void *, 108 110 size_t, size_t *); 109 111 static errno_t ata_pcmd_inquiry(ata_device_t *, void *, size_t, size_t *); … … 111 113 static errno_t ata_pcmd_read_capacity(ata_device_t *, uint64_t *, size_t *); 112 114 static errno_t ata_pcmd_read_toc(ata_device_t *, uint8_t, void *, size_t); 115 static errno_t ata_pcmd_start_stop_unit(ata_device_t *, uint8_t); 113 116 static void disk_print_summary(ata_device_t *); 114 117 static size_t ata_disk_maxnb(ata_device_t *); … … 129 132 .get_block_size = ata_bd_get_block_size, 130 133 .get_num_blocks = ata_bd_get_num_blocks, 131 .sync_cache = ata_bd_sync_cache 134 .sync_cache = ata_bd_sync_cache, 135 .eject = ata_bd_eject 132 136 }; 133 137 … … 257 261 258 262 for (i = 0; i < MAX_DEVICES; i++) { 263 if (chan->device[i].present == false) 264 continue; 265 259 266 rc = ata_device_remove(&chan->device[i]); 260 267 if (rc != EOK) { 261 268 ata_msg_error(chan, "Unable to remove device %d.", i); 262 break; 269 fibril_mutex_unlock(&chan->lock); 270 return rc; 263 271 } 264 272 } … … 266 274 ata_bd_fini_irq(chan); 267 275 fibril_mutex_unlock(&chan->lock); 276 free(chan); 268 277 269 278 return rc; … … 753 762 } 754 763 764 /** Eject medium. */ 765 static errno_t ata_bd_eject(bd_srv_t *bd) 766 { 767 ata_device_t *device = bd_srv_device(bd); 768 769 ata_msg_debug(device->chan, "ata_bd_eject()"); 770 return ata_pcmd_start_stop_unit(device, ssf_pc_no_change | 771 ssf_loej); 772 } 773 755 774 /** PIO data-in command protocol. */ 756 775 static errno_t ata_pio_data_in(ata_device_t *device, void *obuf, size_t obuf_size, … … 1083 1102 } 1084 1103 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). 1104 /** Issue packet command (i. e. write a command packet to the device) 1105 * with no data transfer. 1088 1106 * 1089 1107 * @param device Device 1108 * @param cpkt Command packet 1109 * @param cpkt_size Command packet size in bytes 1110 * 1111 * @return EOK on success, EIO on error. 1112 */ 1113 static errno_t ata_cmd_packet_nondata(ata_device_t *device, const void *cpkt, 1114 size_t cpkt_size) 1115 { 1116 ata_channel_t *chan = device->chan; 1117 uint8_t status; 1118 uint8_t drv_head; 1119 errno_t rc; 1120 1121 ata_msg_debug(chan, "ata_cmd_packet_nondata()"); 1122 1123 fibril_mutex_lock(&chan->lock); 1124 1125 /* New value for Drive/Head register */ 1126 drv_head = 1127 ((disk_dev_idx(device) != 0) ? DHR_DRV : 0); 1128 1129 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) { 1130 fibril_mutex_unlock(&chan->lock); 1131 return EIO; 1132 } 1133 1134 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head); 1135 1136 if (wait_status(chan, 0, ~(SR_BSY | SR_DRQ), NULL, TIMEOUT_BSY) != EOK) { 1137 fibril_mutex_unlock(&chan->lock); 1138 return EIO; 1139 } 1140 1141 ata_write_cmd_8(chan, REG_COMMAND, CMD_PACKET); 1142 1143 if (wait_status(chan, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 1144 if (chan->params.use_dma) 1145 ata_dma_chan_teardown(device); 1146 fibril_mutex_unlock(&chan->lock); 1147 return EIO; 1148 } 1149 1150 /* Write command packet. */ 1151 ata_write_data_16(chan, ((uint16_t *) cpkt), (cpkt_size + 1) / 2); 1152 1153 rc = ata_pio_nondata(device); 1154 1155 fibril_mutex_unlock(&chan->lock); 1156 1157 return rc; 1158 } 1159 1160 /** Issue packet command (i. e. write a command packet to the device) 1161 * performing data-in transfer. 1162 * 1163 * @param device Device 1164 * @param cpkt Command packet 1165 * @param cpkt_size Command packet size in bytes 1090 1166 * @param obuf Buffer for storing data read from device 1091 1167 * @param obuf_size Size of obuf in bytes … … 1094 1170 * @return EOK on success, EIO on error. 1095 1171 */ 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)1172 static errno_t ata_cmd_packet_din(ata_device_t *device, const void *cpkt, 1173 size_t cpkt_size, void *obuf, size_t obuf_size, size_t *rcvd_size) 1098 1174 { 1099 1175 ata_channel_t *chan = device->chan; … … 1190 1266 cp->alloc_len = host2uint16_t_be(min(obuf_size, 0xff)); 1191 1267 1192 rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, rcvd_size); 1268 rc = ata_cmd_packet_din(device, cpb, sizeof(cpb), obuf, obuf_size, 1269 rcvd_size); 1193 1270 if (rc != EOK) 1194 1271 return rc; … … 1216 1293 cdb.op_code = SCSI_CMD_READ_CAPACITY_10; 1217 1294 1218 rc = ata_cmd_packet(device, &cdb, sizeof(cdb), &data, sizeof(data), &rsize); 1295 rc = ata_cmd_packet_din(device, &cdb, sizeof(cdb), &data, sizeof(data), 1296 &rsize); 1219 1297 if (rc != EOK) 1220 1298 return rc; … … 1257 1335 cp.xfer_len = host2uint32_t_be(cnt); 1258 1336 1259 rc = ata_cmd_packet (device, &cp, sizeof(cp), obuf, obuf_size, NULL);1337 rc = ata_cmd_packet_din(device, &cp, sizeof(cp), obuf, obuf_size, NULL); 1260 1338 if (rc != EOK) 1261 1339 return rc; … … 1297 1375 cp->control = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */ 1298 1376 1299 rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, NULL); 1377 rc = ata_cmd_packet_din(device, cpb, sizeof(cpb), obuf, obuf_size, 1378 NULL); 1300 1379 if (rc != EOK) 1301 1380 return rc; 1381 1382 return EOK; 1383 } 1384 1385 /** Issue Start Stop Unit command. 1386 * 1387 * @param device Device 1388 * @param flags Flags field of Start Stop Unit command (ssf_*) 1389 * @return EOK on success, EIO on error. 1390 */ 1391 static errno_t ata_pcmd_start_stop_unit(ata_device_t *device, uint8_t flags) 1392 { 1393 uint8_t cpb[12]; 1394 scsi_cdb_start_stop_unit_t *cp = (scsi_cdb_start_stop_unit_t *)cpb; 1395 errno_t rc; 1396 1397 ata_msg_debug(device->chan, "ata_pcmd_start_stop_unit(device, 0x%x)", 1398 flags); 1399 1400 memset(cpb, 0, sizeof(cpb)); 1401 1402 /* 1403 * For SFF 8020 compliance the command must be padded to 12 bytes. 1404 */ 1405 cp->op_code = SCSI_CMD_START_STOP_UNIT; 1406 cp->immed = 0; 1407 cp->flags = flags; 1408 cp->control = 0; 1409 1410 rc = ata_cmd_packet_nondata(device, cpb, sizeof(cpb)); 1411 if (rc != EOK) 1412 return rc; 1413 1414 ata_msg_debug(device->chan, "ata_pcmd_start_stop_unit(): " 1415 "ata_cmd_packet_nondata -> %d", rc); 1302 1416 1303 1417 return EOK; … … 1532 1646 * exceed DMA buffer size. 1533 1647 */ 1534 dma_maxnb = d->chan->params.max_dma_xfer / d->block_size; 1535 if (dma_maxnb < maxnb) 1536 maxnb = dma_maxnb; 1648 if (d->chan->params.use_dma) { 1649 dma_maxnb = d->chan->params.max_dma_xfer / d->block_size; 1650 if (dma_maxnb < maxnb) 1651 maxnb = dma_maxnb; 1652 } 1537 1653 1538 1654 return maxnb;
Note:
See TracChangeset
for help on using the changeset viewer.