Lines Matching refs:ida

32 __FBSDID("$FreeBSD: releng/10.3/sys/dev/ida/ida.c 281826 2015-04-21 11:27:50Z mav $");
56 #include <dev/ida/idareg.h>
57 #include <dev/ida/idavar.h>
58 #include <dev/ida/idaio.h>
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);
73 .d_name = "ida",
77 ida_free(struct ida_softc *ida)
81 if (ida->ih != NULL)
82 bus_teardown_intr(ida->dev, ida->irq, ida->ih);
84 mtx_lock(&ida->lock);
85 callout_stop(&ida->ch);
86 mtx_unlock(&ida->lock);
87 callout_drain(&ida->ch);
89 if (ida->buffer_dmat) {
91 bus_dmamap_destroy(ida->buffer_dmat, ida->qcbs[i].dmamap);
92 bus_dma_tag_destroy(ida->buffer_dmat);
95 if (ida->hwqcb_dmat) {
96 if (ida->hwqcb_busaddr)
97 bus_dmamap_unload(ida->hwqcb_dmat, ida->hwqcb_dmamap);
98 if (ida->hwqcbs)
99 bus_dmamem_free(ida->hwqcb_dmat, ida->hwqcbs,
100 ida->hwqcb_dmamap);
101 bus_dma_tag_destroy(ida->hwqcb_dmat);
104 if (ida->qcbs != NULL)
105 free(ida->qcbs, M_DEVBUF);
107 if (ida->irq != NULL)
108 bus_release_resource(ida->dev, ida->irq_res_type,
109 0, ida->irq);
111 if (ida->parent_dmat != NULL)
112 bus_dma_tag_destroy(ida->parent_dmat);
114 if (ida->regs != NULL)
115 bus_release_resource(ida->dev, ida->regs_res_type,
116 ida->regs_res_id, ida->regs);
118 mtx_destroy(&ida->lock);
134 ida_get_qcb(struct ida_softc *ida)
138 if ((qcb = SLIST_FIRST(&ida->free_qcbs)) != NULL) {
139 SLIST_REMOVE_HEAD(&ida->free_qcbs, link.sle);
146 ida_free_qcb(struct ida_softc *ida, struct ida_qcb *qcb)
152 SLIST_INSERT_HEAD(&ida->free_qcbs, qcb, link.sle);
156 idahwqcbvtop(struct ida_softc *ida, struct ida_hardware_qcb *hwqcb)
158 return (ida->hwqcb_busaddr +
159 ((bus_addr_t)hwqcb - (bus_addr_t)ida->hwqcbs));
163 idahwqcbptov(struct ida_softc *ida, bus_addr_t hwqcb_addr)
168 ((bus_addr_t)ida->hwqcbs + (hwqcb_addr - ida->hwqcb_busaddr));
173 ida_alloc_qcbs(struct ida_softc *ida)
179 qcb = &ida->qcbs[i];
181 error = bus_dmamap_create(ida->buffer_dmat, /*flags*/0, &qcb->dmamap);
185 qcb->ida = ida;
187 qcb->hwqcb = &ida->hwqcbs[i];
189 qcb->hwqcb_busaddr = idahwqcbvtop(ida, qcb->hwqcb);
190 SLIST_INSERT_HEAD(&ida->free_qcbs, qcb, link.sle);
196 ida_init(struct ida_softc *ida)
202 SLIST_INIT(&ida->free_qcbs);
203 STAILQ_INIT(&ida->qcb_queue);
204 bioq_init(&ida->bio_queue);
206 ida->qcbs = (struct ida_qcb *)
209 if (ida->qcbs == NULL)
218 /* parent */ ida->parent_dmat,
231 &ida->hwqcb_dmat);
237 /* parent */ ida->parent_dmat,
250 &ida->buffer_dmat);
256 error = bus_dmamem_alloc(ida->hwqcb_dmat,
257 (void **)&ida->hwqcbs, BUS_DMA_NOWAIT, &ida->hwqcb_dmamap);
262 bus_dmamap_load(ida->hwqcb_dmat, ida->hwqcb_dmamap,
263 ida->hwqcbs, IDA_QCB_MAX * sizeof(struct ida_hardware_qcb),
264 ida_dma_map_cb, &ida->hwqcb_busaddr, /*flags*/0);
266 bzero(ida->hwqcbs, IDA_QCB_MAX * sizeof(struct ida_hardware_qcb));
268 error = ida_alloc_qcbs(ida);
272 mtx_lock(&ida->lock);
273 ida->cmd.int_enable(ida, 0);
275 error = ida_command(ida, CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo),
278 mtx_unlock(&ida->lock);
279 device_printf(ida->dev, "CMD_GET_CTRL_INFO failed.\n");
283 device_printf(ida->dev, "drives=%d firm_rev=%c%c%c%c\n",
287 if (ida->flags & IDA_FIRMWARE) {
290 error = ida_command(ida, CMD_START_FIRMWARE,
293 mtx_unlock(&ida->lock);
294 device_printf(ida->dev, "CMD_START_FIRMWARE failed.\n");
299 ida->cmd.int_enable(ida, 1);
300 ida->flags |= IDA_ATTACHED;
301 mtx_unlock(&ida->lock);
304 child = device_add_child(ida->dev, /*"idad"*/NULL, -1);
309 ida->ich.ich_func = ida_startup;
310 ida->ich.ich_arg = ida;
311 if (config_intrhook_establish(&ida->ich) != 0) {
312 device_delete_children(ida->dev);
313 device_printf(ida->dev, "Cannot establish configuration hook\n");
317 unit = device_get_unit(ida->dev);
318 ida->ida_dev_t = make_dev(&ida_cdevsw, unit,
320 "ida%d", unit);
321 ida->ida_dev_t->si_drv1 = ida;
329 struct ida_softc *ida;
331 ida = arg;
333 config_intrhook_disestablish(&ida->ich);
336 bus_generic_attach(ida->dev);
343 struct ida_softc *ida;
346 ida = (struct ida_softc *)device_get_softc(dev);
367 destroy_dev(ida->ida_dev_t);
368 ida_free(ida);
376 struct ida_softc *ida;
382 ida = qcb->ida;
384 mtx_assert(&ida->lock, MA_OWNED);
387 ida_done(ida, qcb);
414 bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op);
416 bus_dmamap_sync(ida->hwqcb_dmat, ida->hwqcb_dmamap,
419 STAILQ_INSERT_TAIL(&ida->qcb_queue, qcb, link.stqe);
420 ida_start(ida);
421 ida->flags &= ~IDA_QFROZEN;
425 ida_map_qcb(struct ida_softc *ida, struct ida_qcb *qcb, void *data,
430 if (ida->flags & IDA_INTERRUPTS)
434 error = bus_dmamap_load(ida->buffer_dmat, qcb->dmamap, data, datasize,
437 ida->flags |= IDA_QFROZEN;
444 ida_command(struct ida_softc *ida, int command, void *data, int datasize,
452 mtx_assert(&ida->lock, MA_OWNED);
453 qcb = ida_get_qcb(ida);
456 device_printf(ida->dev, "out of QCBs\n");
467 error = ida_map_qcb(ida, qcb, data, datasize);
469 error = ida_wait(ida, qcb);
479 ida_free_qcb(ida, qcb);
484 ida_submit_buf(struct ida_softc *ida, struct bio *bp)
486 mtx_lock(&ida->lock);
487 bioq_insert_tail(&ida->bio_queue, bp);
488 ida_startio(ida);
489 mtx_unlock(&ida->lock);
493 ida_startio(struct ida_softc *ida)
501 mtx_assert(&ida->lock, MA_OWNED);
503 if (ida->flags & IDA_QFROZEN)
505 bp = bioq_first(&ida->bio_queue);
509 qcb = ida_get_qcb(ida);
513 bioq_remove(&ida->bio_queue, bp);
524 error = ida_map_qcb(ida, qcb, bp->bio_data, bp->bio_bcount);
527 ida_done(ida, qcb);
533 ida_start(struct ida_softc *ida)
538 mtx_assert(&ida->lock, MA_OWNED);
539 while ((qcb = STAILQ_FIRST(&ida->qcb_queue)) != NULL) {
540 if (ida->cmd.fifo_full(ida))
542 STAILQ_REMOVE_HEAD(&ida->qcb_queue, link.stqe);
549 if (!ida->qactive && !dumping)
550 callout_reset(&ida->ch, hz * 5, ida_timeout, ida);
551 ida->qactive++;
554 ida->cmd.submit(ida, qcb);
559 ida_wait(struct ida_softc *ida, struct ida_qcb *qcb)
566 mtx_assert(&ida->lock, MA_OWNED);
567 if (ida->flags & IDA_INTERRUPTS) {
568 if (mtx_sleep(qcb, &ida->lock, PRIBIO, "idacmd", 5 * hz)) {
577 while ((completed = ida->cmd.done(ida)) == 0) {
585 qcb_done = idahwqcbptov(ida, completed & ~3);
588 ida_done(ida, qcb);
595 struct ida_softc *ida;
599 ida = (struct ida_softc *)data;
601 mtx_lock(&ida->lock);
602 if (ida->cmd.int_pending(ida) == 0) {
603 mtx_unlock(&ida->lock);
607 while ((completed = ida->cmd.done(ida)) != 0) {
608 qcb = idahwqcbptov(ida, completed & ~3);
611 device_printf(ida->dev,
618 ida_done(ida, qcb);
620 ida_startio(ida);
621 mtx_unlock(&ida->lock);
628 ida_done(struct ida_softc *ida, struct ida_qcb *qcb)
637 mtx_assert(&ida->lock, MA_OWNED);
653 bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op);
654 bus_dmamap_unload(ida->buffer_dmat, qcb->dmamap);
657 bus_dmamap_sync(ida->hwqcb_dmat, ida->hwqcb_dmamap,
662 device_printf(ida->dev, "soft %s error\n",
666 device_printf(ida->dev, "soft error\n");
671 device_printf(ida->dev, "hard %s error\n",
675 device_printf(ida->dev, "hard error\n");
679 device_printf(ida->dev, "invalid request\n");
683 device_printf(ida->dev, "request failed to map: %d\n", qcb->error);
687 if (ida->flags & IDA_INTERRUPTS)
690 ida_free_qcb(ida, qcb);
696 ida_free_qcb(ida, qcb);
702 ida->qactive--;
704 if (ida->qactive)
705 callout_reset(&ida->ch, hz * 5, ida_timeout, ida);
707 callout_stop(&ida->ch);
713 struct ida_softc *ida;
715 ida = (struct ida_softc *)arg;
716 device_printf(ida->dev, "%s() qactive %d\n", __func__, ida->qactive);
718 if (ida->flags & IDA_INTERRUPTS)
719 device_printf(ida->dev, "IDA_INTERRUPTS\n");
721 device_printf(ida->dev, "\t R_CMD_FIFO: %08x\n"
726 ida_inl(ida, R_CMD_FIFO),
727 ida_inl(ida, R_DONE_FIFO),
728 ida_inl(ida, R_INT_MASK),
729 ida_inl(ida, R_STATUS),
730 ida_inl(ida, R_INT_PENDING));