Changeset 645d3832 in mainline for uspace/drv/block/pci-ide/pci-ide.c
- Timestamp:
- 2024-06-10T17:29:13Z (4 weeks ago)
- Branches:
- master
- Children:
- a38d504
- Parents:
- 69c376b5
- git-author:
- Jiri Svoboda <jiri@…> (2024-06-10 17:24:58)
- git-committer:
- Jiri Svoboda <jiri@…> (2024-06-10 17:29:13)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/block/pci-ide/pci-ide.c
r69c376b5 r645d3832 36 36 */ 37 37 38 #include <assert.h> 38 39 #include <ddi.h> 39 40 #include <ddf/interrupt.h> … … 67 68 static errno_t pci_ide_irq_enable(void *); 68 69 static errno_t pci_ide_irq_disable(void *); 70 static void pci_ide_dma_chan_setup(void *, void *, size_t, ata_dma_dir_t); 71 static void pci_ide_dma_chan_teardown(void *); 69 72 static errno_t pci_ide_add_device(void *, unsigned, void *); 70 73 static errno_t pci_ide_remove_device(void *, unsigned); … … 93 96 }; 94 97 98 /** Initialize PCI IDE controller. 99 * 100 * @param ctrl PCI IDE controller 101 * @param res Hardware resources 102 * 103 * @return EOK on success or an error code 104 */ 105 errno_t pci_ide_ctrl_init(pci_ide_ctrl_t *ctrl, pci_ide_hwres_t *res) 106 { 107 errno_t rc; 108 void *vaddr; 109 110 ddf_msg(LVL_DEBUG, "pci_ide_ctrl_init()"); 111 ctrl->bmregs_physical = res->bmregs; 112 113 ddf_msg(LVL_NOTE, "Bus master IDE regs I/O address: 0x%lx", 114 ctrl->bmregs_physical); 115 116 rc = pio_enable((void *)ctrl->bmregs_physical, sizeof(pci_ide_regs_t), 117 &vaddr); 118 if (rc != EOK) { 119 ddf_msg(LVL_ERROR, "Cannot initialize device I/O space."); 120 return rc; 121 } 122 123 ctrl->bmregs = vaddr; 124 125 ddf_msg(LVL_DEBUG, "pci_ide_ctrl_init: DONE"); 126 return EOK; 127 } 128 129 /** Finalize PCI IDE controller. 130 * 131 * @param ctrl PCI IDE controller 132 * @return EOK on success or an error code 133 */ 134 errno_t pci_ide_ctrl_fini(pci_ide_ctrl_t *ctrl) 135 { 136 ddf_msg(LVL_DEBUG, ": pci_ide_ctrl_fini()"); 137 138 // XXX TODO 139 return EOK; 140 } 141 95 142 /** Initialize PCI IDE channel. */ 96 143 errno_t pci_ide_channel_init(pci_ide_ctrl_t *ctrl, pci_ide_channel_t *chan, … … 100 147 bool irq_inited = false; 101 148 ata_params_t params; 102 103 ddf_msg(LVL_DEBUG, "pci_ide_ctrl_init()"); 149 void *buffer; 150 151 ddf_msg(LVL_DEBUG, "pci_ide_channel_init()"); 104 152 105 153 chan->ctrl = ctrl; … … 116 164 } 117 165 166 chan->dma_buf_size = 8192; 167 118 168 ddf_msg(LVL_NOTE, "I/O address %p/%p", (void *) chan->cmd_physical, 119 169 (void *) chan->ctl_physical); … … 128 178 if (rc != EOK) { 129 179 ddf_msg(LVL_NOTE, "init IRQ failed"); 130 return rc;180 goto error; 131 181 } 132 182 133 183 irq_inited = true; 134 184 135 ddf_msg(LVL_DEBUG, "pci_ide_ctrl_init(): Initialize IDE channel"); 185 ddf_msg(LVL_DEBUG, "Allocate PRD table"); 186 187 buffer = AS_AREA_ANY; 188 rc = dmamem_map_anonymous(sizeof (pci_ide_prd_t), DMAMEM_4GiB | 0xffff, 189 AS_AREA_WRITE | AS_AREA_READ, 0, &chan->prdt_pa, &buffer); 190 if (rc != EOK) { 191 ddf_msg(LVL_NOTE, "Failed allocating PRD table."); 192 goto error; 193 } 194 195 chan->prdt = (pci_ide_prd_t *)buffer; 196 197 ddf_msg(LVL_DEBUG, "Allocate DMA buffer"); 198 199 buffer = AS_AREA_ANY; 200 rc = dmamem_map_anonymous(chan->dma_buf_size, DMAMEM_4GiB | 0xffff, 201 AS_AREA_WRITE | AS_AREA_READ, 0, &chan->dma_buf_pa, &buffer); 202 if (rc != EOK) { 203 ddf_msg(LVL_NOTE, "Failed allocating PRD table."); 204 goto error; 205 } 206 207 chan->dma_buf = buffer; 208 209 /* Populate PRD with information on our single DMA buffer */ 210 chan->prdt->pba = host2uint32_t_le(chan->dma_buf_pa); 211 chan->prdt->bcnt = host2uint16_t_le(chan->dma_buf_size); 212 chan->prdt->eot_res = host2uint16_t_le(pci_ide_prd_eot); 213 214 /* Program PRD table pointer register */ 215 if (chan_id == 0) { 216 pio_write_32(&chan->ctrl->bmregs->bmidtpp, 217 (uint32_t)chan->prdt_pa); 218 } else { 219 pio_write_32(&chan->ctrl->bmregs->bmidtps, 220 (uint32_t)chan->prdt_pa); 221 } 222 223 ddf_msg(LVL_DEBUG, "pci_ide_channel_init(): Initialize IDE channel"); 136 224 137 225 params.arg = (void *)chan; 138 226 params.have_irq = (chan->irq >= 0) ? true : false; 227 params.use_dma = true; 139 228 params.write_data_16 = pci_ide_write_data_16; 140 229 params.read_data_16 = pci_ide_read_data_16; … … 145 234 params.irq_enable = pci_ide_irq_enable; 146 235 params.irq_disable = pci_ide_irq_disable; 236 params.dma_chan_setup = pci_ide_dma_chan_setup; 237 params.dma_chan_teardown = pci_ide_dma_chan_teardown; 147 238 params.add_device = pci_ide_add_device; 148 239 params.remove_device = pci_ide_remove_device; … … 160 251 goto error; 161 252 162 ddf_msg(LVL_DEBUG, "pci_ide_c trl_init: DONE");253 ddf_msg(LVL_DEBUG, "pci_ide_channel_init: DONE"); 163 254 return EOK; 164 255 error: … … 174 265 errno_t rc; 175 266 176 ddf_msg(LVL_DEBUG, ": pci_ide_c trl_remove()");267 ddf_msg(LVL_DEBUG, ": pci_ide_channel_fini()"); 177 268 178 269 fibril_mutex_lock(&chan->lock); … … 212 303 213 304 chan->ctl = vaddr; 305 306 rc = pio_enable((void *) chan->cmd_physical, sizeof(ata_cmd_t), &vaddr); 307 if (rc != EOK) { 308 ddf_msg(LVL_ERROR, "Cannot initialize device I/O space."); 309 return rc; 310 } 311 312 chan->cmd = vaddr; 313 214 314 return EOK; 215 315 } … … 435 535 } 436 536 537 /** Set up DMA channel callback handler 538 * 539 * @param arg Argument (pci_ide_channel_t *) 540 * @param buf Buffer 541 * @param buf_size Buffer size 542 * @param dir DMA transfer direction 543 */ 544 static void pci_ide_dma_chan_setup(void *arg, void *buf, size_t buf_size, 545 ata_dma_dir_t dir) 546 { 547 pci_ide_channel_t *chan = (pci_ide_channel_t *)arg; 548 uint8_t *bmicx; 549 uint8_t val; 550 551 /* Needed later in teardown */ 552 chan->cur_dir = dir; 553 chan->cur_buf = buf; 554 chan->cur_buf_size = buf_size; 555 556 if (dir == ata_dma_write) { 557 assert(buf_size < chan->dma_buf_size); 558 memcpy(chan->dma_buf, buf, buf_size); 559 } 560 561 /* Primary or secondary channel control register */ 562 bmicx = (chan->chan_id == 0) ? &chan->ctrl->bmregs->bmicp : 563 &chan->ctrl->bmregs->bmics; 564 565 /* Set read / write */ 566 val = (dir == ata_dma_write) ? bmicx_rwcon : 0; 567 pio_write_8(bmicx, val); 568 569 /* Start bus master DMA engine */ 570 val = val | bmicx_ssbm; 571 pio_write_8(bmicx, val); 572 } 573 574 /** Tear down DMA channel callback handler 575 * 576 * @param arg Argument (pci_ide_channel_t *) 577 */ 578 static void pci_ide_dma_chan_teardown(void *arg) 579 { 580 pci_ide_channel_t *chan = (pci_ide_channel_t *)arg; 581 uint8_t *bmicx; 582 uint8_t val; 583 584 /* Primary or secondary channel control register */ 585 bmicx = (chan->chan_id == 0) ? &chan->ctrl->bmregs->bmicp : 586 &chan->ctrl->bmregs->bmics; 587 588 /* Stop bus master DMA engine clear SSBM but keep RWCON the same */ 589 val = (chan->cur_dir == ata_dma_write) ? bmicx_rwcon : 0; 590 pio_write_8(bmicx, val); 591 592 if (chan->cur_dir == ata_dma_read) { 593 assert(chan->cur_buf_size < chan->dma_buf_size); 594 memcpy(chan->cur_buf, chan->dma_buf, chan->cur_buf_size); 595 } 596 } 597 437 598 /** Add ATA device callback handler. 438 599 *
Note:
See TracChangeset
for help on using the changeset viewer.