svn commit: r241492 - head/sys/dev/advansys

John Baldwin jhb at FreeBSD.org
Fri Oct 12 21:31:45 UTC 2012


Author: jhb
Date: Fri Oct 12 21:31:44 2012
New Revision: 241492
URL: http://svn.freebsd.org/changeset/base/241492

Log:
  Add locking to adv(4) driver and mark it MPSAFE.
  - Disable the support for the second channel on twin-channel EISA cards as
    the current incarnation can't possibly work correctly (it hasn't worked
    since switching to new-bus where new-bus allocates the softc).  If anyone
    bothers to test this again it can be fixed properly and brought back.
  - Use device_printf() and device_get_nameunit() instead of adv_name().
  - Remove use of explicit bus space handles and tags.
  - Use PCI bus accessors and helper routines rather than accessing
    config registers directly.
  - Handle failures from adv_attach().
  
  Tested by:	no one (hope it works)

Modified:
  head/sys/dev/advansys/adv_eisa.c
  head/sys/dev/advansys/adv_isa.c
  head/sys/dev/advansys/adv_pci.c
  head/sys/dev/advansys/advansys.c
  head/sys/dev/advansys/advansys.h
  head/sys/dev/advansys/advlib.c
  head/sys/dev/advansys/advlib.h

Modified: head/sys/dev/advansys/adv_eisa.c
==============================================================================
--- head/sys/dev/advansys/adv_eisa.c	Fri Oct 12 19:53:13 2012	(r241491)
+++ head/sys/dev/advansys/adv_eisa.c	Fri Oct 12 21:31:44 2012	(r241492)
@@ -131,17 +131,27 @@ adv_eisa_probe(device_t dev)
 	return 0;
 }
 
+/*
+ * The adv_b stuff to handle twin-channel cards will not work in its current
+ * incarnation.  It tries to reuse the same softc since adv_alloc() doesn't
+ * actually allocate a softc.  It also tries to reuse the same unit number
+ * for both sims.  This can be re-enabled if someone fixes it properly.
+ */
 static int
 adv_eisa_attach(device_t dev)
 {
 	struct adv_softc *adv;
+#if 0
 	struct adv_softc *adv_b;
+#endif
 	struct resource *io;
 	struct resource *irq;
 	int rid, error;
 	void *ih;
 
+#if 0
 	adv_b = NULL;
+#endif
 
 	rid = 0;
 	io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
@@ -162,8 +172,8 @@ adv_eisa_attach(device_t dev)
 
 	switch (eisa_get_id(dev) & ~0xF) {
 	case EISA_DEVICE_ID_ADVANSYS_750:
-		adv_b = adv_alloc(dev, rman_get_bustag(io),
-				  rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN2);
+#if 0
+		adv_b = adv_alloc(dev, io, ADV_EISA_OFFSET_CHAN2);
 		if (adv_b == NULL)
 			goto bad;
 		
@@ -183,26 +193,28 @@ adv_eisa_attach(device_t dev)
 				/* nsegments	*/ ~0,
 				/* maxsegsz	*/ ADV_EISA_MAX_DMA_COUNT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&adv_b->parent_dmat);
  
 		if (error != 0) {
-			printf("%s: Could not allocate DMA tag - error %d\n",
-			       adv_name(adv_b), error);
+			device_printf(dev, "Could not allocate DMA tag - error %d\n",
+			       error);
 			adv_free(adv_b);
 			goto bad;
 		}
 
 		adv_b->init_level++;
+#endif
 
 		/* FALLTHROUGH */
 	case EISA_DEVICE_ID_ADVANSYS_740:
-		adv = adv_alloc(dev, rman_get_bustag(io),
-				rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN1);
+		adv = adv_alloc(dev, io, ADV_EISA_OFFSET_CHAN1);
 		if (adv == NULL) {
+#if 0
 			if (adv_b != NULL)
 				adv_free(adv_b);
+#endif
 			goto bad;
 		}
 
@@ -222,13 +234,13 @@ adv_eisa_attach(device_t dev)
 				/* nsegments	*/ ~0,
 				/* maxsegsz	*/ ADV_EISA_MAX_DMA_COUNT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&adv->parent_dmat);
  
 		if (error != 0) {
-			printf("%s: Could not allocate DMA tag - error %d\n",
-			       adv_name(adv), error);
+			device_printf(dev, "Could not allocate DMA tag - error %d\n",
+			       error);
 			adv_free(adv);
 			goto bad;
 		}
