Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Oct 2012 15:59:14 +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: r241589 - head/sys/dev/aha
Message-ID:  <201210151559.q9FFxEtg022008@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Mon Oct 15 15:59:13 2012
New Revision: 241589
URL: http://svn.freebsd.org/changeset/base/241589

Log:
  Add locking to the aha(4) driver and mark it MPSAFE.
  - Remove use of explicit bus space handles and tags.
  
  Tested by:	no one

Modified:
  head/sys/dev/aha/aha.c
  head/sys/dev/aha/aha_isa.c
  head/sys/dev/aha/aha_mca.c
  head/sys/dev/aha/ahareg.h

Modified: head/sys/dev/aha/aha.c
==============================================================================
--- head/sys/dev/aha/aha.c	Mon Oct 15 15:26:00 2012	(r241588)
+++ head/sys/dev/aha/aha.c	Mon Oct 15 15:59:13 2012	(r241589)
@@ -147,6 +147,7 @@ static void		ahaallocccbs(struct aha_sof
 static bus_dmamap_callback_t ahaexecuteccb;
 static void		ahadone(struct aha_softc *aha, struct aha_ccb *accb,
 			       aha_mbi_comp_code_t comp_code);
+static void		aha_intr_locked(struct aha_softc *aha);
 
 /* Host adapter command functions */
 static int	ahareset(struct aha_softc* aha, int hard_reset);
@@ -168,7 +169,7 @@ static void	ahaaction(struct cam_sim *si
 static void	ahapoll(struct cam_sim *sim);
 
 /* Our timeout handler */
-static timeout_t ahatimeout;
+static void	ahatimeout(void *arg);
 
 /* Exported functions */
 void
@@ -179,11 +180,9 @@ aha_alloc(struct aha_softc *aha, int uni
 	SLIST_INIT(&aha->free_aha_ccbs);
 	LIST_INIT(&aha->pending_ccbs);
 	SLIST_INIT(&aha->sg_maps);
-	aha->unit = unit;
-	aha->tag = tag;
-	aha->bsh = bsh;
 	aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID;
 	aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID;
+	mtx_init(&aha->lock, "aha", NULL, MTX_DEF);
 }
 
 void
@@ -225,6 +224,7 @@ aha_free(struct aha_softc *aha)
 	case 0:
 		break;
 	}
+	mtx_destroy(&aha->lock);
 }
 
 /*
@@ -464,7 +464,7 @@ aha_init(struct aha_softc* aha)
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_24BIT,
 				/* flags	*/ BUS_DMA_ALLOCNOW,
 				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockarg	*/ &aha->lock,
 				&aha->buffer_dmat) != 0) {
 		goto error_exit;
 	}
@@ -484,8 +484,8 @@ aha_init(struct aha_softc* aha)
 				/* nsegments	*/ 1,
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_24BIT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&aha->mailbox_dmat) != 0) {
 		goto error_exit;
         }
@@ -523,8 +523,8 @@ aha_init(struct aha_softc* aha)
 				/* nsegments	*/ 1,
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_24BIT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&aha->ccb_dmat) != 0) {
 		goto error_exit;
         }
@@ -556,8 +556,8 @@ aha_init(struct aha_softc* aha)
 				/* nsegments	*/ 1,
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_24BIT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&aha->sg_dmat) != 0)
 		goto error_exit;
 
@@ -605,22 +605,27 @@ aha_attach(struct aha_softc *aha)
 	/*
 	 * Construct our SIM entry
 	 */
-	aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, aha->unit,
-	     &Giant, 2, tagged_dev_openings, devq);
+	aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha,
+	    device_get_unit(aha->dev), &aha->lock, 2, tagged_dev_openings,
+	    devq);
 	if (aha->sim == NULL) {
 		cam_simq_free(devq);
 		return (ENOMEM);
 	}
+	mtx_lock(&aha->lock);
 	if (xpt_bus_register(aha->sim, aha->dev, 0) != CAM_SUCCESS) {
 		cam_sim_free(aha->sim, /*free_devq*/TRUE);
+		mtx_unlock(&aha->lock);
 		return (ENXIO);
 	}
 	if (xpt_create_path(&aha->path, /*periph*/NULL, cam_sim_path(aha->sim),
 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 		xpt_bus_deregister(cam_sim_path(aha->sim));
 		cam_sim_free(aha->sim, /*free_devq*/TRUE);
+		mtx_unlock(&aha->lock);
 		return (ENXIO);
 	}
+	mtx_unlock(&aha->lock);
 
 	return (0);
 }
