Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Aug 2012 00:00:30 +0000 (UTC)
From:      Matt Jacob <mjacob@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r239023 - head/sys/dev/isp
Message-ID:  <201208040000.q7400UT9084673@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjacob
Date: Sat Aug  4 00:00:30 2012
New Revision: 239023
URL: http://svn.freebsd.org/changeset/base/239023

Log:
  Add detach logic to SBus variant.
  
  Obtained from:	Marius
  MFC after:	1 month

Modified:
  head/sys/dev/isp/isp_sbus.c

Modified: head/sys/dev/isp/isp_sbus.c
==============================================================================
--- head/sys/dev/isp/isp_sbus.c	Fri Aug  3 20:30:40 2012	(r239022)
+++ head/sys/dev/isp/isp_sbus.c	Sat Aug  4 00:00:30 2012	(r239023)
@@ -78,19 +78,22 @@ static struct ispmdvec mdvec = {
 
 static int isp_sbus_probe (device_t);
 static int isp_sbus_attach (device_t);
+static int isp_sbus_detach (device_t);
 
 
 #define	ISP_SBD(isp)	((struct isp_sbussoftc *)isp)->sbus_dev
 struct isp_sbussoftc {
 	ispsoftc_t			sbus_isp;
 	device_t			sbus_dev;
-	struct resource *		sbus_reg;
+	struct resource *		regs;
+	void *				irq;
+	int				iqd;
+	int				rgd;
 	void *				ih;
 	int16_t				sbus_poff[_NREG_BLKS];
 	sdparam				sbus_param;
 	struct isp_spi			sbus_spi;
 	struct ispmdvec			sbus_mdvec;
-	struct resource *		sbus_ires;
 };
 
 
@@ -98,6 +101,7 @@ static device_method_t isp_sbus_methods[
 	/* Device interface */
 	DEVMETHOD(device_probe,		isp_sbus_probe),
 	DEVMETHOD(device_attach,	isp_sbus_attach),
+	DEVMETHOD(device_detach,	isp_sbus_detach),
 	{ 0, 0 }
 };
 
@@ -136,13 +140,21 @@ isp_sbus_probe(device_t dev)
 static int
 isp_sbus_attach(device_t dev)
 {
-	struct resource *regs;
-	int tval, iqd, isp_debug, role, rid, ispburst, default_id;
+	int tval, isp_debug, role, ispburst, default_id;
 	struct isp_sbussoftc *sbs;
 	ispsoftc_t *isp = NULL;
 	int locksetup = 0;
 	int ints_setup = 0;
 
+	sbs = device_get_softc(dev);
+	if (sbs == NULL) {
+		device_printf(dev, "cannot get softc\n");
+		return (ENOMEM);
+	}
+
+	sbs->sbus_dev = dev;
+	sbs->sbus_mdvec = mdvec;
+
 	/*
 	 * Figure out if we're supposed to skip this one.
 	 * If we are, we actually go to ISP_ROLE_NONE.
@@ -165,23 +177,15 @@ isp_sbus_attach(device_t dev)
 		role = ISP_DEFAULT_ROLES;
 	}
 
-	sbs = malloc(sizeof (*sbs), M_DEVBUF, M_NOWAIT | M_ZERO);
-	if (sbs == NULL) {
-		device_printf(dev, "cannot allocate softc\n");
-		return (ENOMEM);
-	}
+	sbs->irq = sbs->regs = NULL;
+	sbs->rgd = sbs->iqd = 0;
 
-	regs = NULL;
-	iqd = 0;
-	rid = 0;
-	regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
-	if (regs == 0) {
+	sbs->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sbs->rgd,
+	    RF_ACTIVE);
+	if (sbs->regs == NULL) {
 		device_printf(dev, "unable to map registers\n");
 		goto bad;
 	}
-	sbs->sbus_dev = dev;
-	sbs->sbus_reg = regs;
-	sbs->sbus_mdvec = mdvec;
 
 	sbs->sbus_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
 	sbs->sbus_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = SBUS_MBOX_REGS_OFF;
@@ -189,8 +193,8 @@ isp_sbus_attach(device_t dev)
 	sbs->sbus_poff[RISC_BLOCK >> _BLK_REG_SHFT] = SBUS_RISC_REGS_OFF;
 	sbs->sbus_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
 	isp = &sbs->sbus_isp;
-	isp->isp_bus_tag = rman_get_bustag(regs);
-	isp->isp_bus_handle = rman_get_bushandle(regs);
+	isp->isp_bus_tag = rman_get_bustag(sbs->regs);
+	isp->isp_bus_handle = rman_get_bushandle(sbs->regs);
 	isp->isp_mdvec = &sbs->sbus_mdvec;
 	isp->isp_bustype = ISP_BT_SBUS;
 	isp->isp_type = ISP_HA_SCSI_UNKNOWN;
@@ -244,7 +248,6 @@ isp_sbus_attach(device_t dev)
 		SDPARAM(isp, 0)->isp_ptisp = 1;
 	}
 
-
 	isp->isp_osinfo.fw = firmware_get("isp_1000");
 	if (isp->isp_osinfo.fw) {
 		union {
@@ -280,16 +283,15 @@ isp_sbus_attach(device_t dev)
 	mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF);
 	locksetup++;
 
-	iqd = 0;
-	sbs->sbus_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
+	sbs->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sbs->iqd,
 	    RF_ACTIVE | RF_SHAREABLE);
-	if (sbs->sbus_ires == NULL) {
+	if (sbs->irq == NULL) {
 		device_printf(dev, "could not allocate interrupt\n");
 		goto bad;
 	}
 
-	if (isp_setup_intr(dev, sbs->sbus_ires, ISP_IFLAGS, NULL,
-	    isp_platform_intr, isp, &sbs->ih)) {
+	if (isp_setup_intr(dev, sbs->irq, ISP_IFLAGS, NULL, isp_platform_intr,
+	    isp, &sbs->ih)) {
 		device_printf(dev, "could not setup interrupt\n");
 		goto bad;
 	}
@@ -333,25 +335,49 @@ isp_sbus_attach(device_t dev)
 bad:
 
 	if (sbs && ints_setup) {
-		(void) bus_teardown_intr(dev, sbs->sbus_ires, sbs->ih);
+		(void) bus_teardown_intr(dev, sbs->irq, sbs->ih);
 	}
 
-	if (sbs && sbs->sbus_ires) {
-		bus_release_resource(dev, SYS_RES_IRQ, iqd, sbs->sbus_ires);
+	if (sbs && sbs->irq) {
+		bus_release_resource(dev, SYS_RES_IRQ, sbs->iqd, sbs->irq);
 	}
 
 	if (locksetup && isp) {
 		mtx_destroy(&isp->isp_osinfo.lock);
 	}
 
-	if (regs) {
-		(void) bus_release_resource(dev, SYS_RES_MEMORY, 0, regs);
+	if (sbs->regs) {
+		(void) bus_release_resource(dev, SYS_RES_MEMORY, sbs->rgd,
+		    sbs->regs);
 	}
+	return (ENXIO);
+}
 
-	if (sbs) {
-		free(sbs, M_DEVBUF);
+static int
+isp_sbus_detach(device_t dev)
+{
+	struct isp_sbussoftc *sbs;
+	ispsoftc_t *isp;
+	int status;
+
+	sbs = device_get_softc(dev);
+	if (sbs == NULL) {
+		return (ENXIO);
 	}
-	return (ENXIO);
+	isp = (ispsoftc_t *) sbs;
+	status = isp_detach(isp);
+	if (status)
+		return (status);
+	ISP_LOCK(isp);
+	isp_uninit(isp);
+	if (sbs->ih) {
+		(void) bus_teardown_intr(dev, sbs->irq, sbs->ih);
+	}
+	ISP_UNLOCK(isp);
+	mtx_destroy(&isp->isp_osinfo.lock);
+	(void) bus_release_resource(dev, SYS_RES_IRQ, sbs->iqd, sbs->irq);
+	(void) bus_release_resource(dev, SYS_RES_MEMORY, sbs->rgd, sbs->regs);
+	return (0);
 }
 
 #define	IspVirt2Off(a, x)	\



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