@@ -244,7 +256,7 @@ adv_eisa_attach(device_t dev)
 	if (overrun_buf == NULL) {
 		/* Need to allocate our overrun buffer */
 		if (bus_dma_tag_create(
-				/* parent	*/ adv->parent_dmat,
+				/* parent	*/ bus_get_dma_tag(dev),
 				/* alignment	*/ 8,
 				/* boundary	*/ 0,
 				/* lowaddr	*/ ADV_EISA_MAX_DMA_ADDR,
@@ -255,8 +267,8 @@ adv_eisa_attach(device_t dev)
 				/* nsegments	*/ 1,
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&overrun_dmat) != 0) {
 			adv_free(adv);
 			goto bad;
@@ -292,14 +304,17 @@ adv_eisa_attach(device_t dev)
 
 	if (adv_init(adv) != 0) {
 		adv_free(adv);
+#if 0
 		if (adv_b != NULL)
 			adv_free(adv_b);
-		return(-1);
+#endif
+		goto bad;
 	}
 
 	adv->max_dma_count = ADV_EISA_MAX_DMA_COUNT;
 	adv->max_dma_addr = ADV_EISA_MAX_DMA_ADDR;
 
+#if 0
 	if (adv_b != NULL) {
 		/*
 		 * Stop the chip.
@@ -317,24 +332,33 @@ adv_eisa_attach(device_t dev)
 			adv_b->max_dma_addr = ADV_EISA_MAX_DMA_ADDR;
 		}
 	}
+#endif
 
 	/*
 	 * Enable our interrupt handler.
 	 */
-	bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY, NULL, adv_intr, 
-	    adv, &ih);
+	if (bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, NULL,
+	    adv_intr, adv, &ih) != 0) {
+		adv_free(adv);
+		goto bad;
+	}
 
-	/* Attach sub-devices - always succeeds */
-	adv_attach(adv);
+	/* Attach sub-devices */
+	if (adv_attach(adv) != 0) {
+		adv_free(adv);
+		goto bad;
+	}
+#if 0
 	if (adv_b != NULL)
 		adv_attach(adv_b);
+#endif
 
 	return 0;
 
  bad:
 	bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
 	bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
-	return -1;
+	return ENXIO;
 }
 
 static device_method_t adv_eisa_methods[] = {

Modified: head/sys/dev/advansys/adv_isa.c
==============================================================================
--- head/sys/dev/advansys/adv_isa.c	Fri Oct 12 19:53:13 2012	(r241491)
+++ head/sys/dev/advansys/adv_isa.c	Fri Oct 12 21:31:44 2012	(r241492)
@@ -135,12 +135,13 @@ adv_isa_probe(device_t dev)
 		if ((port_index > max_port_index)
 		 || (iobase != adv_isa_ioports[port_index])) {
 			if (bootverbose)
-			    printf("adv%d: Invalid baseport of 0x%lx specified. "
-				"Nearest valid baseport is 0x%x.  Failing "
-				"probe.\n", device_get_unit(dev), iobase,
-				(port_index <= max_port_index) ?
-					adv_isa_ioports[port_index] :
-					adv_isa_ioports[max_port_index]);
+				device_printf(dev,
+				    "Invalid baseport of 0x%lx specified. "
+				    "Nearest valid baseport is 0x%x.  Failing "
+				    "probe.\n", iobase,
+				    (port_index <= max_port_index) ?
+				    adv_isa_ioports[port_index] :
+				    adv_isa_ioports[max_port_index]);
 			return ENXIO;
 		}
 		max_port_index = port_index;
@@ -169,8 +170,7 @@ adv_isa_probe(device_t dev)
 		if (iores == NULL)
 			continue;
 
-		if (adv_find_signature(rman_get_bustag(iores),
-				       rman_get_bushandle(iores)) == 0) {
+		if (adv_find_signature(iores) == 0) {
 			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
 			continue;
 		}
@@ -179,8 +179,7 @@ adv_isa_probe(device_t dev)
 		 * Got one.  Now allocate our softc
 		 * and see if we can initialize the card.
 		 */
-		adv = adv_alloc(dev, rman_get_bustag(iores),
-				rman_get_bushandle(iores));
+		adv = adv_alloc(dev, iores, 0);
 		if (adv == NULL) {
 			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
 			break;
@@ -238,13 +237,13 @@ adv_isa_probe(device_t dev)
 				/* nsegments	*/ ~0,
 				/* maxsegsz	*/ maxsegsz,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&adv->parent_dmat); 
 
 		if (error != 0) {
-			printf("%s: Could not allocate DMA tag - error %d\n",
-			       adv_name(adv), error); 
+			device_printf(dev,
+			    "Could not allocate DMA tag - error %d\n", error);
 			adv_free(adv); 
 			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
 			break;
@@ -335,8 +334,11 @@ adv_isa_probe(device_t dev)
 		irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
 						RF_ACTIVE);
 		if (irqres == NULL ||
-		    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY,
-		        NULL, adv_intr, adv, &ih)) {
+		    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|
+		    INTR_MPSAFE, NULL, adv_intr, adv, &ih) != 0) {
+			if (irqres != NULL)
+				bus_release_resource(dev, SYS_RES_IRQ, rid,
+				    irqres);
 			bus_dmamap_unload(overrun_dmat, overrun_dmamap);
 			bus_dmamem_free(overrun_dmat, overrun_buf,
 			    overrun_dmamap);

Modified: head/sys/dev/advansys/adv_pci.c
==============================================================================
--- head/sys/dev/advansys/adv_pci.c	Fri Oct 12 19:53:13 2012	(r241491)
+++ head/sys/dev/advansys/adv_pci.c	Fri Oct 12 21:31:44 2012	(r241492)
@@ -138,7 +138,6 @@ adv_pci_attach(device_t dev)
 {
 	struct		adv_softc *adv;
 	u_int32_t	id;
-	u_int32_t	command;
 	int		error, rid, irqrid;
 	void		*ih;
 	struct resource	*iores, *irqres;
@@ -146,19 +145,8 @@ adv_pci_attach(device_t dev)
 	/*
 	 * Determine the chip version.
 	 */
-	id = pci_read_config(dev, PCIR_DEVVENDOR, /*bytes*/4);
-	command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
-
-	/*
-	 * These cards do not allow memory mapped accesses, so we must
-	 * ensure that I/O accesses are available or we won't be able
-	 * to talk to them.
-	 */
-	if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
-	 != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
-		command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
-		pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
-	}
+	id = pci_get_devid(dev);
+	pci_enable_busmaster(dev);
 
 	/*
 	 * Early chips can't handle non-zero latency timer settings.
@@ -174,13 +162,12 @@ adv_pci_attach(device_t dev)
 	if (iores == NULL)
 		return ENXIO;
 
-	if (adv_find_signature(rman_get_bustag(iores),
-			       rman_get_bushandle(iores)) == 0) {
+	if (adv_find_signature(iores) == 0) {
 		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
 		return ENXIO;
 	}
 
-	adv = adv_alloc(dev, rman_get_bustag(iores), rman_get_bushandle(iores));
+	adv = adv_alloc(dev, iores, 0);
 	if (adv == NULL) {
 		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
 		return ENXIO;
@@ -199,13 +186,13 @@ adv_pci_attach(device_t dev)
 			/* nsegments	*/ ~0,
 			/* maxsegsz	*/ ADV_PCI_MAX_DMA_COUNT,
 			/* flags	*/ 0,
-			/* lockfunc	*/ busdma_lock_mutex,
-			/* lockarg	*/ &Giant,
+			/* lockfunc	*/ NULL,
+			/* lockarg	*/ NULL,
 			&adv->parent_dmat);
  
 	if (error != 0) {
-		printf("%s: Could not allocate DMA tag - error %d\n",
-		       adv_name(adv), error);
+		device_printf(dev, "Could not allocate DMA tag - error %d\n",
+		    error);
 		adv_free(adv);
 		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
 		return ENXIO;
@@ -227,8 +214,8 @@ adv_pci_attach(device_t dev)
 				/* nsegments	*/ 1,
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&overrun_dmat) != 0) {
 			bus_dma_tag_destroy(adv->parent_dmat);
 			adv_free(adv);
@@ -308,14 +295,22 @@ adv_pci_attach(device_t dev)
 	irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqrid,
 					RF_SHAREABLE | RF_ACTIVE);
 	if (irqres == NULL ||
-	    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY, NULL, 
-	        adv_intr, adv, &ih)) {
+	    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE,
+	    NULL, adv_intr, adv, &ih) != 0) {
+		if (irqres != NULL)
+			bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres);
 		adv_free(adv);
 		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
 		return ENXIO;
 	}
 
