Date: Mon, 15 Oct 2012 16:29:08 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r241593 - head/sys/dev/dpt Message-ID: <201210151629.q9FGT83s027406@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Mon Oct 15 16:29:08 2012 New Revision: 241593 URL: http://svn.freebsd.org/changeset/base/241593 Log: Add locking to the dpt(4) driver and mark it MPSAFE. - Use device_printf() and device_get_unit() instead of storing the unit number in the softc. - Remove use of explicit bus space handles and tags. - Remove the global dpt_softcs list and use devclass_get_device() instead. - Use pci_enable_busmaster() rather than frobbing the PCI command register directly. Tested by: no one Modified: head/sys/dev/dpt/dpt.h head/sys/dev/dpt/dpt_eisa.c head/sys/dev/dpt/dpt_isa.c head/sys/dev/dpt/dpt_pci.c head/sys/dev/dpt/dpt_scsi.c Modified: head/sys/dev/dpt/dpt.h ============================================================================== --- head/sys/dev/dpt/dpt.h Mon Oct 15 16:13:55 2012 (r241592) +++ head/sys/dev/dpt/dpt.h Mon Oct 15 16:29:08 2012 (r241593) @@ -876,6 +876,7 @@ typedef enum { typedef struct dpt_ccb { eata_ccb_t eata_ccb; bus_dmamap_t dmamap; + struct callout timer; dpt_sg_t *sg_list; u_int32_t sg_busaddr; dccb_state state; @@ -1017,6 +1018,7 @@ struct sg_map_node { /* Main state machine and interface structure */ typedef struct dpt_softc { device_t dev; + struct mtx lock; struct resource * io_res; int io_rid; @@ -1030,8 +1032,6 @@ typedef struct dpt_softc { struct resource * drq_res; int drq_rid; - bus_space_tag_t tag; - bus_space_handle_t bsh; bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ dpt_ccb_t *dpt_dccbs; /* Array of dpt ccbs */ bus_addr_t dpt_ccb_busbase; /* phys base address of array */ @@ -1079,7 +1079,6 @@ typedef struct dpt_softc { u_int8_t dma_channel; TAILQ_ENTRY(dpt_softc) links; - int unit; int init_level; /* @@ -1275,9 +1274,6 @@ dpt_time_delta(struct timeval start, (end.tv_usec - start.tv_usec) ); } -extern TAILQ_HEAD(dpt_softc_list, dpt_softc) dpt_softcs; - -extern int dpt_controllers_present; extern devclass_t dpt_devclass; #ifdef _KERNEL Modified: head/sys/dev/dpt/dpt_eisa.c ============================================================================== --- head/sys/dev/dpt/dpt_eisa.c Mon Oct 15 16:13:55 2012 (r241592) +++ head/sys/dev/dpt/dpt_eisa.c Mon Oct 15 16:29:08 2012 (r241593) @@ -105,11 +105,11 @@ static int dpt_eisa_attach (device_t dev) { dpt_softc_t * dpt; - int s; int error = 0; dpt = device_get_softc(dev); dpt->dev = dev; + dpt_alloc(dev); dpt->io_rid = 0; dpt->io_type = SYS_RES_IOPORT; @@ -120,11 +120,8 @@ dpt_eisa_attach (device_t dev) goto bad; } - dpt_alloc(dev); - /* Allocate a dmatag representing the capabilities of this attachment */ - /* XXX Should be a child of the EISA bus dma tag */ - if (bus_dma_tag_create( /* parent */ NULL, + if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), /* alignemnt */ 1, /* boundary */ 0, /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, @@ -135,17 +132,14 @@ dpt_eisa_attach (device_t dev) /* nsegments */ ~0, /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &dpt->parent_dmat) != 0) { error = ENXIO; goto bad; } - s = splcam(); - if (dpt_init(dpt) != 0) { - splx(s); error = ENXIO; goto bad; } @@ -153,10 +147,8 @@ dpt_eisa_attach (device_t dev) /* Register with the XPT */ dpt_attach(dpt); - splx(s); - - if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, dpt_intr, dpt, &dpt->ih)) { + if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) { device_printf(dev, "Unable to register interrupt handler\n"); error = ENXIO; goto bad; Modified: head/sys/dev/dpt/dpt_isa.c ============================================================================== --- head/sys/dev/dpt/dpt_isa.c Mon Oct 15 16:13:55 2012 (r241592) +++ head/sys/dev/dpt/dpt_isa.c Mon Oct 15 16:29:08 2012 (r241593) @@ -31,7 +31,9 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> @@ -150,11 +152,11 @@ static int dpt_isa_attach (device_t dev) { dpt_softc_t * dpt; - int s; int error = 0; dpt = device_get_softc(dev); dpt->dev = dev; + dpt_alloc(dev); dpt->io_rid = 0; dpt->io_type = SYS_RES_IOPORT; @@ -176,10 +178,8 @@ dpt_isa_attach (device_t dev) isa_dma_acquire(rman_get_start(dpt->drq_res)); isa_dmacascade(rman_get_start(dpt->drq_res)); - dpt_alloc(dev); - /* Allocate a dmatag representing the capabilities of this attachment */ - if (bus_dma_tag_create( /* parent */ NULL, + if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), /* alignemnt */ 1, /* boundary */ 0, /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, @@ -190,17 +190,14 @@ dpt_isa_attach (device_t dev) /* nsegments */ ~0, /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &dpt->parent_dmat) != 0) { error = ENXIO; goto bad; } - s = splcam(); - if (dpt_init(dpt) != 0) { - splx(s); error = ENXIO; goto bad; } @@ -208,10 +205,8 @@ dpt_isa_attach (device_t dev) /* Register with the XPT */ dpt_attach(dpt); - splx(s); - - if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - dpt_intr, dpt, &dpt->ih)) { + if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) { device_printf(dev, "Unable to register interrupt handler\n"); error = ENXIO; goto bad; Modified: head/sys/dev/dpt/dpt_pci.c ============================================================================== --- head/sys/dev/dpt/dpt_pci.c Mon Oct 15 16:13:55 2012 (r241592) +++ head/sys/dev/dpt/dpt_pci.c Mon Oct 15 16:29:08 2012 (r241593) @@ -75,13 +75,13 @@ static int dpt_pci_attach (device_t dev) { dpt_softc_t * dpt; - int s; int error = 0; u_int32_t command; dpt = device_get_softc(dev); dpt->dev = dev; + dpt_alloc(dev); command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1); @@ -117,8 +117,7 @@ dpt_pci_attach (device_t dev) } /* Ensure busmastering is enabled */ - command |= PCIM_CMD_BUSMASTEREN; - pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1); + pci_enable_busmaster(dev); if (rman_get_start(dpt->io_res) == (ISA_PRIMARY_WD_ADDRESS - 0x10)) { #ifdef DPT_DEBUG_WARN @@ -129,8 +128,6 @@ dpt_pci_attach (device_t dev) goto bad; } - dpt_alloc(dev); - /* Allocate a dmatag representing the capabilities of this attachment */ if (bus_dma_tag_create( /* PCI parent */ bus_get_dma_tag(dev), /* alignemnt */ 1, @@ -143,15 +140,13 @@ dpt_pci_attach (device_t dev) /* nsegments */ ~0, /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &dpt->parent_dmat) != 0) { error = ENXIO; goto bad; } - s = splcam(); - if (dpt_init(dpt) != 0) { error = ENXIO; goto bad; @@ -160,10 +155,8 @@ dpt_pci_attach (device_t dev) /* Register with the XPT */ dpt_attach(dpt); - splx(s); - - if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, dpt_intr, dpt, &dpt->ih)) { + if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) { device_printf(dev, "Unable to register interrupt handler\n"); error = ENXIO; goto bad; Modified: head/sys/dev/dpt/dpt_scsi.c ============================================================================== --- head/sys/dev/dpt/dpt_scsi.c Mon Oct 15 16:13:55 2012 (r241592) +++ head/sys/dev/dpt/dpt_scsi.c Mon Oct 15 16:29:08 2012 (r241593) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> +#include <sys/conf.h> #include <sys/eventhandler.h> #include <sys/malloc.h> #include <sys/kernel.h> @@ -79,19 +80,18 @@ __FBSDID("$FreeBSD$"); #include <dev/dpt/dpt.h> /* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */ -int dpt_controllers_present; devclass_t dpt_devclass; #define microtime_now dpt_time_now() #define dpt_inl(dpt, port) \ - bus_space_read_4((dpt)->tag, (dpt)->bsh, port) + bus_read_4((dpt)->io_res, (dpt)->io_offset + port) #define dpt_inb(dpt, port) \ - bus_space_read_1((dpt)->tag, (dpt)->bsh, port) + bus_read_1((dpt)->io_res, (dpt)->io_offset + port) #define dpt_outl(dpt, port, value) \ - bus_space_write_4((dpt)->tag, (dpt)->bsh, port, value) + bus_write_4((dpt)->io_res, (dpt)->io_offset + port, value) #define dpt_outb(dpt, port, value) \ - bus_space_write_1((dpt)->tag, (dpt)->bsh, port, value) + bus_write_1((dpt)->io_res, (dpt)->io_offset + port, value) /* * These will have to be setup by parameters passed at boot/load time. For @@ -142,6 +142,7 @@ static void dpt_detect_cache(dpt_softc_ u_int8_t *buff); static void dpt_poll(struct cam_sim *sim); +static void dpt_intr_locked(dpt_softc_t *dpt); static void dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error); @@ -222,9 +223,9 @@ static __inline struct dpt_ccb* dptgetccb(struct dpt_softc *dpt) { struct dpt_ccb* dccb; - int s; - s = splcam(); + if (!dumping) + mtx_assert(&dpt->lock, MA_OWNED); if ((dccb = SLIST_FIRST(&dpt->free_dccb_list)) != NULL) { SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links); dpt->free_dccbs--; @@ -232,13 +233,12 @@ dptgetccb(struct dpt_softc *dpt) dptallocccbs(dpt); dccb = SLIST_FIRST(&dpt->free_dccb_list); if (dccb == NULL) - printf("dpt%d: Can't malloc DCCB\n", dpt->unit); + device_printf(dpt->dev, "Can't malloc DCCB\n"); else { SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links); dpt->free_dccbs--; } } - splx(s); return (dccb); } @@ -246,9 +246,9 @@ dptgetccb(struct dpt_softc *dpt) static __inline void dptfreeccb(struct dpt_softc *dpt, struct dpt_ccb *dccb) { - int s; - s = splcam(); + if (!dumping) + mtx_assert(&dpt->lock, MA_OWNED); if ((dccb->state & DCCB_ACTIVE) != 0) LIST_REMOVE(&dccb->ccb->ccb_h, sim_links.le); if ((dccb->state & DCCB_RELEASE_SIMQ) != 0) @@ -261,7 +261,6 @@ dptfreeccb(struct dpt_softc *dpt, struct dccb->state = DCCB_FREE; SLIST_INSERT_HEAD(&dpt->free_dccb_list, dccb, links); ++dpt->free_dccbs; - splx(s); } static __inline bus_addr_t @@ -332,7 +331,6 @@ dptallocsgmap(struct dpt_softc *dpt) /* * Allocate another chunk of CCB's. Return count of entries added. - * Assumed to be called at splcam(). */ static int dptallocccbs(dpt_softc_t *dpt) @@ -344,6 +342,8 @@ dptallocccbs(dpt_softc_t *dpt) int newcount; int i; + if (!dumping) + mtx_assert(&dpt->lock, MA_OWNED); next_ccb = &dpt->dpt_dccbs[dpt->total_dccbs]; if (next_ccb == dpt->dpt_dccbs) { @@ -371,6 +371,7 @@ dptallocccbs(dpt_softc_t *dpt) &next_ccb->dmamap); if (error != 0) break; + callout_init_mtx(&next_ccb->timer, &dpt->lock, 0); next_ccb->sg_list = segs; next_ccb->sg_busaddr = htonl(physaddr); next_ccb->eata_ccb.cp_dataDMA = htonl(physaddr); @@ -404,7 +405,7 @@ dpt_pio_get_conf (u_int32_t base) */ if (!conf) { conf = (dpt_conf_t *)malloc(sizeof(dpt_conf_t), - M_DEVBUF, M_NOWAIT); + M_DEVBUF, M_NOWAIT | M_ZERO); } /* @@ -416,11 +417,6 @@ dpt_pio_get_conf (u_int32_t base) } /* - * If we have one, clean it up. - */ - bzero(conf, sizeof(dpt_conf_t)); - - /* * Reset the controller. */ outb((base + HA_WCOMMAND), EATA_CMD_RESET); @@ -498,9 +494,9 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t u_int8_t status; int ndx; - int ospl; int result; + mtx_assert(&dpt->lock, MA_OWNED); cp = &dccb->eata_ccb; bzero((void *)(uintptr_t)(volatile void *)dpt->sp, sizeof(*dpt->sp)); @@ -523,8 +519,6 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t cp->cp_identify = 1; cp->cp_datalen = htonl(size); - ospl = splcam(); - /* * This could be a simple for loop, but we suspected the compiler To * have optimized it a bit too much. Wait for the controller to @@ -540,9 +534,8 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t * the DPT controller is in a NON PC (PCI?) platform). */ if (dpt_raid_busy(dpt)) { - printf("dpt%d WARNING: Get_conf() RSUS failed.\n", - dpt->unit); - splx(ospl); + device_printf(dpt->dev, + "WARNING: Get_conf() RSUS failed.\n"); return (0); } } @@ -557,10 +550,10 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t if ((result = dpt_send_eata_command(dpt, cp, dccb_busaddr, EATA_CMD_DMA_SEND_CP, 10000, 0, 0, 0)) != 0) { - printf("dpt%d WARNING: Get_conf() failed (%d) to send " + device_printf(dpt->dev, + "WARNING: Get_conf() failed (%d) to send " "EATA_CMD_DMA_READ_CONFIG\n", - dpt->unit, result); - splx(ospl); + result); return (0); } /* Wait for two seconds for a response. This can be slow */ @@ -574,8 +567,6 @@ dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t /* Grab the status and clear interrupts */ status = dpt_inb(dpt, HA_RSTATUS); - splx(ospl); - /* * Check the status carefully. Return only if the * command was successful. @@ -601,10 +592,11 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c u_int8_t *param; int bytes; int result; - int ospl; int ndx; u_int8_t status; + mtx_assert(&dpt->lock, MA_OWNED); + /* * Default setting, for best perfromance.. * This is what virtually all cards default to.. @@ -646,14 +638,13 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c cp->cp_datalen = htonl(512); - ospl = splcam(); result = dpt_send_eata_command(dpt, cp, dccb_busaddr, EATA_CMD_DMA_SEND_CP, 10000, 0, 0, 0); if (result != 0) { - printf("dpt%d WARNING: detect_cache() failed (%d) to send " - "EATA_CMD_DMA_SEND_CP\n", dpt->unit, result); - splx(ospl); + device_printf(dpt->dev, + "WARNING: detect_cache() failed (%d) to send " + "EATA_CMD_DMA_SEND_CP\n", result); return; } /* Wait for two seconds for a response. This can be slow... */ @@ -666,7 +657,6 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c /* Grab the status and clear interrupts */ status = dpt_inb(dpt, HA_RSTATUS); - splx(ospl); /* * Sanity check @@ -681,8 +671,7 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c /* * DPT Log Page layout error */ - printf("dpt%d: NOTICE: Log Page (1) layout error\n", - dpt->unit); + device_printf(dpt->dev, "NOTICE: Log Page (1) layout error\n"); return; } if (!(param[4] & 0x4)) { @@ -721,7 +710,7 @@ dpt_detect_cache(dpt_softc_t *dpt, dpt_c static void dpt_poll(struct cam_sim *sim) { - dpt_intr(cam_sim_softc(sim)); + dpt_intr_locked(cam_sim_softc(sim)); } static void @@ -730,16 +719,18 @@ dptexecuteccb(void *arg, bus_dma_segment struct dpt_ccb *dccb; union ccb *ccb; struct dpt_softc *dpt; - int s; + if (!dumping) + mtx_assert(&dpt->lock, MA_OWNED); dccb = (struct dpt_ccb *)arg; ccb = dccb->ccb; dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr; if (error != 0) { if (error != EFBIG) - printf("dpt%d: Unexepected error 0x%x returned from " - "bus_dmamap_load\n", dpt->unit, error); + device_printf(dpt->dev, + "Unexepected error 0x%x returned from " + "bus_dmamap_load\n", error); if (ccb->ccb_h.status == CAM_REQ_INPROG) { xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; @@ -787,8 +778,6 @@ dptexecuteccb(void *arg, bus_dma_segment dccb->eata_ccb.cp_datalen = 0; } - s = splcam(); - /* * Last time we need to check if this CCB needs to * be aborted. @@ -798,16 +787,14 @@ dptexecuteccb(void *arg, bus_dma_segment bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap); dptfreeccb(dpt, dccb); xpt_done(ccb); - splx(s); return; } dccb->state |= DCCB_ACTIVE; ccb->ccb_h.status |= CAM_SIM_QUEUED; LIST_INSERT_HEAD(&dpt->pending_ccb_list, &ccb->ccb_h, sim_links.le); - ccb->ccb_h.timeout_ch = - timeout(dpttimeout, (caddr_t)dccb, - (ccb->ccb_h.timeout * hz) / 1000); + callout_reset(&dccb->timer, (ccb->ccb_h.timeout * hz) / 1000, + dpttimeout, dccb); if (dpt_send_eata_command(dpt, &dccb->eata_ccb, dccb->eata_ccb.cp_busaddr, EATA_CMD_DMA_SEND_CP, 0, 0, 0, 0) != 0) { @@ -817,8 +804,6 @@ dptexecuteccb(void *arg, bus_dma_segment dptfreeccb(dpt, dccb); xpt_done(ccb); } - - splx(s); } static void @@ -829,6 +814,7 @@ dpt_action(struct cam_sim *sim, union cc CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("dpt_action\n")); dpt = (struct dpt_softc *)cam_sim_softc(sim); + mtx_assert(&dpt->lock, MA_OWNED); if ((dpt->state & DPT_HA_SHUTDOWN_ACTIVE) != 0) { xpt_print_path(ccb->ccb_h.path); @@ -856,11 +842,7 @@ dpt_action(struct cam_sim *sim, union cc return; } if ((dccb = dptgetccb(dpt)) == NULL) { - int s; - - s = splcam(); dpt->resource_shortage = 1; - splx(s); xpt_freeze_simq(sim, /*count*/1); ccb->ccb_h.status = CAM_REQUEUE_REQ; xpt_done(ccb); @@ -934,10 +916,8 @@ dpt_action(struct cam_sim *sim, union cc * to a single buffer. */ if ((ccbh->flags & CAM_DATA_PHYS) == 0) { - int s; int error; - s = splsoftvm(); error = bus_dmamap_load(dpt->buffer_dmat, dccb->dmamap, @@ -955,7 +935,6 @@ dpt_action(struct cam_sim *sim, union cc xpt_freeze_simq(sim, 1); dccb->state |= CAM_RELEASE_SIMQ; } - splx(s); } else { struct bus_dma_segment seg; @@ -1105,7 +1084,6 @@ dpt_action(struct cam_sim *sim, union cc * This routine will try to send an EATA command to the DPT HBA. * It will, by default, try 20,000 times, waiting 50us between tries. * It returns 0 on success and 1 on failure. - * It is assumed to be called at splcam(). */ static int dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd_block, @@ -1183,9 +1161,7 @@ dpt_alloc(device_t dev) dpt_softc_t *dpt = device_get_softc(dev); int i; - dpt->tag = rman_get_bustag(dpt->io_res); - dpt->bsh = rman_get_bushandle(dpt->io_res) + dpt->io_offset; - dpt->unit = device_get_unit(dev); + mtx_init(&dpt->lock, "dpt", NULL, MTX_DEF); SLIST_INIT(&dpt->free_dccb_list); LIST_INIT(&dpt->pending_ccb_list); for (i = 0; i < MAX_CHANNELS; i++) @@ -1229,6 +1205,7 @@ dpt_free(struct dpt_softc *dpt) case 0: break; } + mtx_destroy(&dpt->lock); } int @@ -1301,9 +1278,10 @@ dpt_init(struct dpt_softc *dpt) dpt->init_level = 0; SLIST_INIT(&dpt->sg_maps); + mtx_lock(&dpt->lock); #ifdef DPT_RESET_BOARD - printf("dpt%d: resetting HBA\n", dpt->unit); + device_printf(dpt->dev, "resetting HBA\n"); dpt_outb(dpt, HA_WCOMMAND, EATA_CMD_RESET); DELAY(750000); /* XXX Shouldn't we poll a status register or something??? */ @@ -1320,8 +1298,8 @@ dpt_init(struct dpt_softc *dpt) /* nsegments */ 1, /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &dpt->sg_dmat) != 0) { goto error_exit; } @@ -1357,8 +1335,8 @@ dpt_init(struct dpt_softc *dpt) sizeof(conf), 0xc1, 7, 1); if (retval != 0) { - printf("dpt%d: Failed to get board configuration\n", dpt->unit); - return (retval); + device_printf(dpt->dev, "Failed to get board configuration\n"); + goto error_exit; } bcopy(&dccb[1], &conf, sizeof(conf)); @@ -1366,8 +1344,8 @@ dpt_init(struct dpt_softc *dpt) retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t), sizeof(dpt->board_data), 0, conf.scsi_id0, 0); if (retval != 0) { - printf("dpt%d: Failed to get inquiry information\n", dpt->unit); - return (retval); + device_printf(dpt->dev, "Failed to get inquiry information\n"); + goto error_exit; } bcopy(&dccb[1], &dpt->board_data, sizeof(dpt->board_data)); @@ -1416,8 +1394,8 @@ dpt_init(struct dpt_softc *dpt) dpt->max_dccbs = ntohs(conf.queuesiz); if (dpt->max_dccbs > 256) { - printf("dpt%d: Max CCBs reduced from %d to " - "256 due to tag algorithm\n", dpt->unit, dpt->max_dccbs); + device_printf(dpt->dev, "Max CCBs reduced from %d to " + "256 due to tag algorithm\n", dpt->max_dccbs); dpt->max_dccbs = 256; } @@ -1450,9 +1428,10 @@ dpt_init(struct dpt_softc *dpt) /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, /* flags */ BUS_DMA_ALLOCNOW, /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockarg */ &dpt->lock, &dpt->buffer_dmat) != 0) { - printf("dpt: bus_dma_tag_create(...,dpt->buffer_dmat) failed\n"); + device_printf(dpt->dev, + "bus_dma_tag_create(...,dpt->buffer_dmat) failed\n"); goto error_exit; } @@ -1472,10 +1451,11 @@ dpt_init(struct dpt_softc *dpt) /* nsegments */ 1, /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, /* flags */ 0, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &Giant, + /* lockfunc */ NULL, + /* lockarg */ NULL, &dpt->dccb_dmat) != 0) { - printf("dpt: bus_dma_tag_create(...,dpt->dccb_dmat) failed\n"); + device_printf(dpt->dev, + "bus_dma_tag_create(...,dpt->dccb_dmat) failed\n"); goto error_exit; } @@ -1484,7 +1464,8 @@ dpt_init(struct dpt_softc *dpt) /* Allocation for our ccbs and interrupt status packet */ if (bus_dmamem_alloc(dpt->dccb_dmat, (void **)&dpt->dpt_dccbs, BUS_DMA_NOWAIT, &dpt->dccb_dmamap) != 0) { - printf("dpt: bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n"); + device_printf(dpt->dev, + "bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n"); goto error_exit; } @@ -1510,7 +1491,8 @@ dpt_init(struct dpt_softc *dpt) /* Allocate our first batch of ccbs */ if (dptallocccbs(dpt) == 0) { - printf("dpt: dptallocccbs(dpt) == 0\n"); + device_printf(dpt->dev, "dptallocccbs(dpt) == 0\n"); + mtx_unlock(&dpt->lock); return (2); } @@ -1526,8 +1508,8 @@ dpt_init(struct dpt_softc *dpt) strp += string_sizes[i]; } - printf("dpt%d: %.8s %.16s FW Rev. %.4s, ", - dpt->unit, dpt->board_data.vendor, + device_printf(dpt->dev, "%.8s %.16s FW Rev. %.4s, ", + dpt->board_data.vendor, dpt->board_data.modelNum, dpt->board_data.firmware); printf("%d channel%s, ", dpt->channels, dpt->channels > 1 ? "s" : ""); @@ -1540,9 +1522,11 @@ dpt_init(struct dpt_softc *dpt) } printf("%d CCBs\n", dpt->max_dccbs); + mtx_unlock(&dpt->lock); return (0); error_exit: + mtx_unlock(&dpt->lock); return (1); } @@ -1559,12 +1543,13 @@ dpt_attach(dpt_softc_t *dpt) if (devq == NULL) return (0); + mtx_lock(&dpt->lock); for (i = 0; i < dpt->channels; i++) { /* * Construct our SIM entry */ dpt->sims[i] = cam_sim_alloc(dpt_action, dpt_poll, "dpt", - dpt, dpt->unit, &Giant, + dpt, device_get_unit(dpt->dev), &dpt->lock, /*untagged*/2, /*tagged*/dpt->max_dccbs, devq); if (dpt->sims[i] == NULL) { @@ -1594,6 +1579,7 @@ dpt_attach(dpt_softc_t *dpt) } } + mtx_unlock(&dpt->lock); if (i > 0) EVENTHANDLER_REGISTER(shutdown_final, dptshutdown, dpt, SHUTDOWN_PRI_DEFAULT); @@ -1608,6 +1594,7 @@ dpt_detach (device_t dev) dpt = device_get_softc(dev); + mtx_lock(&dpt->lock); for (i = 0; i < dpt->channels; i++) { #if 0 xpt_async(AC_LOST_DEVICE, dpt->paths[i], NULL); @@ -1616,6 +1603,7 @@ dpt_detach (device_t dev) xpt_bus_deregister(cam_sim_path(dpt->sims[i])); cam_sim_free(dpt->sims[i], /*free_devq*/TRUE); } + mtx_unlock(&dpt->lock); dptshutdown((void *)dpt, SHUTDOWN_PRI_DEFAULT); @@ -1633,6 +1621,16 @@ void dpt_intr(void *arg) { dpt_softc_t *dpt; + + dpt = arg; + mtx_lock(&dpt->lock); + dpt_intr_locked(dpt); + mtx_unlock(&dpt->lock); +} + +void +dpt_intr_locked(dpt_softc_t *dpt) +{ dpt_ccb_t *dccb; union ccb *ccb; u_int status; @@ -1641,8 +1639,6 @@ dpt_intr(void *arg) u_int scsi_stat; u_int32_t residue_len; /* Number of bytes not transferred */ - dpt = (dpt_softc_t *)arg; - /* First order of business is to check if this interrupt is for us */ while (((aux_status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ) != 0) { @@ -1653,7 +1649,8 @@ dpt_intr(void *arg) */ if (dpt->sp->ccb_busaddr < dpt->dpt_ccb_busbase || dpt->sp->ccb_busaddr >= dpt->dpt_ccb_busend) { - printf("Encountered bogus status packet\n"); + device_printf(dpt->dev, + "Encountered bogus status packet\n"); status = dpt_inb(dpt, HA_RSTATUS); return; } @@ -1664,9 +1661,10 @@ dpt_intr(void *arg) /* Ignore status packets with EOC not set */ if (dpt->sp->EOC == 0) { - printf("dpt%d ERROR: Request %d received with " + device_printf(dpt->dev, + "ERROR: Request %d received with " "clear EOC.\n Marking as LOST.\n", - dpt->unit, dccb->transaction_id); + dccb->transaction_id); #ifdef DPT_HANDLE_TIMEOUTS dccb->state |= DPT_CCB_STATE_MARKED_LOST; @@ -1696,20 +1694,20 @@ dpt_intr(void *arg) /* Check that this is not a board reset interrupt */ if (dpt_just_reset(dpt)) { - printf("dpt%d: HBA rebooted.\n" + device_printf(dpt->dev, "HBA rebooted.\n" " All transactions should be " - "resubmitted\n", - dpt->unit); + "resubmitted\n"); - printf("dpt%d: >>---->> This is incomplete, " - "fix me.... <<----<<", dpt->unit); + device_printf(dpt->dev, + ">>---->> This is incomplete, " + "fix me.... <<----<<"); panic("DPT Rebooted"); } } /* Process CCB */ ccb = dccb->ccb; - untimeout(dpttimeout, dccb, ccb->ccb_h.timeout_ch); + callout_stop(&dccb->timer); if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { bus_dmasync_op_t op; @@ -1803,7 +1801,7 @@ dptprocesserror(dpt_softc_t *dpt, dpt_cc ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; break; default: - printf("dpt%d: Undocumented Error %x\n", dpt->unit, hba_stat); + device_printf(dpt->dev, "Undocumented Error %x\n", hba_stat); printf("Please mail this message to shimon@simon-shapiro.org\n"); ccb->ccb_h.status = CAM_REQ_CMP_ERR; break; @@ -1818,29 +1816,26 @@ dpttimeout(void *arg) struct dpt_ccb *dccb; union ccb *ccb; struct dpt_softc *dpt; - int s; dccb = (struct dpt_ccb *)arg; ccb = dccb->ccb; dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr; + mtx_assert(&dpt->lock, MA_OWNED); xpt_print_path(ccb->ccb_h.path); printf("CCB %p - timed out\n", (void *)dccb); - s = splcam(); - /* * Try to clear any pending jobs. FreeBSD will lose interrupts, * leaving the controller suspended, and commands timed-out. * By calling the interrupt handler, any command thus stuck will be * completed. */ - dpt_intr(dpt); + dpt_intr_locked(dpt); if ((dccb->state & DCCB_ACTIVE) == 0) { xpt_print_path(ccb->ccb_h.path); printf("CCB %p - timed out CCB already completed\n", (void *)dccb); - splx(s); return; } @@ -1848,7 +1843,6 @@ dpttimeout(void *arg) dpt_send_immediate(dpt, &dccb->eata_ccb, dccb->eata_ccb.cp_busaddr, /*retries*/20000, EATA_SPECIFIC_ABORT, 0, 0); ccb->ccb_h.status = CAM_CMD_TIMEOUT; - splx(s); } /* @@ -1862,16 +1856,18 @@ dptshutdown(void *arg, int howto) dpt = (dpt_softc_t *)arg; - printf("dpt%d: Shutting down (mode %x) HBA. Please wait...\n", - dpt->unit, howto); + device_printf(dpt->dev, + "Shutting down (mode %x) HBA. Please wait...\n", howto); /* * What we do for a shutdown, is give the DPT early power loss warning */ + mtx_lock(&dpt->lock); dpt_send_immediate(dpt, NULL, 0, EATA_POWER_OFF_WARN, 0, 0, 0); + mtx_unlock(&dpt->lock); DELAY(1000 * 1000 * 5); - printf("dpt%d: Controller was warned of shutdown and is now " - "disabled\n", dpt->unit); + device_printf(dpt->dev, "Controller was warned of shutdown and is now " + "disabled\n"); } /*============================================================================*/ @@ -1890,11 +1886,12 @@ static void dpt_reset_hba(dpt_softc_t *dpt) { eata_ccb_t *ccb; - int ospl; dpt_ccb_t dccb, *dccbp; int result; struct scsi_xfer *xs; - + + mtx_assert(&dpt->lock, MA_OWNED); + /* Prepare a control block. The SCSI command part is immaterial */ dccb.xs = NULL; dccb.flags = 0; @@ -1920,26 +1917,24 @@ dpt_reset_hba(dpt_softc_t *dpt) ccb->cp_scsi_cmd = 0; /* Should be ignored */ /* Lock up the submitted queue. We are very persistant here */ - ospl = splcam(); while (dpt->queue_status & DPT_SUBMITTED_QUEUE_ACTIVE) { DELAY(100); } dpt->queue_status |= DPT_SUBMITTED_QUEUE_ACTIVE; - splx(ospl); /* Send the RESET message */ if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb, EATA_CMD_RESET, 0, 0, 0, 0)) != 0) { - printf("dpt%d: Failed to send the RESET message.\n" - " Trying cold boot (ouch!)\n", dpt->unit); + device_printf(dpt->dev, "Failed to send the RESET message.\n" + " Trying cold boot (ouch!)\n"); if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb, EATA_COLD_BOOT, 0, 0, 0, 0)) != 0) { - panic("dpt%d: Faild to cold boot the HBA\n", - dpt->unit); + panic("%s: Faild to cold boot the HBA\n", + device_get_nameunit(dpt->dev)); } #ifdef DPT_MEASURE_PERFORMANCE dpt->performance.cold_boots++; @@ -1950,8 +1945,8 @@ dpt_reset_hba(dpt_softc_t *dpt) dpt->performance.warm_starts++; #endif /* DPT_MEASURE_PERFORMANCE */ - printf("dpt%d: Aborting pending requests. O/S should re-submit\n", - dpt->unit); + device_printf(dpt->dev, + "Aborting pending requests. O/S should re-submit\n"); while ((dccbp = TAILQ_FIRST(&dpt->completed_ccbs)) != NULL) { struct scsi_xfer *xs = dccbp->xs; @@ -1971,13 +1966,11 @@ dpt_reset_hba(dpt_softc_t *dpt) (dccbp->std_callback)(dpt, dccbp->eata_ccb.cp_channel, dccbp); } else { - ospl = splcam(); dpt_Qpush_free(dpt, dccbp); - splx(ospl); } } - printf("dpt%d: reset done aborting all pending commands\n", dpt->unit); + device_printf(dpt->dev, "reset done aborting all pending commands\n"); dpt->queue_status &= ~DPT_SUBMITTED_QUEUE_ACTIVE; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210151629.q9FGT83s027406>