@@ -664,6 +669,7 @@ ahaallocccbs(struct aha_softc *aha)
 		next_ccb->sg_list = segs;
 		next_ccb->sg_list_phys = physaddr;
 		next_ccb->flags = ACCB_FREE;
+		callout_init_mtx(&next_ccb->timer, &aha->lock, 0);
 		error = bus_dmamap_create(aha->buffer_dmat, /*flags*/0,
 		    &next_ccb->dmamap);
 		if (error != 0)
@@ -685,9 +691,9 @@ ahaallocccbs(struct aha_softc *aha)
 static __inline void
 ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb)
 {
-	int s;
 
-	s = splcam();
+	if (!dumping)
+		mtx_assert(&aha->lock, MA_OWNED);
 	if ((accb->flags & ACCB_ACTIVE) != 0)
 		LIST_REMOVE(&accb->ccb->ccb_h, sim_links.le);
 	if (aha->resource_shortage != 0
@@ -698,16 +704,15 @@ ahafreeccb(struct aha_softc *aha, struct
 	accb->flags = ACCB_FREE;
 	SLIST_INSERT_HEAD(&aha->free_aha_ccbs, accb, links);
 	aha->active_ccbs--;
-	splx(s);
 }
 
 static struct aha_ccb*
 ahagetccb(struct aha_softc *aha)
 {
 	struct	aha_ccb* accb;
-	int	s;
 
-	s = splcam();
+	if (!dumping)
+		mtx_assert(&aha->lock, MA_OWNED);
 	if ((accb = SLIST_FIRST(&aha->free_aha_ccbs)) != NULL) {
 		SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links);
 		aha->active_ccbs++;
@@ -721,7 +726,6 @@ ahagetccb(struct aha_softc *aha)
 			aha->active_ccbs++;
 		}
 	}
-	splx(s);
 
 	return (accb);
 }