-	adv_attach(adv);
+	if (adv_attach(adv) != 0) {
+		bus_teardown_intr(dev, irqres, ih);
+		bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres);
+		adv_free(adv);
+		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
+		return ENXIO;
+	}
 	return 0;
 }
 

Modified: head/sys/dev/advansys/advansys.c
==============================================================================
--- head/sys/dev/advansys/advansys.c	Fri Oct 12 19:53:13 2012	(r241491)
+++ head/sys/dev/advansys/advansys.c	Fri Oct 12 21:31:44 2012	(r241492)
@@ -49,6 +49,7 @@
 __FBSDID("$FreeBSD$");
  
 #include <sys/param.h>
+#include <sys/conf.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
@@ -79,6 +80,7 @@ __FBSDID("$FreeBSD$");
 static void	adv_action(struct cam_sim *sim, union ccb *ccb);
 static void	adv_execute_ccb(void *arg, bus_dma_segment_t *dm_segs,
 				int nsegments, int error);
+static void	adv_intr_locked(struct adv_softc *adv);
 static void	adv_poll(struct cam_sim *sim);
 static void	adv_run_doneq(struct adv_softc *adv);
 static struct adv_ccb_info *
@@ -97,15 +99,14 @@ static __inline struct adv_ccb_info *
 adv_get_ccb_info(struct adv_softc *adv)
 {
 	struct adv_ccb_info *cinfo;
-	int opri;
 
-	opri = splcam();
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 	if ((cinfo = SLIST_FIRST(&adv->free_ccb_infos)) != NULL) {
 		SLIST_REMOVE_HEAD(&adv->free_ccb_infos, links);
 	} else {
 		cinfo = adv_alloc_ccb_info(adv);
 	}
-	splx(opri);
 
 	return (cinfo);
 }
