--- //depot/vendor/freebsd/src/sys/dev/iir/iir.c +++ //depot/user/jhb/cleanup/sys/dev/iir/iir.c @@ -71,9 +71,6 @@ static MALLOC_DEFINE(M_GDTBUF, "iirbuf", "iir driver buffer"); -struct gdt_softc *gdt_wait_gdt; -int gdt_wait_index; - #ifdef GDT_DEBUG int gdt_debug = GDT_DEBUG; #ifdef __SERIAL__ @@ -135,13 +132,13 @@ #endif #endif -/* The linked list of softc structures */ -struct gdt_softc_list gdt_softcs = TAILQ_HEAD_INITIALIZER(gdt_softcs); /* controller cnt. */ int gdt_cnt = 0; /* event buffer */ static gdt_evt_str ebuffer[GDT_MAX_EVENTS]; static int elastidx, eoldidx; +static struct mtx elock; +MTX_SYSINIT(iir_elock, &elock, "iir events", MTX_DEF); /* statistics */ gdt_statist_t gdt_stat; @@ -150,6 +147,7 @@ #define ccb_priority spriv_field1 static void iir_action(struct cam_sim *sim, union ccb *ccb); +static int iir_intr_locked(struct gdt_softc *gdt); static void iir_poll(struct cam_sim *sim); static void iir_shutdown(void *arg, int howto); static void iir_timeout(void *arg); @@ -168,12 +166,12 @@ u_int8_t index, struct gdt_ccb *gccb); static int gdt_async_event(struct gdt_softc *gdt, int service); static struct gdt_ccb *gdt_raw_cmd(struct gdt_softc *gdt, - union ccb *ccb, int *lock); + union ccb *ccb); static struct gdt_ccb *gdt_cache_cmd(struct gdt_softc *gdt, - union ccb *ccb, int *lock); + union ccb *ccb); static struct gdt_ccb *gdt_ioctl_cmd(struct gdt_softc *gdt, - gdt_ucmd_t *ucmd, int *lock); -static void gdt_internal_cache_cmd(struct gdt_softc *gdt,union ccb *ccb); + gdt_ucmd_t *ucmd); +static void gdt_internal_cache_cmd(struct gdt_softc *gdt, union ccb *ccb); static void gdtmapmem(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error); @@ -197,7 +195,6 @@ SLIST_INIT(&gdt->sc_pending_gccb); TAILQ_INIT(&gdt->sc_ccb_queue); TAILQ_INIT(&gdt->sc_ucmd_queue); - TAILQ_INSERT_TAIL(&gdt_softcs, gdt, links); /* DMA tag for mapping buffers into device visible space. */ if (bus_dma_tag_create(gdt->sc_parent_dmat, /*alignment*/1, /*boundary*/0, @@ -207,10 +204,11 @@ /*maxsize*/MAXBSIZE, /*nsegments*/GDT_MAXSG, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/BUS_DMA_ALLOCNOW, - /*lockfunc*/busdma_lock_mutex, /*lockarg*/&Giant, + /*lockfunc*/busdma_lock_mutex, + /*lockarg*/&gdt->sc_lock, &gdt->sc_buffer_dmat) != 0) { - printf("iir%d: bus_dma_tag_create(...,gdt->sc_buffer_dmat) failed\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, + "bus_dma_tag_create(..., gdt->sc_buffer_dmat) failed\n"); return (1); } gdt->sc_init_level++; @@ -227,9 +225,10 @@ /*nsegments*/1, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, &gdt->sc_gcscratch_dmat) != 0) { - printf("iir%d: bus_dma_tag_create(...,gdt->sc_gcscratch_dmat) failed\n", - gdt->sc_hanum); + /*lockarg*/&gdt->sc_lock, + &gdt->sc_gcscratch_dmat) != 0) { + device_printf(gdt->sc_devnode, + "bus_dma_tag_create(...,gdt->sc_gcscratch_dmat) failed\n"); return (1); } gdt->sc_init_level++; @@ -237,8 +236,8 @@ /* Allocation for our ccb scratch area */ if (bus_dmamem_alloc(gdt->sc_gcscratch_dmat, (void **)&gdt->sc_gcscratch, BUS_DMA_NOWAIT, &gdt->sc_gcscratch_dmamap) != 0) { - printf("iir%d: bus_dmamem_alloc(...,&gdt->sc_gccbs,...) failed\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, + "bus_dmamem_alloc(...,&gdt->sc_gccbs,...) failed\n"); return (1); } gdt->sc_init_level++; @@ -256,7 +255,7 @@ gdt->sc_gccbs = malloc(sizeof(struct gdt_ccb) * GDT_MAXCMDS, M_GDTBUF, M_NOWAIT | M_ZERO); if (gdt->sc_gccbs == NULL) { - printf("iir%d: no memory for gccbs.\n", gdt->sc_hanum); + device_printf(gdt->sc_devnode, "no memory for gccbs.\n"); return (1); } for (i = GDT_MAXCMDS-1; i >= 0; i--) { @@ -270,28 +269,30 @@ gccb->gc_map_flag = TRUE; gccb->gc_scratch = &gdt->sc_gcscratch[GDT_SCRATCH_SZ * i]; gccb->gc_scratch_busbase = gdt->sc_gcscratch_busbase + GDT_SCRATCH_SZ * i; - callout_handle_init(&gccb->gc_timeout_ch); + callout_init_mtx(&gccb->gc_timeout, &gdt->sc_lock, 0); SLIST_INSERT_HEAD(&gdt->sc_free_gccb, gccb, sle); } gdt->sc_init_level++; /* create the control device */ - gdt->sc_dev = gdt_make_dev(gdt->sc_hanum); + gdt->sc_dev = gdt_make_dev(gdt); /* allocate ccb for gdt_internal_cmd() */ + mtx_lock(&gdt->sc_lock); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + mtx_unlock(&gdt->sc_lock); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } bzero(gccb->gc_cmd, GDT_CMD_SZ); if (!gdt_internal_cmd(gdt, gccb, GDT_SCREENSERVICE, GDT_INIT, 0, 0, 0)) { - printf("iir%d: Screen service initialization error %d\n", - gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, + "Screen service initialization error %d\n", gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } @@ -300,9 +301,10 @@ if (!gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_INIT, GDT_LINUX_OS, 0, 0)) { - printf("iir%d: Cache service initialization error %d\n", - gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, "Cache service initialization error %d\n", + gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } cdev_cnt = (u_int16_t)gdt->sc_info; @@ -332,9 +334,10 @@ GDT_IO_CHANNEL | GDT_INVALID_CHANNEL, GDT_GETCH_SZ)) { if (i == 0) { - printf("iir%d: Cannot get channel count, " - "error %d\n", gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, "Cannot get channel count, " + "error %d\n", gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } break; @@ -351,9 +354,10 @@ if (!gdt_internal_cmd(gdt, gccb, GDT_SCSIRAWSERVICE, GDT_INIT, 0, 0, 0)) { - printf("iir%d: Raw service initialization error %d\n", - gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, + "Raw service initialization error %d\n", gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } @@ -365,9 +369,11 @@ 0, 0, 0)) { gdt->sc_raw_feat = gdt->sc_info; if (!(gdt->sc_info & GDT_SCATTER_GATHER)) { - panic("iir%d: Scatter/Gather Raw Service " - "required but not supported!\n", gdt->sc_hanum); + panic("%s: Scatter/Gather Raw Service " + "required but not supported!\n", + device_get_nameunit(gdt->sc_devnode)); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } } @@ -381,9 +387,11 @@ 0, 0, 0)) { gdt->sc_cache_feat = gdt->sc_info; if (!(gdt->sc_info & GDT_SCATTER_GATHER)) { - panic("iir%d: Scatter/Gather Cache Service " - "required but not supported!\n", gdt->sc_hanum); + panic("%s: Scatter/Gather Cache Service " + "required but not supported!\n", + device_get_nameunit(gdt->sc_devnode)); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } } @@ -442,8 +450,9 @@ gdt->sc_bus_cnt, cdev_cnt, cdev_cnt == 1 ? "" : "s")); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); - gdt_cnt++; + atomic_add_int(&gdt_cnt, 1); return (0); } @@ -459,9 +468,11 @@ gdt_destroy_dev(gdt->sc_dev); case 5: for (i = GDT_MAXCMDS-1; i >= 0; i--) - if (gdt->sc_gccbs[i].gc_map_flag) + if (gdt->sc_gccbs[i].gc_map_flag) { + callout_drain(&gdt->sc_gccbs[i].gc_timeout); bus_dmamap_destroy(gdt->sc_buffer_dmat, gdt->sc_gccbs[i].gc_dmamap); + } bus_dmamap_unload(gdt->sc_gcscratch_dmat, gdt->sc_gcscratch_dmamap); free(gdt->sc_gccbs, M_GDTBUF); case 4: @@ -475,7 +486,6 @@ case 0: break; } - TAILQ_REMOVE(&gdt_softcs, gdt, links); } void @@ -499,11 +509,12 @@ * Construct our SIM entry */ gdt->sims[i] = cam_sim_alloc(iir_action, iir_poll, "iir", - gdt, gdt->sc_hanum, &Giant, - /*untagged*/1, - /*tagged*/GDT_MAXCMDS, devq); + gdt, device_get_unit(gdt->sc_devnode), &gdt->sc_lock, + /*untagged*/1, /*tagged*/GDT_MAXCMDS, devq); + mtx_lock(&gdt->sc_lock); if (xpt_bus_register(gdt->sims[i], gdt->sc_devnode, i) != CAM_SUCCESS) { cam_sim_free(gdt->sims[i], /*free_devq*/i == 0); + mtx_unlock(&gdt->sc_lock); break; } @@ -513,8 +524,10 @@ CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(gdt->sims[i])); cam_sim_free(gdt->sims[i], /*free_devq*/i == 0); + mtx_unlock(&gdt->sc_lock); break; } + mtx_unlock(&gdt->sc_lock); } if (i > 0) EVENTHANDLER_REGISTER(shutdown_final, iir_shutdown, @@ -556,9 +569,7 @@ gdt->sc_state |= GDT_POLL_WAIT; do { - iir_intr(gdt); - if (gdt == gdt_wait_gdt && - gccb->gc_cmd_index == gdt_wait_index) { + if (iir_intr_locked(gdt) == gccb->gc_cmd_index) { rv = 1; break; } @@ -642,11 +653,10 @@ gdt_get_ccb(struct gdt_softc *gdt) { struct gdt_ccb *gccb; - int lock; GDT_DPRINTF(GDT_D_QUEUE, ("gdt_get_ccb(%p)\n", gdt)); - lock = splcam(); + mtx_assert(&gdt->sc_lock, MA_OWNED); gccb = SLIST_FIRST(&gdt->sc_free_gccb); if (gccb != NULL) { SLIST_REMOVE_HEAD(&gdt->sc_free_gccb, sle); @@ -655,23 +665,20 @@ if (gdt_stat.cmd_index_act > gdt_stat.cmd_index_max) gdt_stat.cmd_index_max = gdt_stat.cmd_index_act; } - splx(lock); return (gccb); } void gdt_free_ccb(struct gdt_softc *gdt, struct gdt_ccb *gccb) { - int lock; GDT_DPRINTF(GDT_D_QUEUE, ("gdt_free_ccb(%p, %p)\n", gdt, gccb)); - - lock = splcam(); + + mtx_assert(&gdt->sc_lock, MA_OWNED); gccb->gc_flags = GDT_GCF_UNUSED; SLIST_REMOVE(&gdt->sc_pending_gccb, gccb, gdt_ccb, sle); SLIST_INSERT_HEAD(&gdt->sc_free_gccb, gccb, sle); --gdt_stat.cmd_index_act; - splx(lock); if (gdt->sc_state & GDT_SHUTDOWN) wakeup(gccb); } @@ -679,7 +686,6 @@ void gdt_next(struct gdt_softc *gdt) { - int lock; union ccb *ccb; gdt_ucmd_t *ucmd; struct cam_sim *sim; @@ -693,10 +699,9 @@ GDT_DPRINTF(GDT_D_QUEUE, ("gdt_next(%p)\n", gdt)); - lock = splcam(); + mtx_assert(&gdt->sc_lock, MA_OWNED); if (gdt->sc_test_busy(gdt)) { if (!(gdt->sc_state & GDT_POLLING)) { - splx(lock); return; } while (gdt->sc_test_busy(gdt)) @@ -715,7 +720,7 @@ ucmd = TAILQ_FIRST(&gdt->sc_ucmd_queue); if (ucmd != NULL) { TAILQ_REMOVE(&gdt->sc_ucmd_queue, ucmd, links); - if ((gccb = gdt_ioctl_cmd(gdt, ucmd, &lock)) == NULL) { + if ((gccb = gdt_ioctl_cmd(gdt, ucmd)) == NULL) { TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links); break; } @@ -746,7 +751,7 @@ xpt_done(ccb); } else if (bus != gdt->sc_virt_bus) { /* raw service command */ - if ((gccb = gdt_raw_cmd(gdt, ccb, &lock)) == NULL) { + if ((gccb = gdt_raw_cmd(gdt, ccb)) == NULL) { TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe); ++gdt_stat.req_queue_act; @@ -763,7 +768,7 @@ /* cache service command */ if (cmd == READ_6 || cmd == WRITE_6 || cmd == READ_10 || cmd == WRITE_10) { - if ((gccb = gdt_cache_cmd(gdt, ccb, &lock)) == NULL) { + if ((gccb = gdt_cache_cmd(gdt, ccb)) == NULL) { TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe); ++gdt_stat.req_queue_act; @@ -772,9 +777,7 @@ next_cmd = FALSE; } } else { - splx(lock); gdt_internal_cache_cmd(gdt, ccb); - lock = splcam(); } } if ((gdt->sc_state & GDT_POLLING) || !next_cmd) @@ -783,15 +786,13 @@ if (gdt->sc_cmd_cnt > 0) gdt->sc_release_event(gdt); - splx(lock); - if ((gdt->sc_state & GDT_POLLING) && gdt->sc_cmd_cnt > 0) { gdt_wait(gdt, gccb, GDT_POLL_TIMEOUT); } } static struct gdt_ccb * -gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) +gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb) { struct gdt_ccb *gccb; struct cam_sim *sim; @@ -802,15 +803,15 @@ if (roundup(GDT_CMD_UNION + GDT_RAW_SZ, sizeof(u_int32_t)) + gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET > gdt->sc_ic_all_size) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_raw_cmd(): DPMEM overflow\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: gdt_raw_cmd(): DPMEM overflow\n", + device_get_nameunit(gdt->sc_devnode))); return (NULL); } gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: No free command index found\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: No free command index found\n", + device_get_nameunit(gdt->sc_devnode))); return (gccb); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -821,7 +822,6 @@ if (gdt->sc_cmd_cnt == 0) gdt->sc_set_sema0(gdt); - splx(*lock); gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX, gccb->gc_cmd_index); gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_WRITE); @@ -856,12 +856,11 @@ gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ; } - *lock = splcam(); return (gccb); } static struct gdt_ccb * -gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) +gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb) { struct gdt_ccb *gccb; struct cam_sim *sim; @@ -875,15 +874,15 @@ if (roundup(GDT_CMD_UNION + GDT_CACHE_SZ, sizeof(u_int32_t)) + gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET > gdt->sc_ic_all_size) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_cache_cmd(): DPMEM overflow\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: gdt_cache_cmd(): DPMEM overflow\n", + device_get_nameunit(gdt->sc_devnode))); return (NULL); } gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_DEBUG, ("%s: No free command index found\n", + device_get_nameunit(gdt->sc_devnode))); return (gccb); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -894,7 +893,6 @@ if (gdt->sc_cmd_cnt == 0) gdt->sc_set_sema0(gdt); - splx(*lock); gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX, gccb->gc_cmd_index); cmdp = ccb->csio.cdb_io.cdb_bytes; @@ -928,12 +926,11 @@ xpt_freeze_simq(sim, 1); gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ; } - *lock = splcam(); return (gccb); } static struct gdt_ccb * -gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) +gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd) { struct gdt_ccb *gccb; u_int32_t cnt; @@ -942,8 +939,8 @@ gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_DEBUG, ("%s: No free command index found\n", + device_get_nameunit(gdt->sc_devnode))); return (gccb); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -958,8 +955,8 @@ sizeof(u_int32_t)); cnt = ucmd->u.ioctl.param_size; if (cnt > GDT_SCRATCH_SZ) { - printf("iir%d: Scratch buffer too small (%d/%d)\n", - gdt->sc_hanum, GDT_SCRATCH_SZ, cnt); + device_printf(gdt->sc_devnode, + "Scratch buffer too small (%d/%d)\n", GDT_SCRATCH_SZ, cnt); gdt_free_ccb(gdt, gccb); return (NULL); } @@ -968,8 +965,8 @@ GDT_SG_SZ, sizeof(u_int32_t)); cnt = ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE; if (cnt > GDT_SCRATCH_SZ) { - printf("iir%d: Scratch buffer too small (%d/%d)\n", - gdt->sc_hanum, GDT_SCRATCH_SZ, cnt); + device_printf(gdt->sc_devnode, + "Scratch buffer too small (%d/%d)\n", GDT_SCRATCH_SZ, cnt); gdt_free_ccb(gdt, gccb); return (NULL); } @@ -979,8 +976,8 @@ GDT_SG_SZ, sizeof(u_int32_t)); cnt = ucmd->u.raw.sdlen; if (cnt + ucmd->u.raw.sense_len > GDT_SCRATCH_SZ) { - printf("iir%d: Scratch buffer too small (%d/%d)\n", - gdt->sc_hanum, GDT_SCRATCH_SZ, cnt + ucmd->u.raw.sense_len); + device_printf(gdt->sc_devnode, "Scratch buffer too small (%d/%d)\n", + GDT_SCRATCH_SZ, cnt + ucmd->u.raw.sense_len); gdt_free_ccb(gdt, gccb); return (NULL); } @@ -990,15 +987,14 @@ if (gdt->sc_cmd_off + gccb->gc_cmd_len + GDT_DPMEM_COMMAND_OFFSET > gdt->sc_ic_all_size) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_ioctl_cmd(): DPMEM overflow\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: gdt_ioctl_cmd(): DPMEM overflow\n", + device_get_nameunit(gdt->sc_devnode))); gdt_free_ccb(gdt, gccb); return (NULL); } if (gdt->sc_cmd_cnt == 0) gdt->sc_set_sema0(gdt); - splx(*lock); /* fill cmd structure */ gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX, @@ -1064,7 +1060,6 @@ GDT_SG_LEN, ucmd->u.raw.sdlen); } - *lock = splcam(); gdt_stat.sg_count_act = 1; gdt->sc_copy_cmd(gdt, gccb); return (gccb); @@ -1181,13 +1176,12 @@ struct gdt_ccb *gccb; union ccb *ccb; struct gdt_softc *gdt; - int i, lock; + int i; - lock = splcam(); - gccb = (struct gdt_ccb *)arg; ccb = gccb->gc_ccb; gdt = cam_sim_softc((struct cam_sim *)ccb->ccb_h.ccb_sim_ptr); + mtx_assert(&gdt->sc_lock, MA_OWNED); GDT_DPRINTF(GDT_D_CMD, ("gdtexecuteccb(%p, %p, %p, %d, %d)\n", gdt, gccb, dm_segs, nseg, error)); @@ -1240,12 +1234,10 @@ ccb->ccb_h.status |= CAM_SIM_QUEUED; /* timeout handling */ - gccb->gc_timeout_ch = - timeout(iir_timeout, (caddr_t)gccb, - (ccb->ccb_h.timeout * hz) / 1000); + callout_reset(&gccb->gc_timeout, (ccb->ccb_h.timeout * hz) / 1000, + iir_timeout, gccb); gdt->sc_copy_cmd(gdt, gccb); - splx(lock); } @@ -1253,9 +1245,10 @@ iir_action( struct cam_sim *sim, union ccb *ccb ) { struct gdt_softc *gdt; - int lock, bus, target, lun; + int bus, target, lun; gdt = (struct gdt_softc *)cam_sim_softc( sim ); + mtx_assert(&gdt->sc_lock, MA_OWNED); ccb->ccb_h.ccb_sim_ptr = sim; bus = cam_sim_bus(sim); target = ccb->ccb_h.target_id; @@ -1270,12 +1263,10 @@ switch (ccb->ccb_h.func_code) { case XPT_SCSI_IO: - lock = splcam(); TAILQ_INSERT_TAIL(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe); ++gdt_stat.req_queue_act; if (gdt_stat.req_queue_act > gdt_stat.req_queue_max) gdt_stat.req_queue_max = gdt_stat.req_queue_act; - splx(lock); gdt_next(gdt); break; case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ @@ -1406,7 +1397,7 @@ gdt = (struct gdt_softc *)cam_sim_softc( sim ); GDT_DPRINTF(GDT_D_CMD, ("iir_poll sim %p gdt %p\n", sim, gdt)); - iir_intr(gdt); + iir_intr_locked(gdt); } static void @@ -1421,29 +1412,29 @@ struct gdt_softc *gdt; struct gdt_ccb *gccb; gdt_ucmd_t *ucmd; - int lock, i; + int i; gdt = (struct gdt_softc *)arg; GDT_DPRINTF(GDT_D_CMD, ("iir_shutdown(%p, %d)\n", gdt, howto)); - printf("iir%d: Flushing all Host Drives. Please wait ... ", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, + "Flushing all Host Drives. Please wait ... "); /* allocate ucmd buffer */ ucmd = malloc(sizeof(gdt_ucmd_t), M_GDTBUF, M_NOWAIT); if (ucmd == NULL) { - printf("iir%d: iir_shutdown(): Cannot allocate resource\n", - gdt->sc_hanum); + printf("\n"); + device_printf(gdt->sc_devnode, + "iir_shutdown(): Cannot allocate resource\n"); return; } bzero(ucmd, sizeof(gdt_ucmd_t)); /* wait for pending IOs */ - lock = splcam(); + mtx_lock(&gdt->sc_lock); gdt->sc_state = GDT_SHUTDOWN; - splx(lock); if ((gccb = SLIST_FIRST(&gdt->sc_pending_gccb)) != NULL) - (void) tsleep((void *)gccb, PCATCH | PRIBIO, "iirshw", 100 * hz); + mtx_sleep(gccb, &gdt->sc_lock, PCATCH | PRIBIO, "iirshw", 100 * hz); /* flush */ for (i = 0; i < GDT_MAX_HDRIVES; ++i) { @@ -1451,15 +1442,15 @@ ucmd->service = GDT_CACHESERVICE; ucmd->OpCode = GDT_FLUSH; ucmd->u.cache.DeviceNo = i; - lock = splcam(); TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links); ucmd->complete_flag = FALSE; - splx(lock); gdt_next(gdt); if (!ucmd->complete_flag) - (void) tsleep((void *)ucmd, PCATCH|PRIBIO, "iirshw", 10*hz); + mtx_sleep(ucmd, &gdt->sc_lock, PCATCH | PRIBIO, "iirshw", + 10 * hz); } } + mtx_unlock(&gdt->sc_lock); free(ucmd, M_DEVBUF); printf("Done.\n"); @@ -1469,29 +1460,33 @@ iir_intr(void *arg) { struct gdt_softc *gdt = arg; + + mtx_lock(&gdt->sc_lock); + iir_intr_locked(gdt); + mtx_unlock(&gdt->sc_lock); +} + +int +iir_intr_locked(struct gdt_softc *gdt) +{ struct gdt_intr_ctx ctx; - int lock = 0; struct gdt_ccb *gccb; gdt_ucmd_t *ucmd; u_int32_t cnt; GDT_DPRINTF(GDT_D_INTR, ("gdt_intr(%p)\n", gdt)); + mtx_assert(&gdt->sc_lock, MA_OWNED); + /* If polling and we were not called from gdt_wait, just return */ if ((gdt->sc_state & GDT_POLLING) && !(gdt->sc_state & GDT_POLL_WAIT)) - return; + return (0); - if (!(gdt->sc_state & GDT_POLLING)) - lock = splcam(); - gdt_wait_index = 0; - ctx.istatus = gdt->sc_get_status(gdt); if (ctx.istatus == 0x00) { - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); gdt->sc_status = GDT_S_NO_STATUS; - return; + return (ctx.istatus); } gdt->sc_intr(gdt, &ctx); @@ -1501,27 +1496,18 @@ gdt->sc_info = ctx.info; gdt->sc_info2 = ctx.info2; - if (gdt->sc_state & GDT_POLL_WAIT) { - gdt_wait_gdt = gdt; - gdt_wait_index = ctx.istatus; - } - if (ctx.istatus == GDT_ASYNCINDEX) { gdt_async_event(gdt, ctx.service); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); - return; + return (ctx.istatus); } if (ctx.istatus == GDT_SPEZINDEX) { GDT_DPRINTF(GDT_D_INVALID, - ("iir%d: Service unknown or not initialized!\n", - gdt->sc_hanum)); + ("%s: Service unknown or not initialized!\n", + device_get_nameunit(gdt->sc_devnode))); gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver); gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum; gdt_store_event(GDT_ES_DRIVER, 4, &gdt->sc_dvr); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); - return; + return (ctx.istatus); } gccb = &gdt->sc_gccbs[ctx.istatus - 2]; @@ -1529,18 +1515,16 @@ switch (gccb->gc_flags) { case GDT_GCF_UNUSED: - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: Index (%d) to unused command!\n", - gdt->sc_hanum, ctx.istatus)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: Index (%d) to unused command!\n", + device_get_nameunit(gdt->sc_devnode), ctx.istatus)); gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver); gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum; gdt->sc_dvr.eu.driver.index = ctx.istatus; gdt_store_event(GDT_ES_DRIVER, 1, &gdt->sc_dvr); gdt_free_ccb(gdt, gccb); - /* fallthrough */ + break; case GDT_GCF_INTERNAL: - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); break; case GDT_GCF_IOCTL: @@ -1549,8 +1533,6 @@ GDT_DPRINTF(GDT_D_DEBUG, ("iir_intr(%p) ioctl: gccb %p busy\n", gdt, gccb)); TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); } else { ucmd->status = gdt->sc_status; ucmd->info = gdt->sc_info; @@ -1573,8 +1555,6 @@ bcopy(gccb->gc_scratch, ucmd->data, cnt); } gdt_free_ccb(gdt, gccb); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); /* wakeup */ wakeup(ucmd); } @@ -1584,11 +1564,11 @@ default: gdt_free_ccb(gdt, gccb); gdt_sync_event(gdt, ctx.service, ctx.istatus, gccb); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); gdt_next(gdt); break; } + + return (ctx.istatus); } int @@ -1604,8 +1584,7 @@ DELAY(1); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -1624,8 +1603,8 @@ sizeof(u_int32_t)); gdt->sc_cmd_cnt = 0; gdt->sc_copy_cmd(gdt, gccb); - printf("iir%d: [PCI %d/%d] ", - gdt->sc_hanum,gdt->sc_bus,gdt->sc_slot); + device_printf(gdt->sc_devnode, "[PCI %d/%d] ", gdt->sc_bus, + gdt->sc_slot); gdt->sc_release_event(gdt); } @@ -1644,7 +1623,7 @@ *(u_int32_t *)gdt->sc_dvr.eu.async.scsi_coord = gdt->sc_info2; } gdt_store_event(GDT_ES_ASYNC, service, &gdt->sc_dvr); - printf("iir%d: %s\n", gdt->sc_hanum, gdt->sc_dvr.event_string); + device_printf(gdt->sc_devnode, "%s\n", gdt->sc_dvr.event_string); } return (0); @@ -1679,8 +1658,7 @@ bzero(gccb->gc_cmd, GDT_CMD_SZ); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } gccb->gc_service = service; @@ -1723,8 +1701,7 @@ bzero(gccb->gc_cmd, GDT_CMD_SZ); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } gccb->gc_service = service; @@ -1748,7 +1725,7 @@ printf("\n"); return (0); } else { - untimeout(iir_timeout, gccb, gccb->gc_timeout_ch); + callout_stop(&gccb->gc_timeout); if (gdt->sc_status == GDT_S_BSY) { GDT_DPRINTF(GDT_D_DEBUG, ("gdt_sync_event(%p) gccb %p busy\n", gdt, gccb)); @@ -1816,7 +1793,7 @@ } /* Controller event handling functions */ -gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx, +void gdt_store_event(u_int16_t source, u_int16_t idx, gdt_evt_data *evt) { gdt_evt_str *e; @@ -1824,8 +1801,9 @@ GDT_DPRINTF(GDT_D_MISC, ("gdt_store_event(%d, %d)\n", source, idx)); if (source == 0) /* no source -> no event */ - return 0; + return; + mtx_lock(&elock); if (ebuffer[elastidx].event_source == source && ebuffer[elastidx].event_idx == idx && ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 && @@ -1858,16 +1836,16 @@ e->event_data = *evt; e->application = 0; } - return e; + mtx_unlock(&elock); } int gdt_read_event(int handle, gdt_evt_str *estr) { gdt_evt_str *e; - int eindex, lock; + int eindex; GDT_DPRINTF(GDT_D_MISC, ("gdt_read_event(%d)\n", handle)); - lock = splcam(); + mtx_lock(&elock); if (handle == -1) eindex = eoldidx; else @@ -1875,7 +1853,7 @@ estr->event_source = 0; if (eindex >= GDT_MAX_EVENTS) { - splx(lock); + mtx_unlock(&elock); return eindex; } e = &ebuffer[eindex]; @@ -1888,7 +1866,7 @@ } memcpy(estr, e, sizeof(gdt_evt_str)); } - splx(lock); + mtx_unlock(&elock); return eindex; } @@ -1896,10 +1874,10 @@ { gdt_evt_str *e; int found = FALSE; - int eindex, lock; + int eindex; GDT_DPRINTF(GDT_D_MISC, ("gdt_readapp_event(%d)\n", application)); - lock = splcam(); + mtx_lock(&elock); eindex = eoldidx; for (;;) { e = &ebuffer[eindex]; @@ -1919,13 +1897,15 @@ memcpy(estr, e, sizeof(gdt_evt_str)); else estr->event_source = 0; - splx(lock); + mtx_unlock(&elock); } void gdt_clear_events() { GDT_DPRINTF(GDT_D_MISC, ("gdt_clear_events\n")); + mtx_lock(&elock); eoldidx = elastidx = 0; ebuffer[0].event_source = 0; + mtx_unlock(&elock); } --- //depot/vendor/freebsd/src/sys/dev/iir/iir.h +++ //depot/user/jhb/cleanup/sys/dev/iir/iir.h @@ -591,6 +591,7 @@ /* softc structure */ struct gdt_softc { device_t sc_devnode; + struct mtx sc_lock; int sc_hanum; int sc_class; /* Controller class */ #define GDT_MPR 0x05 @@ -608,9 +609,7 @@ #define GDT_SHUTDOWN 0x02 #define GDT_POLL_WAIT 0x80 struct cdev *sc_dev; - bus_space_tag_t sc_dpmemt; - bus_space_handle_t sc_dpmemh; - bus_addr_t sc_dpmembase; + struct resource *sc_dpmem; bus_dma_tag_t sc_parent_dmat; bus_dma_tag_t sc_buffer_dmat; bus_dma_tag_t sc_gcscratch_dmat; @@ -684,9 +683,8 @@ union ccb *gc_ccb; gdt_ucmd_t *gc_ucmd; bus_dmamap_t gc_dmamap; - struct callout_handle gc_timeout_ch; + struct callout gc_timeout; int gc_map_flag; - int gc_timeout; u_int8_t gc_service; u_int8_t gc_cmd_index; u_int8_t gc_flags; @@ -738,15 +736,14 @@ } #endif -extern TAILQ_HEAD(gdt_softc_list, gdt_softc) gdt_softcs; extern u_int8_t gdt_polling; -struct cdev *gdt_make_dev(int unit); +struct cdev *gdt_make_dev(struct gdt_softc *gdt); void gdt_destroy_dev(struct cdev *dev); void gdt_next(struct gdt_softc *gdt); void gdt_free_ccb(struct gdt_softc *gdt, struct gdt_ccb *gccb); -gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx, +void gdt_store_event(u_int16_t source, u_int16_t idx, gdt_evt_data *evt); int gdt_read_event(int handle, gdt_evt_str *estr); void gdt_readapp_event(u_int8_t app, gdt_evt_str *estr); --- //depot/vendor/freebsd/src/sys/dev/iir/iir_ctrl.c +++ //depot/user/jhb/cleanup/sys/dev/iir/iir_ctrl.c @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -52,12 +53,13 @@ #include #include #include +#include #include #include /* Entry points and other prototypes */ -static struct gdt_softc *gdt_minor2softc(int minor_no); +static struct gdt_softc *gdt_minor2softc(struct cdev *dev, int minor_no); static d_open_t iir_open; static d_close_t iir_close; @@ -68,7 +70,6 @@ /* Normally, this is a static structure. But we need it in pci/iir_pci.c */ static struct cdevsw iir_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = iir_open, .d_close = iir_close, .d_read = iir_read, @@ -77,11 +78,10 @@ .d_name = "iir", }; -/* -static int iir_devsw_installed = 0; -*/ #ifndef SDEV_PER_HBA static int sdev_made = 0; +static struct sx sdev_lock; +SX_SYSINIT(iir_sdev_lock, &sdev_lock, "iir sdev"); #endif extern int gdt_cnt; extern gdt_statist_t gdt_stat; @@ -91,19 +91,22 @@ * make a special device and return the dev_t */ struct cdev * -gdt_make_dev(int unit) +gdt_make_dev(struct gdt_softc *gdt) { struct cdev *dev; #ifdef SDEV_PER_HBA - dev = make_dev(&iir_cdevsw, hba2minor(unit), UID_ROOT, GID_OPERATOR, + dev = make_dev(&iir_cdevsw, 0, UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "iir%d", unit); + dev->si_drv1 = gdt; #else + sx_xlock(&sdev_lock); if (sdev_made) - return (0); + return (NULL); dev = make_dev(&iir_cdevsw, 0, UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "iir"); sdev_made = 1; + sx_xunlock(&sdev_lock); #endif return (dev); } @@ -120,22 +123,23 @@ * return the pointer to its softc structure */ static struct gdt_softc * -gdt_minor2softc(int minor_no) +gdt_minor2softc(struct cdev *dev, int minor_no) { - struct gdt_softc *gdt; - int hanum; +#ifdef SDEV_PER_HBA -#ifdef SDEV_PER_HBA - hanum = minor2hba(minor_no); + return (dev->si_drv1); #else - hanum = minor_no; + devclass_t dc; + device_t child; + + dc = devclass_find("iir"); + if (dc == NULL) + return (NULL); + child = devclass_get_device(dc, minor_no); + if (child == NULL) + return (NULL); + return (device_get_softc(child)); #endif - - for (gdt = TAILQ_FIRST(&gdt_softcs); - gdt != NULL && gdt->sc_hanum != hanum; - gdt = TAILQ_NEXT(gdt, links)); - - return (gdt); } static int @@ -143,16 +147,6 @@ { GDT_DPRINTF(GDT_D_DEBUG, ("iir_open()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -161,16 +155,6 @@ { GDT_DPRINTF(GDT_D_DEBUG, ("iir_close()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -179,16 +163,6 @@ { GDT_DPRINTF(GDT_D_DEBUG, ("iir_write()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -197,16 +171,6 @@ { GDT_DPRINTF(GDT_D_DEBUG, ("iir_read()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -221,15 +185,6 @@ { GDT_DPRINTF(GDT_D_DEBUG, ("iir_ioctl() cmd 0x%lx\n",cmd)); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif ++gdt_stat.io_count_act; if (gdt_stat.io_count_act > gdt_stat.io_count_max) gdt_stat.io_count_max = gdt_stat.io_count_act; @@ -239,19 +194,19 @@ { gdt_ucmd_t *ucmd; struct gdt_softc *gdt; - int lock; ucmd = (gdt_ucmd_t *)cmdarg; - gdt = gdt_minor2softc(ucmd->io_node); + gdt = gdt_minor2softc(dev, ucmd->io_node); if (gdt == NULL) return (ENXIO); - lock = splcam(); + mtx_lock(&gdt->sc_lock); TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links); ucmd->complete_flag = FALSE; - splx(lock); gdt_next(gdt); if (!ucmd->complete_flag) - (void) tsleep((void *)ucmd, PCATCH | PRIBIO, "iirucw", 0); + (void) mtx_sleep(ucmd, &gdt->sc_lock, PCATCH | PRIBIO, "iirucw", + 0); + mtx_unlock(&gdt->sc_lock); break; } @@ -268,7 +223,7 @@ struct gdt_softc *gdt; p = (gdt_ctrt_t *)cmdarg; - gdt = gdt_minor2softc(p->io_node); + gdt = gdt_minor2softc(dev, p->io_node); if (gdt == NULL) return (ENXIO); /* only RP controllers */ @@ -298,15 +253,9 @@ p = (gdt_osv_t *)cmdarg; p->oscode = 10; - p->version = osrelease[0] - '0'; - if (osrelease[1] == '.') - p->subversion = osrelease[2] - '0'; - else - p->subversion = 0; - if (osrelease[3] == '.') - p->revision = osrelease[4] - '0'; - else - p->revision = 0; + p->version = osreldate / 100000; + p->subversion = osreldate / 1000 % 100; + p->revision = 0; strcpy(p->name, ostype); break; } @@ -318,7 +267,6 @@ case GDT_IOCTL_EVENT: { gdt_event_t *p; - int lock; p = (gdt_event_t *)cmdarg; if (p->erase == 0xff) { @@ -330,14 +278,10 @@ p->dvr.event_data.size = sizeof(p->dvr.event_data.eu.sync); else p->dvr.event_data.size = sizeof(p->dvr.event_data.eu.async); - lock = splcam(); gdt_store_event(p->dvr.event_source, p->dvr.event_idx, &p->dvr.event_data); - splx(lock); } else if (p->erase == 0xfe) { - lock = splcam(); gdt_clear_events(); - splx(lock); } else if (p->erase == 0) { p->handle = gdt_read_event(p->handle, &p->dvr); } else { @@ -362,18 +306,3 @@ --gdt_stat.io_count_act; return (0); } - -/* -static void -iir_drvinit(void *unused) -{ - GDT_DPRINTF(GDT_D_DEBUG, ("iir_drvinit()\n")); - - if (!iir_devsw_installed) { - cdevsw_add(&iir_cdevsw); - iir_devsw_installed = 1; - } -} - -SYSINIT(iir_dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, iir_drvinit, NULL) -*/ --- //depot/vendor/freebsd/src/sys/dev/iir/iir_pci.c +++ //depot/user/jhb/cleanup/sys/dev/iir/iir_pci.c @@ -183,15 +183,18 @@ iir_pci_attach(device_t dev) { struct gdt_softc *gdt; - struct resource *io = NULL, *irq = NULL; + struct resource *irq = NULL; int retries, rid, error = 0; void *ih; u_int8_t protocol; - + + gdt = device_get_softc(dev); + mtx_init(&gdt->sc_lock, "iir", NULL, MTX_DEF); + /* map DPMEM */ rid = PCI_DPMEM; - io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (io == NULL) { + gdt->sc_dpmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (gdt->sc_dpmem == NULL) { device_printf(dev, "can't allocate register resources\n"); error = ENOMEM; goto err; @@ -207,12 +210,8 @@ goto err; } - gdt = device_get_softc(dev); gdt->sc_devnode = dev; gdt->sc_init_level = 0; - gdt->sc_dpmemt = rman_get_bustag(io); - gdt->sc_dpmemh = rman_get_bushandle(io); - gdt->sc_dpmembase = rman_get_start(io); gdt->sc_hanum = device_get_unit(dev); gdt->sc_bus = pci_get_bus(dev); gdt->sc_slot = pci_get_slot(dev); @@ -227,85 +226,70 @@ /* initialize RP controller */ /* check and reset interface area */ - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC, - htole32(GDT_MPR_MAGIC)); - if (bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC) != - htole32(GDT_MPR_MAGIC)) { - printf("cannot access DPMEM at 0x%jx (shadowed?)\n", - (uintmax_t)gdt->sc_dpmembase); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC, htole32(GDT_MPR_MAGIC)); + if (bus_read_4(gdt->sc_dpmem, GDT_MPR_IC) != htole32(GDT_MPR_MAGIC)) { + device_printf(dev, "cannot access DPMEM at 0x%lx (shadowed?)\n", + rman_get_start(gdt->sc_dpmem)); error = ENXIO; goto err; } - bus_space_set_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_I960_SZ, htole32(0), - GDT_MPR_SZ >> 2); + bus_set_region_4(gdt->sc_dpmem, GDT_I960_SZ, htole32(0), GDT_MPR_SZ >> 2); /* Disable everything */ - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN, - bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_EDOOR_EN) | 4); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, - 0); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_CMD_INDEX, - 0); + bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN, + bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) | 4); + bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_CMD_INDEX, 0); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO, - htole32(gdt->sc_dpmembase)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, - 0xff); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, + htole32(rman_get_start(gdt->sc_dpmem))); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; - while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_STATUS) != 0xff) { + while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xff) { if (--retries == 0) { - printf("DEINIT failed\n"); + device_printf(dev, "DEINIT failed\n"); error = ENXIO; goto err; } DELAY(1); } - protocol = (uint8_t)le32toh(bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, - 0); + protocol = (uint8_t)le32toh(bus_read_4(gdt->sc_dpmem, + GDT_MPR_IC + GDT_S_INFO)); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); if (protocol != GDT_PROTOCOL_VERSION) { - printf("unsupported protocol %d\n", protocol); + device_printf(dev, "unsupported protocol %d\n", protocol); error = ENXIO; goto err; } - /* special commnd to controller BIOS */ - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO, - htole32(0)); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), htole32(0)); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), - htole32(1)); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), - htole32(0)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, - 0xfe); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); + /* special command to controller BIOS */ + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, htole32(0)); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), + htole32(0)); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), + htole32(1)); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), + htole32(0)); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xfe); + bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; - while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { + while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { if (--retries == 0) { - printf("initialization error\n"); + device_printf(dev, "initialization error\n"); error = ENXIO; goto err; } DELAY(1); } - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, - 0); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); gdt->sc_ic_all_size = GDT_MPR_SZ; @@ -326,7 +310,7 @@ /*nsegments*/GDT_MAXSG, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, &gdt->sc_parent_dmat) != 0) { + /*lockarg*/&gdt->sc_lock, &gdt->sc_parent_dmat) != 0) { error = ENXIO; goto err; } @@ -342,7 +326,7 @@ iir_attach(gdt); /* associate interrupt handler */ - if (bus_setup_intr( dev, irq, INTR_TYPE_CAM, + if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_MPSAFE, NULL, iir_intr, gdt, &ih )) { device_printf(dev, "Unable to register interrupt handler\n"); error = ENXIO; @@ -355,10 +339,11 @@ err: if (irq) bus_release_resource( dev, SYS_RES_IRQ, 0, irq ); -/* - if (io) - bus_release_resource( dev, SYS_RES_MEMORY, rid, io ); -*/ + + if (gdt->sc_dpmem) + bus_release_resource( dev, SYS_RES_MEMORY, rid, gdt->sc_dpmem ); + mtx_destroy(&gdt->sc_lock); + return (error); } @@ -371,11 +356,9 @@ switch(GDT_CLASS(gdt)) { case GDT_MPR: - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_EDOOR, 0xff); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN, - bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_EDOOR_EN) & ~4); + bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN, + bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) & ~4); break; } } @@ -396,15 +379,14 @@ gdt->sc_cmd_off += cp_count; - bus_space_write_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_DPR_CMD + dp_offset, - (u_int32_t *)gccb->gc_cmd, cp_count >> 2); - bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET, - htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset)); - bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID, - htole16(gccb->gc_service)); + bus_write_region_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_DPR_CMD + dp_offset, + (u_int32_t *)gccb->gc_cmd, cp_count >> 2); + bus_write_2(gdt->sc_dpmem, + GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET, + htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset)); + bus_write_2(gdt->sc_dpmem, + GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID, + htole16(gccb->gc_service)); } u_int8_t @@ -412,7 +394,7 @@ { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_get_status(%p) ", gdt)); - return bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR); + return bus_read_1(gdt->sc_dpmem, GDT_MPR_EDOOR); } void @@ -422,39 +404,32 @@ GDT_DPRINTF(GDT_D_INTR, ("gdt_mpr_intr(%p) ", gdt)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); if (ctx->istatus & 0x80) { /* error flag */ ctx->istatus &= ~0x80; - ctx->cmd_status = bus_space_read_2(gdt->sc_dpmemt, - gdt->sc_dpmemh, GDT_MPR_STATUS); + ctx->cmd_status = bus_read_2(gdt->sc_dpmem, GDT_MPR_STATUS); } else /* no error */ ctx->cmd_status = GDT_S_OK; - ctx->info = - bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_INFO); - ctx->service = - bus_space_read_2(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SERVICE); - ctx->info2 = - bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_INFO + sizeof (u_int32_t)); + ctx->info = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO); + ctx->service = bus_read_2(gdt->sc_dpmem, GDT_MPR_SERVICE); + ctx->info2 = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO + sizeof (u_int32_t)); /* event string */ if (ctx->istatus == GDT_ASYNCINDEX) { if (ctx->service != GDT_SCREENSERVICE && (gdt->sc_fw_vers & 0xff) >= 0x1a) { - gdt->sc_dvr.severity = - bus_space_read_1(gdt->sc_dpmemt,gdt->sc_dpmemh, GDT_SEVERITY); + gdt->sc_dvr.severity = bus_read_1(gdt->sc_dpmem, GDT_SEVERITY); for (i = 0; i < 256; ++i) { - gdt->sc_dvr.event_string[i] = - bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_EVT_BUF + i); + gdt->sc_dvr.event_string[i] = bus_read_1(gdt->sc_dpmem, + GDT_EVT_BUF + i); if (gdt->sc_dvr.event_string[i] == 0) break; } } } - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA1, 0); + bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA1, 0); } void @@ -462,7 +437,7 @@ { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_release_event(%p) ", gdt)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); + bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); } void @@ -470,7 +445,7 @@ { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_set_sema0(%p) ", gdt)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA0, 1); + bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA0, 1); } int @@ -478,6 +453,5 @@ { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_test_busy(%p) ", gdt)); - return (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_SEMA0) & 1); + return (bus_read_1(gdt->sc_dpmem, GDT_MPR_SEMA0) & 1); }