Lines Matching defs:ahb

28  * $FreeBSD: releng/11.0/sys/dev/ahb/ahb.c 298955 2016-05-03 03:41:25Z pfg $
55 #include <dev/ahb/ahbreg.h>
60 #define ahb_inb(ahb, port) \
61 bus_read_1((ahb)->res, port)
63 #define ahb_inl(ahb, port) \
64 bus_read_4((ahb)->res, port)
66 #define ahb_outb(ahb, port, value) \
67 bus_write_1((ahb)->res, port, value)
69 #define ahb_outl(ahb, port, value) \
70 bus_write_4((ahb)->res, port, value)
74 static void ahbfree(struct ahb_softc *ahb);
75 static int ahbreset(struct ahb_softc *ahb);
78 static int ahbxptattach(struct ahb_softc *ahb);
79 static void ahbhandleimmed(struct ahb_softc *ahb,
81 static void ahbcalcresid(struct ahb_softc *ahb,
83 static __inline void ahbdone(struct ahb_softc *ahb, u_int32_t mbox,
86 static void ahbintr_locked(struct ahb_softc *ahb);
94 static __inline struct ecb* ahbecbget(struct ahb_softc *ahb);
95 static __inline void ahbecbfree(struct ahb_softc* ahb,
97 static __inline u_int32_t ahbecbvtop(struct ahb_softc *ahb,
99 static __inline struct ecb* ahbecbptov(struct ahb_softc *ahb,
104 static __inline void ahbqueuembox(struct ahb_softc *ahb,
109 ahbecbget(struct ahb_softc *ahb)
114 mtx_assert(&ahb->lock, MA_OWNED);
115 if ((ecb = SLIST_FIRST(&ahb->free_ecbs)) != NULL)
116 SLIST_REMOVE_HEAD(&ahb->free_ecbs, links);
122 ahbecbfree(struct ahb_softc* ahb, struct ecb* ecb)
126 mtx_assert(&ahb->lock, MA_OWNED);
128 SLIST_INSERT_HEAD(&ahb->free_ecbs, ecb, links);
132 ahbecbvtop(struct ahb_softc *ahb, struct ecb *ecb)
134 return (ahb->ecb_physbase
135 + (u_int32_t)((caddr_t)ecb - (caddr_t)ahb->ecb_array));
139 ahbecbptov(struct ahb_softc *ahb, u_int32_t ecb_addr)
141 return (ahb->ecb_array
143 - (struct ecb*)(uintptr_t)ahb->ecb_physbase));
165 ahbqueuembox(struct ahb_softc *ahb, u_int32_t mboxval, u_int attn_code)
171 status = ahb_inb(ahb, HOSTSTAT);
179 device_get_nameunit(ahb->dev));
181 ahb_outl(ahb, MBOXOUT0, mboxval);
182 ahb_outb(ahb, ATTN, attn_code);
261 struct ahb_softc *ahb;
276 ahb = ahballoc(dev, io);
278 if (ahbreset(ahb) != 0)
306 /* lockarg */ &ahb->lock,
307 &ahb->buffer_dmat) != 0)
310 ahb->init_level++;
322 + sizeof(*ahb->ha_inq_data),
328 &ahb->ecb_dmat) != 0)
331 ahb->init_level++;
334 if (bus_dmamem_alloc(ahb->ecb_dmat, (void **)&ahb->ecb_array,
335 BUS_DMA_NOWAIT, &ahb->ecb_dmamap) != 0)
338 ahb->ha_inq_data = (struct ha_inquiry_data *)&ahb->ecb_array[AHB_NECB];
340 ahb->init_level++;
343 bus_dmamap_load(ahb->ecb_dmat, ahb->ecb_dmamap,
344 ahb->ecb_array, AHB_NSEG * sizeof(struct ecb),
345 ahbmapecbs, ahb, /*flags*/0);
347 ahb->init_level++;
350 bzero(ahb->ecb_array, (AHB_NECB * sizeof(struct ecb))
351 + sizeof(*ahb->ha_inq_data));
352 next_ecb = ahb->ecb_array;
353 while (ahb->num_ecbs < AHB_NECB) {
356 if (bus_dmamap_create(ahb->buffer_dmat, /*flags*/0,
359 callout_init_mtx(&next_ecb->timer, &ahb->lock, 0);
360 ecb_paddr = ahbecbvtop(ahb, next_ecb);
363 ahb->num_ecbs++;
364 ahbecbfree(ahb, next_ecb);
368 ahb->init_level++;
374 if (ahbxptattach(ahb))
379 NULL, ahbintr, ahb, &ih) != 0)
390 ahbfree(ahb);
400 struct ahb_softc *ahb;
402 ahb = device_get_softc(dev);
403 SLIST_INIT(&ahb->free_ecbs);
404 LIST_INIT(&ahb->pending_ccbs);
405 ahb->res = res;
406 ahb->disc_permitted = ~0;
407 ahb->tags_permitted = ~0;
408 ahb->dev = dev;
409 mtx_init(&ahb->lock, "ahb", NULL, MTX_DEF);
411 return (ahb);
415 ahbfree(struct ahb_softc *ahb)
417 switch (ahb->init_level) {
420 bus_dmamap_unload(ahb->ecb_dmat, ahb->ecb_dmamap);
422 bus_dmamem_free(ahb->ecb_dmat, ahb->ecb_array,
423 ahb->ecb_dmamap);
425 bus_dma_tag_destroy(ahb->ecb_dmat);
427 bus_dma_tag_destroy(ahb->buffer_dmat);
431 mtx_destroy(&ahb->lock);
438 ahbreset(struct ahb_softc *ahb)
443 if ((ahb_inb(ahb, PORTADDR) & PORTADDR_ENHANCED) == 0) {
448 ahb_outb(ahb, CONTROL, CNTRL_HARD_RST);
450 ahb_outb(ahb, CONTROL, 0);
453 if ((ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_BUSY) == 0)
461 if ((test = ahb_inb(ahb, MBOXIN0)) != 0) {
465 while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) {
466 ahb_outb(ahb, CONTROL, CNTRL_CLRINT);
475 struct ahb_softc* ahb;
477 ahb = (struct ahb_softc*)arg;
478 ahb->ecb_physbase = segs->ds_addr;
483 ahb->ha_inq_physbase = ahbecbvtop(ahb, &ahb->ecb_array[AHB_NECB]);
487 ahbxptattach(struct ahb_softc *ahb)
493 mtx_lock(&ahb->lock);
496 ahb->scsi_id = ahb_inb(ahb, SCSIDEF) & HSCSIID;
499 ahb->extended_trans = ahb_inb(ahb, RESV1) & EXTENDED_TRANS;
502 ecb = ahbecbget(ahb); /* Always succeeds - no outstanding commands */
505 ecb->hecb.data_ptr = ahb->ha_inq_physbase;
511 ahbqueuembox(ahb, ahbecbvtop(ahb, ecb),
512 ATTN_STARTECB|ahb->scsi_id);
516 ahbintr_locked(ahb);
520 ahb->num_ecbs = MIN(ahb->num_ecbs,
521 ahb->ha_inq_data->scsi_data.spc2_flags);
522 device_printf(ahb->dev,
524 ahb->ha_inq_data->scsi_data.product,
525 (ahb->ha_inq_data->scsi_data.flags & 0x4) ? "Differential"
527 ahb->ha_inq_data->scsi_data.revision,
528 ahb->scsi_id, ahb->num_ecbs);
531 ecb->hecb.sense_ptr = ahbsensepaddr(ahbecbvtop(ahb, ecb));
533 ahbecbfree(ahb, ecb);
538 devq = cam_simq_alloc(ahb->num_ecbs);
540 mtx_unlock(&ahb->lock);
547 ahb->sim = cam_sim_alloc(ahbaction, ahbpoll, "ahb", ahb,
548 device_get_unit(ahb->dev), &ahb->lock, 2, ahb->num_ecbs, devq);
549 if (ahb->sim == NULL) {
551 mtx_unlock(&ahb->lock);
555 if (xpt_bus_register(ahb->sim, ahb->dev, 0) != CAM_SUCCESS) {
556 cam_sim_free(ahb->sim, /*free_devq*/TRUE);
557 mtx_unlock(&ahb->lock);
561 if (xpt_create_path(&ahb->path, /*periph*/NULL,
562 cam_sim_path(ahb->sim), CAM_TARGET_WILDCARD,
564 xpt_bus_deregister(cam_sim_path(ahb->sim));
565 cam_sim_free(ahb->sim, /*free_devq*/TRUE);
566 mtx_unlock(&ahb->lock);
573 ahb_outb(ahb, INTDEF, ahb_inb(ahb, INTDEF) | INTEN);
574 mtx_unlock(&ahb->lock);
580 ahbhandleimmed(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat)
585 if (ahb->immed_cmd == 0) {
586 device_printf(ahb->dev, "Immediate Command complete with no "
593 ccb_h = LIST_FIRST(&ahb->pending_ccbs);
602 || target_id == ahb->scsi_id) {
606 bus_dmamap_unload(ahb->buffer_dmat,
608 if (pending_ecb == ahb->immed_ecb)
611 else if (target_id == ahb->scsi_id)
615 ahbecbfree(ahb, pending_ecb);
617 } else if (ahb->immed_ecb != NULL) {
625 if (ahb->immed_ecb != NULL) {
626 ahb->immed_ecb = NULL;
627 device_printf(ahb->dev, "No longer in timeout\n");
628 } else if (target_id == ahb->scsi_id)
629 device_printf(ahb->dev, "SCSI Bus Reset Delivered\n");
631 device_printf(ahb->dev,
634 ahb->immed_cmd = 0;
638 ahbcalcresid(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb)
687 ahbprocesserror(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb)
715 ahbcalcresid(ahb, ecb, ccb);
742 ahb->tags_permitted &= ~(0x01 << ccb->ccb_h.target_id);
762 device_printf(ahb->dev,
772 device_get_nameunit(ahb->dev), status->ha_status);
782 ahbdone(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat)
787 ecb = ahbecbptov(ahb, mbox);
805 bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op);
806 bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap);
813 ahbprocesserror(ahb, ecb, ccb);
815 ahbecbfree(ahb, ecb);
820 device_printf(ahb->dev, "Command 0%x Failed %x:%x:%x\n",
835 struct ahb_softc *ahb;
837 ahb = arg;
838 mtx_lock(&ahb->lock);
839 ahbintr_locked(ahb);
840 mtx_unlock(&ahb->lock);
844 ahbintr_locked(struct ahb_softc *ahb)
849 while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) {
853 intstat = ahb_inb(ahb, INTSTAT);
854 mbox = ahb_inl(ahb, MBOXIN0);
859 ahb_outb(ahb, CONTROL, CNTRL_CLRINT);
868 ahbdone(ahb, mbox, intstat);
871 if ((intstat & INTSTAT_TARGET_MASK) == ahb->scsi_id) {
873 xpt_print_path(ahb->path);
885 xpt_async(AC_BUS_RESET, ahb->path, NULL);
892 ahbhandleimmed(ahb, mbox, intstat);
905 struct ahb_softc *ahb;
910 ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr;
911 mtx_assert(&ahb->lock, MA_OWNED);
915 device_printf(ahb->dev,
922 ahbecbfree(ahb, ecb);
927 ecb_paddr = ahbecbvtop(ahb, ecb);
962 bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op);
975 bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap);
976 ahbecbfree(ahb, ecb);
983 LIST_INSERT_HEAD(&ahb->pending_ccbs, &ccb->ccb_h, sim_links.le);
986 ahbqueuembox(ahb, ecb_paddr, ATTN_STARTECB|ccb->ccb_h.target_id);
995 struct ahb_softc *ahb;
999 ahb = (struct ahb_softc *)cam_sim_softc(sim);
1000 mtx_assert(&ahb->lock, MA_OWNED);
1013 if ((ecb = ahbecbget(ahb)) == NULL) {
1023 ccb->ccb_h.ccb_ahb_ptr = ahb;
1050 ahbecbfree(ahb, ecb);
1060 ahb->buffer_dmat,
1070 xpt_freeze_simq(ahb->sim, 1);
1108 if ((ahb->disc_permitted & target_mask) != 0)
1110 if ((ahb->tags_permitted & target_mask) != 0)
1134 ahb->immed_cmd = IMMED_RESET;
1135 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id);
1137 for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) {
1145 cam_calc_geometry(&ccb->ccg, ahb->extended_trans);
1153 ahb->immed_cmd = IMMED_RESET;
1154 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id);
1156 for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--)
1178 cpi->initiator_id = ahb->scsi_id;
1216 struct ahb_softc *ahb;
1220 ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr;
1221 mtx_assert(&ahb->lock, MA_OWNED);
1245 xpt_freeze_simq(ahb->sim, /*count*/1);
1249 LIST_FOREACH(ccb_h, &ahb->pending_ccbs, sim_links.le) {
1257 ahb->immed_ecb = ecb;
1275 ahb->immed_cmd = IMMED_RESET;
1276 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id);
1286 ahb->immed_cmd = IMMED_RESET;
1287 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id);
1290 ahbreset(ahb);
1293 ahbhandleimmed(ahb, 0, ahb->scsi_id|INTSTAT_IMMED_OK);
1306 "ahb",
1313 DRIVER_MODULE(ahb, eisa, ahb_eisa_driver, ahb_devclass, 0, 0);
1314 MODULE_DEPEND(ahb, eisa, 1, 1, 1);
1315 MODULE_DEPEND(ahb, cam, 1, 1, 1);