Lines Matching refs:ida
61 static int ida_alloc_qcbs(struct ida_softc *ida);
62 static void ida_done(struct ida_softc *ida, struct ida_qcb *qcb);
63 static void ida_start(struct ida_softc *ida);
64 static void ida_startio(struct ida_softc *ida);
67 static int ida_wait(struct ida_softc *ida, struct ida_qcb *qcb);
77 ida_free(struct ida_softc *ida) in ida_free() argument
81 if (ida->ih != NULL) in ida_free()
82 bus_teardown_intr(ida->dev, ida->irq, ida->ih); in ida_free()
84 mtx_lock(&ida->lock); in ida_free()
85 callout_stop(&ida->ch); in ida_free()
86 mtx_unlock(&ida->lock); in ida_free()
87 callout_drain(&ida->ch); in ida_free()
89 if (ida->buffer_dmat) { in ida_free()
91 bus_dmamap_destroy(ida->buffer_dmat, ida->qcbs[i].dmamap); in ida_free()
92 bus_dma_tag_destroy(ida->buffer_dmat); in ida_free()
95 if (ida->hwqcb_dmat) { in ida_free()
96 if (ida->hwqcb_busaddr) in ida_free()
97 bus_dmamap_unload(ida->hwqcb_dmat, ida->hwqcb_dmamap); in ida_free()
98 if (ida->hwqcbs) in ida_free()
99 bus_dmamem_free(ida->hwqcb_dmat, ida->hwqcbs, in ida_free()
100 ida->hwqcb_dmamap); in ida_free()
101 bus_dma_tag_destroy(ida->hwqcb_dmat); in ida_free()
104 if (ida->qcbs != NULL) in ida_free()
105 free(ida->qcbs, M_DEVBUF); in ida_free()
107 if (ida->irq != NULL) in ida_free()
108 bus_release_resource(ida->dev, ida->irq_res_type, in ida_free()
109 0, ida->irq); in ida_free()
111 if (ida->parent_dmat != NULL) in ida_free()
112 bus_dma_tag_destroy(ida->parent_dmat); in ida_free()
114 if (ida->regs != NULL) in ida_free()
115 bus_release_resource(ida->dev, ida->regs_res_type, in ida_free()
116 ida->regs_res_id, ida->regs); in ida_free()
118 mtx_destroy(&ida->lock); in ida_free()
134 ida_get_qcb(struct ida_softc *ida) in ida_get_qcb() argument
138 if ((qcb = SLIST_FIRST(&ida->free_qcbs)) != NULL) { in ida_get_qcb()
139 SLIST_REMOVE_HEAD(&ida->free_qcbs, link.sle); in ida_get_qcb()
146 ida_free_qcb(struct ida_softc *ida, struct ida_qcb *qcb) in ida_free_qcb() argument
152 SLIST_INSERT_HEAD(&ida->free_qcbs, qcb, link.sle); in ida_free_qcb()
156 idahwqcbvtop(struct ida_softc *ida, struct ida_hardware_qcb *hwqcb) in idahwqcbvtop() argument
158 return (ida->hwqcb_busaddr + in idahwqcbvtop()
159 ((bus_addr_t)hwqcb - (bus_addr_t)ida->hwqcbs)); in idahwqcbvtop()
163 idahwqcbptov(struct ida_softc *ida, bus_addr_t hwqcb_addr) in idahwqcbptov() argument
168 ((bus_addr_t)ida->hwqcbs + (hwqcb_addr - ida->hwqcb_busaddr)); in idahwqcbptov()
173 ida_alloc_qcbs(struct ida_softc *ida) in ida_alloc_qcbs() argument
179 qcb = &ida->qcbs[i]; in ida_alloc_qcbs()
181 error = bus_dmamap_create(ida->buffer_dmat, /*flags*/0, &qcb->dmamap); in ida_alloc_qcbs()
185 qcb->ida = ida; in ida_alloc_qcbs()
187 qcb->hwqcb = &ida->hwqcbs[i]; in ida_alloc_qcbs()
189 qcb->hwqcb_busaddr = idahwqcbvtop(ida, qcb->hwqcb); in ida_alloc_qcbs()
190 SLIST_INSERT_HEAD(&ida->free_qcbs, qcb, link.sle); in ida_alloc_qcbs()
196 ida_setup(struct ida_softc *ida) in ida_setup() argument
202 SLIST_INIT(&ida->free_qcbs); in ida_setup()
203 STAILQ_INIT(&ida->qcb_queue); in ida_setup()
204 bioq_init(&ida->bio_queue); in ida_setup()
206 ida->qcbs = (struct ida_qcb *) in ida_setup()
209 if (ida->qcbs == NULL) in ida_setup()
218 /* parent */ ida->parent_dmat, in ida_setup()
231 &ida->hwqcb_dmat); in ida_setup()
237 /* parent */ ida->parent_dmat, in ida_setup()
249 /* lockarg */ &ida->lock, in ida_setup()
250 &ida->buffer_dmat); in ida_setup()
256 error = bus_dmamem_alloc(ida->hwqcb_dmat, in ida_setup()
257 (void **)&ida->hwqcbs, BUS_DMA_NOWAIT, &ida->hwqcb_dmamap); in ida_setup()
262 bus_dmamap_load(ida->hwqcb_dmat, ida->hwqcb_dmamap, in ida_setup()
263 ida->hwqcbs, IDA_QCB_MAX * sizeof(struct ida_hardware_qcb), in ida_setup()
264 ida_dma_map_cb, &ida->hwqcb_busaddr, /*flags*/0); in ida_setup()
266 bzero(ida->hwqcbs, IDA_QCB_MAX * sizeof(struct ida_hardware_qcb)); in ida_setup()
268 error = ida_alloc_qcbs(ida); in ida_setup()
272 mtx_lock(&ida->lock); in ida_setup()
273 ida->cmd.int_enable(ida, 0); in ida_setup()
275 error = ida_command(ida, CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo), in ida_setup()
278 mtx_unlock(&ida->lock); in ida_setup()
279 device_printf(ida->dev, "CMD_GET_CTRL_INFO failed.\n"); in ida_setup()
283 device_printf(ida->dev, "drives=%d firm_rev=%c%c%c%c\n", in ida_setup()
287 if (ida->flags & IDA_FIRMWARE) { in ida_setup()
290 error = ida_command(ida, CMD_START_FIRMWARE, in ida_setup()
293 mtx_unlock(&ida->lock); in ida_setup()
294 device_printf(ida->dev, "CMD_START_FIRMWARE failed.\n"); in ida_setup()
299 ida->cmd.int_enable(ida, 1); in ida_setup()
300 ida->flags |= IDA_ATTACHED; in ida_setup()
301 mtx_unlock(&ida->lock); in ida_setup()
304 child = device_add_child(ida->dev, /*"idad"*/NULL, DEVICE_UNIT_ANY); in ida_setup()
309 ida->ich.ich_func = ida_startup; in ida_setup()
310 ida->ich.ich_arg = ida; in ida_setup()
311 if (config_intrhook_establish(&ida->ich) != 0) { in ida_setup()
312 device_delete_children(ida->dev); in ida_setup()
313 device_printf(ida->dev, "Cannot establish configuration hook\n"); in ida_setup()
317 unit = device_get_unit(ida->dev); in ida_setup()
318 ida->ida_dev_t = make_dev(&ida_cdevsw, unit, in ida_setup()
321 ida->ida_dev_t->si_drv1 = ida; in ida_setup()
329 struct ida_softc *ida; in ida_startup() local
331 ida = arg; in ida_startup()
333 config_intrhook_disestablish(&ida->ich); in ida_startup()
336 bus_attach_children(ida->dev); in ida_startup()
343 struct ida_softc *ida; in ida_detach() local
346 ida = (struct ida_softc *)device_get_softc(dev); in ida_detach()
364 destroy_dev(ida->ida_dev_t); in ida_detach()
365 ida_free(ida); in ida_detach()
373 struct ida_softc *ida; in ida_data_cb() local
379 ida = qcb->ida; in ida_data_cb()
381 mtx_assert(&ida->lock, MA_OWNED); in ida_data_cb()
384 ida_done(ida, qcb); in ida_data_cb()
411 bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op); in ida_data_cb()
413 bus_dmamap_sync(ida->hwqcb_dmat, ida->hwqcb_dmamap, in ida_data_cb()
416 STAILQ_INSERT_TAIL(&ida->qcb_queue, qcb, link.stqe); in ida_data_cb()
417 ida_start(ida); in ida_data_cb()
418 ida->flags &= ~IDA_QFROZEN; in ida_data_cb()
422 ida_map_qcb(struct ida_softc *ida, struct ida_qcb *qcb, void *data, in ida_map_qcb() argument
427 if (ida->flags & IDA_INTERRUPTS) in ida_map_qcb()
431 error = bus_dmamap_load(ida->buffer_dmat, qcb->dmamap, data, datasize, in ida_map_qcb()
434 ida->flags |= IDA_QFROZEN; in ida_map_qcb()
441 ida_command(struct ida_softc *ida, int command, void *data, int datasize, in ida_command() argument
449 mtx_assert(&ida->lock, MA_OWNED); in ida_command()
450 qcb = ida_get_qcb(ida); in ida_command()
453 device_printf(ida->dev, "out of QCBs\n"); in ida_command()
464 error = ida_map_qcb(ida, qcb, data, datasize); in ida_command()
466 error = ida_wait(ida, qcb); in ida_command()
476 ida_free_qcb(ida, qcb); in ida_command()
481 ida_submit_buf(struct ida_softc *ida, struct bio *bp) in ida_submit_buf() argument
483 mtx_lock(&ida->lock); in ida_submit_buf()
484 bioq_insert_tail(&ida->bio_queue, bp); in ida_submit_buf()
485 ida_startio(ida); in ida_submit_buf()
486 mtx_unlock(&ida->lock); in ida_submit_buf()
490 ida_startio(struct ida_softc *ida) in ida_startio() argument
498 mtx_assert(&ida->lock, MA_OWNED); in ida_startio()
500 if (ida->flags & IDA_QFROZEN) in ida_startio()
502 bp = bioq_first(&ida->bio_queue); in ida_startio()
506 qcb = ida_get_qcb(ida); in ida_startio()
510 bioq_remove(&ida->bio_queue, bp); in ida_startio()
521 error = ida_map_qcb(ida, qcb, bp->bio_data, bp->bio_bcount); in ida_startio()
524 ida_done(ida, qcb); in ida_startio()
530 ida_start(struct ida_softc *ida) in ida_start() argument
535 mtx_assert(&ida->lock, MA_OWNED); in ida_start()
536 while ((qcb = STAILQ_FIRST(&ida->qcb_queue)) != NULL) { in ida_start()
537 if (ida->cmd.fifo_full(ida)) in ida_start()
539 STAILQ_REMOVE_HEAD(&ida->qcb_queue, link.stqe); in ida_start()
546 if (!ida->qactive && !dumping) in ida_start()
547 callout_reset(&ida->ch, hz * 5, ida_timeout, ida); in ida_start()
548 ida->qactive++; in ida_start()
551 ida->cmd.submit(ida, qcb); in ida_start()
556 ida_wait(struct ida_softc *ida, struct ida_qcb *qcb) in ida_wait() argument
563 mtx_assert(&ida->lock, MA_OWNED); in ida_wait()
564 if (ida->flags & IDA_INTERRUPTS) { in ida_wait()
565 if (mtx_sleep(qcb, &ida->lock, PRIBIO, "idacmd", 5 * hz)) { in ida_wait()
574 while ((completed = ida->cmd.done(ida)) == 0) { in ida_wait()
582 qcb_done = idahwqcbptov(ida, completed & ~3); in ida_wait()
585 ida_done(ida, qcb); in ida_wait()
592 struct ida_softc *ida; in ida_intr() local
596 ida = (struct ida_softc *)data; in ida_intr()
598 mtx_lock(&ida->lock); in ida_intr()
599 if (ida->cmd.int_pending(ida) == 0) { in ida_intr()
600 mtx_unlock(&ida->lock); in ida_intr()
604 while ((completed = ida->cmd.done(ida)) != 0) { in ida_intr()
605 qcb = idahwqcbptov(ida, completed & ~3); in ida_intr()
608 device_printf(ida->dev, in ida_intr()
615 ida_done(ida, qcb); in ida_intr()
617 ida_startio(ida); in ida_intr()
618 mtx_unlock(&ida->lock); in ida_intr()
625 ida_done(struct ida_softc *ida, struct ida_qcb *qcb) in ida_done() argument
634 mtx_assert(&ida->lock, MA_OWNED); in ida_done()
650 bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op); in ida_done()
651 bus_dmamap_unload(ida->buffer_dmat, qcb->dmamap); in ida_done()
654 bus_dmamap_sync(ida->hwqcb_dmat, ida->hwqcb_dmamap, in ida_done()
659 device_printf(ida->dev, "soft %s error\n", in ida_done()
663 device_printf(ida->dev, "soft error\n"); in ida_done()
668 device_printf(ida->dev, "hard %s error\n", in ida_done()
672 device_printf(ida->dev, "hard error\n"); in ida_done()
676 device_printf(ida->dev, "invalid request\n"); in ida_done()
680 device_printf(ida->dev, "request failed to map: %d\n", qcb->error); in ida_done()
684 if (ida->flags & IDA_INTERRUPTS) in ida_done()
687 ida_free_qcb(ida, qcb); in ida_done()
693 ida_free_qcb(ida, qcb); in ida_done()
699 ida->qactive--; in ida_done()
701 if (ida->qactive) in ida_done()
702 callout_reset(&ida->ch, hz * 5, ida_timeout, ida); in ida_done()
704 callout_stop(&ida->ch); in ida_done()
710 struct ida_softc *ida; in ida_timeout() local
712 ida = (struct ida_softc *)arg; in ida_timeout()
713 device_printf(ida->dev, "%s() qactive %d\n", __func__, ida->qactive); in ida_timeout()
715 if (ida->flags & IDA_INTERRUPTS) in ida_timeout()
716 device_printf(ida->dev, "IDA_INTERRUPTS\n"); in ida_timeout()
718 device_printf(ida->dev, "\t R_CMD_FIFO: %08x\n" in ida_timeout()
723 ida_inl(ida, R_CMD_FIFO), in ida_timeout()
724 ida_inl(ida, R_DONE_FIFO), in ida_timeout()
725 ida_inl(ida, R_INT_MASK), in ida_timeout()
726 ida_inl(ida, R_STATUS), in ida_timeout()
727 ida_inl(ida, R_INT_PENDING)); in ida_timeout()