@@ -113,12 +114,11 @@ adv_get_ccb_info(struct adv_softc *adv)
 static __inline void
 adv_free_ccb_info(struct adv_softc *adv, struct adv_ccb_info *cinfo)
 {       
-	int opri;
 
-	opri = splcam();
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 	cinfo->state = ACCB_FREE;
 	SLIST_INSERT_HEAD(&adv->free_ccb_infos, cinfo, links);
-	splx(opri);
 }
 
 static __inline void
@@ -139,6 +139,9 @@ adv_clear_state(struct adv_softc *adv, u
 static void
 adv_clear_state_really(struct adv_softc *adv, union ccb* ccb)
 {
+
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 	if ((adv->state & ADV_BUSDMA_BLOCK_CLEARED) != 0)
 		adv->state &= ~(ADV_BUSDMA_BLOCK_CLEARED|ADV_BUSDMA_BLOCK);
 	if ((adv->state & ADV_RESOURCE_SHORTAGE) != 0) {
@@ -164,13 +167,14 @@ adv_clear_state_really(struct adv_softc 
 			 */
 			ccb_h = LIST_FIRST(&adv->pending_ccbs);
 			while (ccb_h != NULL) {
-				ccb_h->timeout_ch =
-				    timeout(adv_timeout, (caddr_t)ccb_h,
-					    (ccb_h->timeout * hz) / 1000);
+				cinfo = ccb_h->ccb_cinfo_ptr;
+				callout_reset(&cinfo->timer,
+				    ccb_h->timeout * hz / 1000, adv_timeout,
+				    ccb_h);
 				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 			}
 			adv->state &= ~ADV_IN_TIMEOUT;
-			printf("%s: No longer in timeout\n", adv_name(adv));
+			device_printf(adv->dev, "No longer in timeout\n");
 		}
 	}
 	if (adv->state == 0)
@@ -186,15 +190,6 @@ adv_map(void *arg, bus_dma_segment_t *se
 	*physaddr = segs->ds_addr;
 }
 
-char *
-adv_name(struct adv_softc *adv)
-{
-	static char name[10];
-
-	snprintf(name, sizeof(name), "adv%d", adv->unit);
-	return (name);
-}
-
 static void
 adv_action(struct cam_sim *sim, union ccb *ccb)
 {
@@ -203,6 +198,7 @@ adv_action(struct cam_sim *sim, union cc
 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("adv_action\n"));
 
 	adv = (struct adv_softc *)cam_sim_softc(sim);
+	mtx_assert(&adv->lock, MA_OWNED);
 
 	switch (ccb->ccb_h.func_code) {
 	/* Common cases first */
@@ -229,10 +225,8 @@ adv_action(struct cam_sim *sim, union cc
 				 * to a single buffer
 				 */
 				if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
-					int s;
 					int error;
 
-					s = splsoftvm();
 					error =
 					    bus_dmamap_load(adv->buffer_dmat,
 							    cinfo->dmamap,
@@ -250,7 +244,6 @@ adv_action(struct cam_sim *sim, union cc
 						adv_set_state(adv,
 							      ADV_BUSDMA_BLOCK);
 					}
-					splx(s);
 				} else {
 					struct bus_dma_segment seg;
 
@@ -299,7 +292,6 @@ adv_action(struct cam_sim *sim, union cc
 		target_bit_vector targ_mask;
 		struct adv_transinfo *tconf;
 		u_int	 update_type;
-		int	 s;
 
 		cts = &ccb->cts;
 		targ_mask = ADV_TID_TO_TARGET_MASK(cts->ccb_h.target_id);
@@ -320,7 +312,6 @@ adv_action(struct cam_sim *sim, union cc
 			break;
 		}
 		
-		s = splcam();
 		scsi = &cts->proto_specific.scsi;
 		spi = &cts->xport_specific.spi;
 		if ((update_type & ADV_TRANS_GOAL) != 0) {
@@ -387,7 +378,6 @@ adv_action(struct cam_sim *sim, union cc
 					 spi->sync_offset, update_type);
 		}
 
-		splx(s);
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		break;
@@ -400,7 +390,6 @@ adv_action(struct cam_sim *sim, union cc
 		struct ccb_trans_settings *cts;
 		struct adv_transinfo *tconf;
 		target_bit_vector target_mask;
-		int s;
 
 		cts = &ccb->cts;
 		target_mask = ADV_TID_TO_TARGET_MASK(cts->ccb_h.target_id);
@@ -416,7 +405,6 @@ adv_action(struct cam_sim *sim, union cc
 		scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 		spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
 
-		s = splcam();
 		if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
 			tconf = &adv->tinfo[cts->ccb_h.target_id].current;
 			if ((adv->disc_enable & target_mask) != 0)
@@ -432,7 +420,6 @@ adv_action(struct cam_sim *sim, union cc
 		}
 		spi->sync_period = tconf->period;
 		spi->sync_offset = tconf->offset;
-		splx(s);
 		spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 		spi->valid = CTS_SPI_VALID_SYNC_RATE
 			   | CTS_SPI_VALID_SYNC_OFFSET
@@ -454,13 +441,10 @@ adv_action(struct cam_sim *sim, union cc
 	}
 	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
 	{
-		int s;
 
-		s = splcam();
 		adv_stop_execution(adv);
 		adv_reset_bus(adv, /*initiate_reset*/TRUE);
 		adv_start_execution(adv);
-		splx(s);
 
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
@@ -521,13 +505,14 @@ adv_execute_ccb(void *arg, bus_dma_segme
 	struct	adv_ccb_info *cinfo;
 	struct	adv_scsi_q scsiq;
 	struct	adv_sg_head sghead;
-	int	s;
 
 	csio = (struct ccb_scsiio *)arg;
 	ccb_h = &csio->ccb_h;
 	sim = xpt_path_sim(ccb_h->path);
 	adv = (struct adv_softc *)cam_sim_softc(sim);
 	cinfo = (struct adv_ccb_info *)csio->ccb_h.ccb_cinfo_ptr;
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 
 	/*
 	 * Setup our done routine to release the simq on
@@ -596,8 +581,6 @@ adv_execute_ccb(void *arg, bus_dma_segme
 		scsiq.sg_head = NULL;
 	}
 
-	s = splcam();
-
 	/*
 	 * Last time we need to check if this SCB needs to
 	 * be aborted.
@@ -608,7 +591,6 @@ adv_execute_ccb(void *arg, bus_dma_segme
 		adv_clear_state(adv, (union ccb *)csio);
 		adv_free_ccb_info(adv, cinfo);
 		xpt_done((union ccb *)csio);
-		splx(s);
 		return;
 	}
 
@@ -621,16 +603,14 @@ adv_execute_ccb(void *arg, bus_dma_segme
 		adv_clear_state(adv, (union ccb *)csio);
 		adv_free_ccb_info(adv, cinfo);
 		xpt_done((union ccb *)csio);
-		splx(s);
 		return;
 	}
 	cinfo->state |= ACCB_ACTIVE;
 	ccb_h->status |= CAM_SIM_QUEUED;
 	LIST_INSERT_HEAD(&adv->pending_ccbs, ccb_h, sim_links.le);
 	/* Schedule our timeout */
-	ccb_h->timeout_ch =
-	    timeout(adv_timeout, csio, (ccb_h->timeout * hz)/1000);
-	splx(s);
+	callout_reset(&cinfo->timer, ccb_h->timeout * hz /1000, adv_timeout,
+	    csio);
 }
 
 static struct adv_ccb_info *
@@ -641,11 +621,12 @@ adv_alloc_ccb_info(struct adv_softc *adv
 
 	cinfo = &adv->ccb_infos[adv->ccb_infos_allocated];
 	cinfo->state = ACCB_FREE;
+	callout_init_mtx(&cinfo->timer, &adv->lock, 0);
 	error = bus_dmamap_create(adv->buffer_dmat, /*flags*/0,
 				  &cinfo->dmamap);
 	if (error != 0) {
-		printf("%s: Unable to allocate CCB info "
-		       "dmamap - error %d\n", adv_name(adv), error);
+		device_printf(adv->dev, "Unable to allocate CCB info "
+		    "dmamap - error %d\n", error);
 		return (NULL);
 	}
 	adv->ccb_infos_allocated++;
@@ -655,28 +636,28 @@ adv_alloc_ccb_info(struct adv_softc *adv
 static void
 adv_destroy_ccb_info(struct adv_softc *adv, struct adv_ccb_info *cinfo)
 {
+
+	callout_drain(&cinfo->timer);
 	bus_dmamap_destroy(adv->buffer_dmat, cinfo->dmamap);
 }
 
 void
 adv_timeout(void *arg)
 {
-	int s;
 	union ccb *ccb;
 	struct adv_softc *adv;
-	struct adv_ccb_info *cinfo;
+	struct adv_ccb_info *cinfo, *cinfo2;
 
 	ccb = (union ccb *)arg;
 	adv = (struct adv_softc *)xpt_path_sim(ccb->ccb_h.path)->softc;
 	cinfo = (struct adv_ccb_info *)ccb->ccb_h.ccb_cinfo_ptr;
+	mtx_assert(&adv->lock, MA_OWNED);
 
 	xpt_print_path(ccb->ccb_h.path);
 	printf("Timed out\n");
 
-	s = splcam();
 	/* Have we been taken care of already?? */
 	if (cinfo == NULL || cinfo->state == ACCB_FREE) {
-		splx(s);
 		return;
 	}
 
@@ -702,7 +683,8 @@ adv_timeout(void *arg)
 
 		ccb_h = LIST_FIRST(&adv->pending_ccbs);
 		while (ccb_h != NULL) {
-			untimeout(adv_timeout, ccb_h, ccb_h->timeout_ch);
+			cinfo2 = ccb_h->ccb_cinfo_ptr;
+			callout_stop(&cinfo2->timer);
 			ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 		}
 
@@ -713,8 +695,7 @@ adv_timeout(void *arg)
 		adv_abort_ccb(adv, ccb->ccb_h.target_id,
 			      ccb->ccb_h.target_lun, ccb,
 			      CAM_CMD_TIMEOUT, /*queued_only*/FALSE);
-		ccb->ccb_h.timeout_ch =
-		    timeout(adv_timeout, ccb, 2 * hz);
+		callout_reset(&cinfo->timer, 2 * hz, adv_timeout, ccb);
 	} else {
 		/* Our attempt to perform an abort failed, go for a reset */
 		xpt_print_path(ccb->ccb_h.path);
@@ -724,11 +705,10 @@ adv_timeout(void *arg)
 		adv_reset_bus(adv, /*initiate_reset*/TRUE);
 	}
 	adv_start_execution(adv);
-	splx(s);
 }
 
 struct adv_softc *
-adv_alloc(device_t dev, bus_space_tag_t tag, bus_space_handle_t bsh)
+adv_alloc(device_t dev, struct resource *res, long offset)
 {
 	struct adv_softc *adv = device_get_softc(dev);
 
@@ -738,9 +718,9 @@ adv_alloc(device_t dev, bus_space_tag_t 
 	LIST_INIT(&adv->pending_ccbs);
 	SLIST_INIT(&adv->free_ccb_infos);
 	adv->dev = dev;
-	adv->unit = device_get_unit(dev);
-	adv->tag = tag;
-	adv->bsh = bsh;
+	adv->res = res;
+	adv->reg_off = offset;
+	mtx_init(&adv->lock, "adv", NULL, MTX_DEF);
 
 	return(adv);
 }
@@ -773,6 +753,7 @@ adv_free(struct adv_softc *adv)
 		if (adv->ccb_infos != NULL)
 			free(adv->ccb_infos, M_DEVBUF);
 	case 0:
+		mtx_destroy(&adv->lock);
 		break;
 	}
 }
@@ -786,6 +767,7 @@ adv_init(struct adv_softc *adv)
 	u_int16_t config_lsw;
 	u_int16_t config_msw;
 
+	mtx_lock(&adv->lock);
 	adv_lib_init(adv);
 
   	/*
@@ -794,14 +776,16 @@ adv_init(struct adv_softc *adv)
 	adv_write_lram_16(adv, ADV_HALTCODE_W, 0x00FE);
 	adv_stop_execution(adv);
 	if (adv_stop_chip(adv) == 0 || adv_is_chip_halted(adv) == 0) {
-		printf("adv%d: Unable to halt adapter. Initialization"
-		       "failed\n", adv->unit);
+		mtx_unlock(&adv->lock);
+		device_printf(adv->dev,
+		    "Unable to halt adapter. Initialization failed\n");
 		return (1);
 	}
 	ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
 	if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) {
-		printf("adv%d: Unable to set program counter. Initialization"
-		       "failed\n", adv->unit);
+		mtx_unlock(&adv->lock);
+		device_printf(adv->dev,
+		    "Unable to set program counter. Initialization failed\n");
 		return (1);
 	}
 
@@ -876,8 +860,8 @@ adv_init(struct adv_softc *adv)
 	} else {
 		u_int8_t sync_data;
 
-		printf("adv%d: Warning EEPROM Checksum mismatch. "
-		       "Using default device parameters\n", adv->unit);
+		device_printf(adv->dev, "Warning EEPROM Checksum mismatch. "
+		       "Using default device parameters\n");
 
 		/* Set reasonable defaults since we can't read the EEPROM */
 		adv->isa_dma_speed = /*ADV_DEF_ISA_DMA_SPEED*/1;
@@ -940,13 +924,15 @@ adv_init(struct adv_softc *adv)
 	 * to be 100% correct.
 	 */
 	if (adv_set_eeprom_config(adv, &eeprom_config) != 0)
-		printf("%s: WARNING! Failure writing to EEPROM.\n",
-		       adv_name(adv));
+		device_printf(adv->dev,
+		    "WARNING! Failure writing to EEPROM.\n");
 #endif
 
 	adv_set_chip_scsiid(adv, adv->scsi_id);
-	if (adv_init_lram_and_mcode(adv))
+	if (adv_init_lram_and_mcode(adv)) {
+		mtx_unlock(&adv->lock);
 		return (1);
+	}
 
 	adv->disc_enable = adv->user_disc_enable;
 
@@ -969,10 +955,12 @@ adv_init(struct adv_softc *adv)
 	}
 	adv_write_lram_8(adv, ADVV_USE_TAGGED_QNG_B, TARGET_BIT_VECTOR_SET);
 	adv_write_lram_8(adv, ADVV_CAN_TAGGED_QNG_B, TARGET_BIT_VECTOR_SET);
-	printf("adv%d: AdvanSys %s Host Adapter, SCSI ID %d, queue depth %d\n",
-	       adv->unit, (adv->type & ADV_ULTRA) && (max_sync == 0)
-			  ? "Ultra SCSI" : "SCSI",
-	       adv->scsi_id, adv->max_openings);
+	device_printf(adv->dev,
+	    "AdvanSys %s Host Adapter, SCSI ID %d, queue depth %d\n",
+	    (adv->type & ADV_ULTRA) && (max_sync == 0)
+	    ? "Ultra SCSI" : "SCSI",
+	    adv->scsi_id, adv->max_openings);
+	mtx_unlock(&adv->lock);
 	return (0);
 }
 
@@ -980,14 +968,24 @@ void
 adv_intr(void *arg)
 {
 	struct	  adv_softc *adv;
+
+	adv = arg;
+	mtx_lock(&adv->lock);
+	adv_intr_locked(adv);
+	mtx_unlock(&adv->lock);
+}
+
+void
+adv_intr_locked(struct adv_softc *adv)
+{
 	u_int16_t chipstat;
 	u_int16_t saved_ram_addr;
 	u_int8_t  ctrl_reg;
 	u_int8_t  saved_ctrl_reg;
 	u_int8_t  host_flag;
 
-	adv = (struct adv_softc *)arg;
-
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 	chipstat = ADV_INW(adv, ADV_CHIP_STATUS);
 
 	/* Is it for us? */
@@ -1000,7 +998,7 @@ adv_intr(void *arg)
 				       ADV_CC_TEST));
 
 	if ((chipstat & (ADV_CSW_SCSI_RESET_LATCH|ADV_CSW_SCSI_RESET_ACTIVE))) {
-		printf("Detected Bus Reset\n");
+		device_printf(adv->dev, "Detected Bus Reset\n");
 		adv_reset_bus(adv, /*initiate_reset*/FALSE);
 		return;
 	}
@@ -1128,9 +1126,11 @@ adv_done(struct adv_softc *adv, union cc
 {
 	struct	   adv_ccb_info *cinfo;
 
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 	cinfo = (struct adv_ccb_info *)ccb->ccb_h.ccb_cinfo_ptr;
 	LIST_REMOVE(&ccb->ccb_h, sim_links.le);
-	untimeout(adv_timeout, ccb, ccb->ccb_h.timeout_ch);
+	callout_stop(&cinfo->timer);
 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 		bus_dmasync_op_t op;
 
@@ -1239,7 +1239,7 @@ adv_done(struct adv_softc *adv, union cc
 		case QHSTA_M_MICRO_CODE_ERROR_HALT:
 		default:
 			panic("%s: Unhandled Host status error %x",
-			      adv_name(adv), host_stat);
+			    device_get_nameunit(adv->dev), host_stat);
 			/* NOTREACHED */
 		}
 		break;
@@ -1280,7 +1280,8 @@ adv_done(struct adv_softc *adv, union cc
 static void
 adv_poll(struct cam_sim *sim)
 {
-	adv_intr(cam_sim_softc(sim));
+
+	adv_intr_locked(cam_sim_softc(sim));
 }
 
 /*
@@ -1350,7 +1351,7 @@ adv_attach(adv)
 			/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
 			/* flags	*/ BUS_DMA_ALLOCNOW,
 			/* lockfunc	*/ busdma_lock_mutex,
-			/* lockarg	*/ &Giant,
+			/* lockarg	*/ &adv->lock,
 			&adv->buffer_dmat) != 0) {
 		return (ENXIO);
 	}
@@ -1371,7 +1372,7 @@ adv_attach(adv)
 			/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
 			/* flags	*/ 0,
 			/* lockfunc	*/ busdma_lock_mutex,
-			/* lockarg	*/ &Giant,
+			/* lockarg	*/ &adv->lock,
 			&adv->sense_dmat) != 0) {
 		return (ENXIO);
         }
@@ -1398,8 +1399,8 @@ adv_attach(adv)
 	 * Fire up the chip
 	 */
 	if (adv_start_chip(adv) != 1) {
-		printf("adv%d: Unable to start on board processor. Aborting.\n",
-		       adv->unit);
+		device_printf(adv->dev,
+		    "Unable to start on board processor. Aborting.\n");
 		return (ENXIO);
 	}
 
@@ -1413,8 +1414,8 @@ adv_attach(adv)
 	/*
 	 * Construct our SIM entry.
 	 */
-	adv->sim = cam_sim_alloc(adv_action, adv_poll, "adv", adv, adv->unit,
-				 &Giant, 1, adv->max_openings, devq);
+	adv->sim = cam_sim_alloc(adv_action, adv_poll, "adv", adv,
+	    device_get_unit(adv->dev), &adv->lock, 1, adv->max_openings, devq);
 	if (adv->sim == NULL)
 		return (ENOMEM);
 
@@ -1423,8 +1424,10 @@ adv_attach(adv)
 	 *
 	 * XXX Twin Channel EISA Cards???
 	 */
+	mtx_lock(&adv->lock);
 	if (xpt_bus_register(adv->sim, adv->dev, 0) != CAM_SUCCESS) {
 		cam_sim_free(adv->sim, /*free devq*/TRUE);
+		mtx_unlock(&adv->lock);
 		return (ENXIO);
 	}
 
@@ -1433,6 +1436,7 @@ adv_attach(adv)
 	    != CAM_REQ_CMP) {
 		xpt_bus_deregister(cam_sim_path(adv->sim));
 		cam_sim_free(adv->sim, /*free devq*/TRUE);
+		mtx_unlock(&adv->lock);
 		return (ENXIO);
 	}
 
@@ -1442,6 +1446,7 @@ adv_attach(adv)
 	csa.callback = advasync;
 	csa.callback_arg = adv;
 	xpt_action((union ccb *)&csa);
+	mtx_unlock(&adv->lock);
 	return (0);
 }
 MODULE_DEPEND(adv, cam, 1, 1, 1);

Modified: head/sys/dev/advansys/advansys.h
==============================================================================
--- head/sys/dev/advansys/advansys.h	Fri Oct 12 19:53:13 2012	(r241491)
+++ head/sys/dev/advansys/advansys.h	Fri Oct 12 21:31:44 2012	(r241492)
@@ -38,9 +38,7 @@
 
 #include <dev/advansys/advlib.h>
 
-struct adv_softc *	adv_alloc(device_t dev, bus_space_tag_t tag,
-				  bus_space_handle_t bsh);
-char *			adv_name(struct adv_softc *adv);
+struct adv_softc *	adv_alloc(device_t dev, struct resource *res, long offset);
 void			adv_map(void *arg, bus_dma_segment_t *segs,
 				int nseg, int error);
 void 			adv_free(struct adv_softc *adv);
@@ -50,6 +48,6 @@ int			adv_attach(struct adv_softc *adv);
 void			adv_done(struct adv_softc *adv, union ccb* ccb,
 				 u_int done_stat, u_int host_stat,
 				 u_int scsi_stat, u_int q_no);
-timeout_t		adv_timeout;
+void			adv_timeout(void *arg);
 
 #endif /* _ADVANSYS_H_ */

Modified: head/sys/dev/advansys/advlib.c
==============================================================================
--- head/sys/dev/advansys/advlib.c	Fri Oct 12 19:53:13 2012	(r241491)
+++ head/sys/dev/advansys/advlib.c	Fri Oct 12 21:31:44 2012	(r241492)
@@ -45,7 +45,10 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
 #include <sys/kernel.h>
+#include <sys/mutex.h>
 #include <sys/systm.h>
 
 #include <machine/bus.h>
@@ -298,6 +301,7 @@ advasync(void *callback_arg, u_int32_t c
 	struct adv_softc *adv;
 
 	adv = (struct adv_softc *)callback_arg;
+	mtx_assert(&adv->lock, MA_OWNED);
 	switch (code) {
 	case AC_FOUND_DEVICE:
 	{
@@ -460,12 +464,12 @@ adv_write_lram_16(struct adv_softc *adv,
  * found, 0 otherwise.
  */
 int                         
-adv_find_signature(bus_space_tag_t tag, bus_space_handle_t bsh)
+adv_find_signature(struct resource *res)
 {                            
 	u_int16_t signature;
 
-	if (bus_space_read_1(tag, bsh, ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) {
-		signature = bus_space_read_2(tag, bsh, ADV_SIGNATURE_WORD);
+	if (bus_read_1(res, ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) {
+		signature = bus_read_2(res, ADV_SIGNATURE_WORD);
 		if ((signature == ADV_1000_ID0W)
 		 || (signature == ADV_1000_ID0W_FIX))
 			return (1);
@@ -594,8 +598,8 @@ adv_init_lram_and_mcode(struct adv_softc
 	retval = adv_load_microcode(adv, 0, (u_int16_t *)adv_mcode,
 				    adv_mcode_size);
 	if (retval != adv_mcode_chksum) {
-		printf("adv%d: Microcode download failed checksum!\n",
-		       adv->unit);
+		device_printf(adv->dev,
+		    "Microcode download failed checksum!\n");
 		return (1);
 	}
 	
@@ -692,6 +696,8 @@ adv_execute_scsi_queue(struct adv_softc 
 	u_int8_t	sg_entry_cnt_minus_one;
 	u_int8_t	tid_no;
 
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 	scsiq->q1.q_no = 0;
 	retval = 1;  /* Default to error case */
 	target_ix = scsiq->q2.target_ix;
@@ -938,6 +944,8 @@ adv_isr_chip_halted(struct adv_softc *ad
 	u_int8_t	  q_cntl;
 	u_int8_t	  tid_no;
 
+	if (!dumping)
+		mtx_assert(&adv->lock, MA_OWNED);
 	int_halt_code = adv_read_lram_16(adv, ADVV_HALTCODE_W);
 	halt_qp = adv_read_lram_8(adv, ADVV_CURCDB_B);
 	halt_q_addr = ADV_QNO_TO_QADDR(halt_qp);
@@ -966,6 +974,7 @@ adv_isr_chip_halted(struct adv_softc *ad
 				     target_mask, tid_no);
 	} else if (int_halt_code == ADV_HALT_CHK_CONDITION) {
 		struct	  adv_target_transinfo* tinfo;
+		struct	  adv_ccb_info *cinfo;
 		union	  ccb *ccb;
 		u_int32_t cinfo_index;
 		u_int8_t  tag_code;
@@ -1008,6 +1017,7 @@ adv_isr_chip_halted(struct adv_softc *ad
 		 */
 		cinfo_index =
 		    adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
+		cinfo = &adv->ccb_infos[cinfo_index];
 		ccb = adv->ccb_infos[cinfo_index].ccb;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list