Skip site navigation (1)Skip section navigation (2)
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>