@@ -730,11 +734,11 @@ static void
 ahaaction(struct cam_sim *sim, union ccb *ccb)
 {
 	struct	aha_softc *aha;
-	int s;
 
 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahaaction\n"));
 
 	aha = (struct aha_softc *)cam_sim_softc(sim);
+	mtx_assert(&aha->lock, MA_OWNED);
 
 	switch (ccb->ccb_h.func_code) {
 	/* Common cases first */
@@ -747,9 +751,7 @@ ahaaction(struct cam_sim *sim, union ccb
 		 * Get an accb to use.
 		 */
 		if ((accb = ahagetccb(aha)) == NULL) {
-			s = splcam();
 			aha->resource_shortage = TRUE;
-			splx(s);
 			xpt_freeze_simq(aha->sim, /*count*/1);
 			ccb->ccb_h.status = CAM_REQUEUE_REQ;
 			xpt_done(ccb);
@@ -818,7 +820,6 @@ ahaaction(struct cam_sim *sim, union ccb
 					if ((ccbh->flags & CAM_DATA_PHYS)==0) {
 						int error;
 
-						s = splsoftvm();
 						error = bus_dmamap_load(
 						    aha->buffer_dmat,
 						    accb->dmamap,
@@ -840,7 +841,6 @@ ahaaction(struct cam_sim *sim, union ccb
 							csio->ccb_h.status |=
 							    CAM_RELEASE_SIMQ;
 						}
-						splx(s);
 					} else {
 						struct bus_dma_segment seg;
 
@@ -1017,7 +1017,6 @@ ahaexecuteccb(void *arg, bus_dma_segment
 	struct	 aha_ccb *accb;
 	union	 ccb *ccb;
 	struct	 aha_softc *aha;
-	int	 s;
 	uint32_t paddr;
 
 	accb = (struct aha_ccb *)arg;
@@ -1077,8 +1076,6 @@ ahaexecuteccb(void *arg, bus_dma_segment
 		ahautoa24(0, accb->hccb.data_addr);
 	}
 
-	s = splcam();
-
 	/*
 	 * Last time we need to check if this CCB needs to
 	 * be aborted.
@@ -1088,7 +1085,6 @@ ahaexecuteccb(void *arg, bus_dma_segment
 			bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
 		ahafreeccb(aha, accb);
 		xpt_done(ccb);
-		splx(s);
 		return;
 	}
 
@@ -1096,8 +1092,8 @@ ahaexecuteccb(void *arg, bus_dma_segment
 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
 	LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le);
 
-	ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb,
-	    (ccb->ccb_h.timeout * hz) / 1000);
+	callout_reset(&accb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+	    ahatimeout, accb);
 
 	/* Tell the adapter about this command */
 	if (aha->cur_outbox->action_code != AMBO_FREE) {
@@ -1111,7 +1107,7 @@ ahaexecuteccb(void *arg, bus_dma_segment
 		device_printf(aha->dev,
 		    "Encountered busy mailbox with %d out of %d "
 		    "commands active!!!", aha->active_ccbs, aha->max_ccbs);
-		untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch);
+		callout_stop(&aacb->timer);
 		if (nseg != 0)
 			bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
 		ahafreeccb(aha, accb);
@@ -1127,17 +1123,25 @@ ahaexecuteccb(void *arg, bus_dma_segment
 	aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
 
 	ahanextoutbox(aha);
-	splx(s);
 }
 
 void
 aha_intr(void *arg)
 {
 	struct	aha_softc *aha;
+
+	aha = arg;
+	mtx_lock(&aha->lock);
+	aha_intr_locked(aha);
+	mtx_unlock(&aha->lock);
+}
+
+void
+aha_intr_locked(struct aha_softc *aha)
+{
 	u_int	intstat;
 	uint32_t paddr;
 
-	aha = (struct aha_softc *)arg;
 	while (((intstat = aha_inb(aha, INTSTAT_REG)) & INTR_PENDING) != 0) {
 		if ((intstat & CMD_COMPLETE) != 0) {
 			aha->latched_status = aha_inb(aha, STATUS_REG);
@@ -1220,9 +1224,9 @@ ahadone(struct aha_softc *aha, struct ah
 				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 				ahadone(aha, pending_accb, AMBI_ERROR);
 			} else {
-				ccb_h->timeout_ch = timeout(ahatimeout,
-				    (caddr_t)pending_accb,
-				    (ccb_h->timeout * hz) / 1000);
+				callout_reset(&pending_accb->timer,
+				    (ccb_h->timeout * hz) / 1000,
+				    ahatimeout, pending_accb);
 				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 			}
 		}
@@ -1230,7 +1234,7 @@ ahadone(struct aha_softc *aha, struct ah
 		return;
 	}
 
-	untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch);
+	callout_stop(&accb->timer);
 
 	switch (comp_code) {
 	case AMBI_FREE:
@@ -1446,7 +1450,6 @@ aha_cmd(struct aha_softc *aha, aha_op_t 
 	u_int	saved_status;
 	u_int	intstat;
 	u_int	reply_buf_size;
-	int	s;
 	int	cmd_complete;
 	int	error;
 
@@ -1465,15 +1468,11 @@ aha_cmd(struct aha_softc *aha, aha_op_t 
 	 * and wait for all completions to occur if necessary.
 	 */
 	timeout = 10000;
-	s = splcam();
 	while (LIST_FIRST(&aha->pending_ccbs) != NULL && --timeout) {
 		/* Fire the interrupt handler in case interrupts are blocked */
 		aha_intr(aha);
-		splx(s);
 		DELAY(10);
-		s = splcam();
 	}
-	splx(s);
 
 	if (timeout == 0) {
 		device_printf(aha->dev, 
@@ -1516,10 +1515,8 @@ aha_cmd(struct aha_softc *aha, aha_op_t 
 	timeout = 10000;
 	while (param_len && --timeout) {
 		DELAY(100);
-		s = splcam();
 		status = aha_inb(aha, STATUS_REG);
 		intstat = aha_inb(aha, INTSTAT_REG);
-		splx(s);
 
 		if ((intstat & (INTR_PENDING|CMD_COMPLETE))
 		 == (INTR_PENDING|CMD_COMPLETE)) {
@@ -1553,10 +1550,8 @@ aha_cmd(struct aha_softc *aha, aha_op_t 
 	 */
 	while (cmd_complete == 0 && --cmd_timeout) {
 
-		s = splcam();
 		status = aha_inb(aha, STATUS_REG);
 		intstat = aha_inb(aha, INTSTAT_REG);
-		splx(s);
 
 		if (aha->command_cmp != 0) {
 			cmd_complete = 1;
@@ -1601,9 +1596,7 @@ aha_cmd(struct aha_softc *aha, aha_op_t 
 	 * Clear any pending interrupts.  Block interrupts so our
 	 * interrupt handler is not re-entered.
 	 */
-	s = splcam();
 	aha_intr(aha);
-	splx(s);
 
 	if (error != 0)
 		return (error);
@@ -1764,7 +1757,7 @@ ahamapsgs(void *arg, bus_dma_segment_t *
 static void
 ahapoll(struct cam_sim *sim)
 {
-	aha_intr(cam_sim_softc(sim));
+	aha_intr_locked(cam_sim_softc(sim));
 }
 
 static void
@@ -1773,23 +1766,20 @@ ahatimeout(void *arg)
 	struct aha_ccb	*accb;
 	union  ccb	*ccb;
 	struct aha_softc *aha;
-	int		 s;
 	uint32_t	paddr;
 	struct ccb_hdr *ccb_h;
 
 	accb = (struct aha_ccb *)arg;
 	ccb = accb->ccb;
 	aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr;
+	mtx_assert(&aha->lock, MA_OWNED);
 	xpt_print_path(ccb->ccb_h.path);
 	printf("CCB %p - timed out\n", (void *)accb);
 
-	s = splcam();
-
 	if ((accb->flags & ACCB_ACTIVE) == 0) {
 		xpt_print_path(ccb->ccb_h.path);
 		printf("CCB %p - timed out CCB already completed\n",
 		    (void *)accb);
-		splx(s);
 		return;
 	}
 
@@ -1814,7 +1804,7 @@ ahatimeout(void *arg)
 			struct aha_ccb *pending_accb;
 
 			pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
-			untimeout(ahatimeout, pending_accb, ccb_h->timeout_ch);
+			callout_stop(&pending_accb->timer);
 			ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 		}
 	}
@@ -1843,7 +1833,7 @@ ahatimeout(void *arg)
 		 * later which will attempt a bus reset.
 		 */
 		accb->flags |= ACCB_DEVICE_RESET;
-		ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb, 2 * hz);
+		callout_reset(&aacb->timer, 2 * hz, ahatimeout, accb);
 		aha->recovery_accb->hccb.opcode = INITIATOR_BUS_DEV_RESET;
 
 		/* No Data Transfer */
@@ -1860,17 +1850,18 @@ ahatimeout(void *arg)
 		aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
 		ahanextoutbox(aha);
 	}
-
-	splx(s);
 }
 
 int
 aha_detach(struct aha_softc *aha)
 {
+	mtx_lock(&aha->lock);
 	xpt_async(AC_LOST_DEVICE, aha->path, NULL);
 	xpt_free_path(aha->path);
 	xpt_bus_deregister(cam_sim_path(aha->sim));
 	cam_sim_free(aha->sim, /*free_devq*/TRUE);
+	mtx_unlock(&aha->lock);
+	/* XXX: Drain all timers? */
 	return (0);
 }
 MODULE_DEPEND(aha, cam, 1, 1, 1);

Modified: head/sys/dev/aha/aha_isa.c
==============================================================================
--- head/sys/dev/aha/aha_isa.c	Mon Oct 15 15:26:00 2012	(r241588)
+++ head/sys/dev/aha/aha_isa.c	Mon Oct 15 15:59:13 2012	(r241589)
@@ -109,7 +109,6 @@ aha_isa_probe(device_t dev)
 	struct	aha_softc *aha = device_get_softc(dev);
 	int	error;
 	u_long	port_start;
-	struct resource *port_res;
 	int	port_rid;
 	int	drq;
 	int	irq;
@@ -121,20 +120,19 @@ aha_isa_probe(device_t dev)
 		return (ENXIO);
 
 	port_rid = 0;
-	port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid,
-	    0, ~0, AHA_NREGS, RF_ACTIVE);
+	aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid,
+	    0ul, ~0ul, AHA_NREGS, RF_ACTIVE);
 
-	if (port_res == NULL)
+	if (aha->port == NULL)
 		return (ENXIO);
 
 	port_start = rman_get_start(port_res);
-	aha_alloc(aha, device_get_unit(dev), rman_get_bustag(port_res),
-	    rman_get_bushandle(port_res));
+	aha_alloc(aha);
 
 	/* See if there is really a card present */
 	if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
 		aha_free(aha);
-		bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);
+		bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port);
 		return (ENXIO);
 	}
 
@@ -151,11 +149,12 @@ aha_isa_probe(device_t dev)
 		    (uintmax_t)port_start);
 		aha_free(aha);
 		bus_release_resource(dev, SYS_RES_IOPORT, port_rid,
-		    port_res);
+		    aha->port);
 		return (ENXIO);
 	}
 
-	bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);
+	bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port);
+	aha->port = NULL;
 
 	switch (config_data.dma_chan) {
 	case DMA_CHAN_5:
@@ -188,17 +187,12 @@ static int
 aha_isa_attach(device_t dev)
 {
 	struct	aha_softc *aha = device_get_softc(dev);
-	bus_dma_filter_t *filter;
-	void		 *filter_arg;
-	bus_addr_t	 lowaddr;
-	void		 *ih;
 	int		 error = ENOMEM;
-	int		 aha_free_needed = 0;
 
 	aha->dev = dev;
 	aha->portrid = 0;
 	aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &aha->portrid,
-	    0, ~0, AHA_NREGS, RF_ACTIVE);
+	    0ul, ~0ul, AHA_NREGS, RF_ACTIVE);
 	if (!aha->port) {
 		device_printf(dev, "Unable to allocate I/O ports\n");
 		goto fail;
@@ -227,23 +221,19 @@ aha_isa_attach(device_t dev)
 	isa_dmacascade(rman_get_start(aha->drq));
 
 	/* Allocate our parent dmatag */
-	filter = NULL;
-	filter_arg = NULL;
-	lowaddr = BUS_SPACE_MAXADDR_24BIT;
-
 	if (bus_dma_tag_create(	/* parent	*/ bus_get_dma_tag(dev),
 				/* alignemnt	*/ 1,
 				/* boundary	*/ 0,
-				/* lowaddr	*/ lowaddr,
+				/* lowaddr	*/ BUS_SPACE_MAXADDR_24BIT,
 				/* highaddr	*/ BUS_SPACE_MAXADDR,
-				/* filter	*/ filter,
-				/* filterarg	*/ filter_arg,
+				/* filter	*/ NULL,
+				/* filterarg	*/ NULL,
 				/* maxsize	*/ BUS_SPACE_MAXSIZE_24BIT,
 				/* nsegments	*/ ~0,
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_24BIT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&aha->parent_dmat) != 0) {
 		device_printf(dev, "dma tag create failed.\n");
 		goto fail;
@@ -263,7 +253,6 @@ aha_isa_attach(device_t dev)
 		aha->ccb_sg_opcode = INITIATOR_SG_CCB;
 		aha->ccb_ccb_opcode = INITIATOR_CCB;
 	}
-	aha_free_needed++;
 	
 	error = aha_attach(aha);
 	if (error) {
@@ -271,20 +260,20 @@ aha_isa_attach(device_t dev)
 		goto fail;
 	}
 
-	error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY,
-	    NULL, aha_intr, aha, &ih);
+	error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY|
+	    INTR_MPSAFE, NULL, aha_intr, aha, &aha->ih);
 	if (error) {
 		device_printf(dev, "Unable to register interrupt handler\n");
+		aha_detach(aha);
                 goto fail;
 	}
 
 	return (0);
 fail: ;
+	aha_free(aha);
 	bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
 	bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
 	bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
-	if (aha_free_needed)
-		aha_free(aha);
 	return (error);
 }
 
@@ -298,16 +287,15 @@ aha_isa_detach(device_t dev)
 	if (error)
 		device_printf(dev, "failed to unregister interrupt handler\n");
 
-	bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
-	bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
-	bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
-
 	error = aha_detach(aha);
 	if (error) {
 		device_printf(dev, "detach failed\n");
 		return (error);
 	}
 	aha_free(aha);
+	bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
+	bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
+	bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
 
 	return (0);
 }
@@ -319,7 +307,6 @@ aha_isa_identify(driver_t *driver, devic
 	bus_addr_t ioport;
 	struct aha_softc aha;
 	int rid;
-	struct resource *res;
 	device_t child;
 
 	/* Attempt to find an adapter */
@@ -334,12 +321,11 @@ aha_isa_identify(driver_t *driver, devic
 		 * XXX kldload/kldunload.
 		 */
 		rid = 0;
-		res = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid,
+		aha->port = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid,
 		    ioport, ioport, AHA_NREGS, RF_ACTIVE);
-		if (res == NULL)
+		if (aha->port == NULL)
 			continue;
-		aha_alloc(&aha, -1, rman_get_bustag(res),
-		    rman_get_bushandle(res));
+		aha_alloc(&aha);
 		/* See if there is really a card present */
 		if (aha_probe(&aha) || aha_fetch_adapter_info(&aha))
 			goto not_this_one;
@@ -350,7 +336,7 @@ aha_isa_identify(driver_t *driver, devic
 		 * that.
 		 */
 	not_this_one:;
-		bus_release_resource(parent, SYS_RES_IOPORT, rid, res);
+		bus_release_resource(parent, SYS_RES_IOPORT, rid, aha->port);
 		aha_free(&aha);
 	}
 }

Modified: head/sys/dev/aha/aha_mca.c
==============================================================================
--- head/sys/dev/aha/aha_mca.c	Mon Oct 15 15:26:00 2012	(r241588)
+++ head/sys/dev/aha/aha_mca.c	Mon Oct 15 15:59:13 2012	(r241589)
@@ -118,8 +118,6 @@ aha_mca_attach (device_t dev)
 {
 	struct aha_softc *	sc = device_get_softc(dev);
 	int			error = ENOMEM;
-	int			unit = device_get_unit(dev);
-	void *			ih;
 
 	sc->portrid = 0;
 	sc->port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid,
@@ -145,8 +143,7 @@ aha_mca_attach (device_t dev)
 		goto bad;
 	}
 
-	aha_alloc(sc, unit, rman_get_bustag(sc->port),
-	    rman_get_bushandle(sc->port));
+	aha_alloc(sc);
 	error = aha_probe(sc);
 	if (error) {
 		device_printf(dev, "aha_probe() failed!\n");
@@ -173,8 +170,8 @@ aha_mca_attach (device_t dev)
 				/* nsegments	*/ ~0,
 				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_24BIT,
 				/* flags	*/ 0,
-				/* lockfunc	*/ busdma_lock_mutex,
-				/* lockarg	*/ &Giant,
+				/* lockfunc	*/ NULL,
+				/* lockarg	*/ NULL,
 				&sc->parent_dmat);
 	if (error) {
 		device_printf(dev, "bus_dma_tag_create() failed!\n");
@@ -193,10 +190,11 @@ aha_mca_attach (device_t dev)
 		goto bad;
 	}
 
-	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY,
-	    NULL, aha_intr, sc, &ih);
+	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY |
+	    INTR_MPSAFE, NULL, aha_intr, sc, &aha->ih);
 	if (error) {
 		device_printf(dev, "Unable to register interrupt handler\n");
+		aha_detach(sc);
 		goto bad;
 	}
 

Modified: head/sys/dev/aha/ahareg.h
==============================================================================
--- head/sys/dev/aha/ahareg.h	Mon Oct 15 15:26:00 2012	(r241588)
+++ head/sys/dev/aha/ahareg.h	Mon Oct 15 15:59:13 2012	(r241589)
@@ -297,6 +297,7 @@ struct aha_ccb {
 	uint32_t		 flags;
 	union ccb		*ccb;
 	bus_dmamap_t		 dmamap;
+	struct callout		 timer;
 	aha_sg_t		*sg_list;
 	uint32_t		 sg_list_phys;
 };
@@ -309,8 +310,6 @@ struct sg_map_node {
 };
 	
 struct aha_softc {
-	bus_space_tag_t		 tag;
-	bus_space_handle_t	 bsh;
 	struct	cam_sim		*sim;
 	struct	cam_path	*path;
 	aha_mbox_out_t		*cur_outbox;
@@ -368,11 +367,12 @@ struct aha_softc {
 	struct resource		*irq;
 	struct resource		*port;
 	struct resource		*drq;
-	int			irqrid;
-	int			portrid;
-	int			drqrid;
+	int			 irqrid;
+	int			 portrid;
+	int			 drqrid;
 	void			**ih;
 	device_t		 dev;
+	struct mtx		 lock;
 };
 
 void aha_alloc(struct aha_softc *, int, bus_space_tag_t, bus_space_handle_t);
@@ -390,10 +390,10 @@ int aha_probe(struct aha_softc *);
 #define DEFAULT_CMD_TIMEOUT 10000	/* 1 sec */
 
 #define aha_inb(aha, port)				\
-	bus_space_read_1((aha)->tag, (aha)->bsh, port)
+	bus_read_1((aha)->port, port)
 
 #define aha_outb(aha, port, value)			\
-	bus_space_write_1((aha)->tag, (aha)->bsh, port, value)
+	bus_write_1((aha)->port, port, value)
 
 #define ADP0100_PNP		0x00019004	/* ADP0100 */
 #define AHA1540_PNP		0x40159004	/* ADP1540 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210151559.q9FFxEtg022008>