Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 01 Sep 2005 00:09:26 +0000
From:      Kyle Brooks <captinsmock@columbus.rr.com>
To:        Scott Long <scottl@samsco.org>
Cc:        freebsd-current@freebsd.org, ticso@cicely.de, Ben Kaduk <minimarmot@gmail.com>
Subject:   Re: panic after removing usb flash drive
Message-ID:  <1125533366.685.11.camel@arbitor.homelinux.com>
In-Reply-To: <4316370E.4030809@samsco.org>
References:  <1125452228.740.3.camel@arbitor.homelinux.com> <47d0403c05083020044f6ac0be@mail.gmail.com> <4315CEEC.80100@samsco.org> <20050831174631.GE37930@cicely12.cicely.de> <4315F15D.4090209@samsco.org> <20050831221535.GB670@cicely12.cicely.de> <4316370E.4030809@samsco.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--=-FYZp8LaGu/8HvL5hC1wt
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Wed, 2005-08-31 at 17:02 -0600, Scott Long wrote:
> Bernd Walter wrote:
> > On Wed, Aug 31, 2005 at 12:05:17PM -0600, Scott Long wrote:
> > 
> >>Bernd Walter wrote:
> >>
> >>>On Wed, Aug 31, 2005 at 09:38:20AM -0600, Scott Long wrote:
> >>>
> >>>>Ben Kaduk wrote:
> >>>>
> >>>>>On 8/31/05, Kyle Brooks <captinsmock@columbus.rr.com> wrote:
> >>>
> >>>This would really a step backward.
> >>>Originally we had LUN creation/deletion on shared SIM and lots of
> >>>different problems.
> >>>SIM deletion should really be fixed - not only for umass, but generally
> >>>as we live in a world with removeable cards.
> >>
> >>Bugs in the umass detach code are immediately responsible for the
> >>problem, but you are correct that CAM in general doesn't like SIMs
> >>going away.  DFly worked on this a while back, but I don't recall
> >>whether the work there was to add more sanity checks in the data
> >>path (which I don't want to do), or if it was the correct approach of
> >>flushing and quiescing the data/queuing, topology, and error recovery
> >>paths.
> > 
> > 
> > What bugs are you refering?
> 
> The CAM detach code should be returning EBUSY errors since the 'da'
> periph has open references to it.  I'm pretty sure that thse errors
> are being ignored by umass.c, leading to the SIM going away unexpectedly
> to CAM.
> 
> > Sample code on how to correctly detach a sim a sparse.
> > The umass code doesn't know that devices on a scbus are in use, or
> > should it?
> 
> Well, it doesn't need to right now because you only have one target
> per SIM.  It should though; most normal SCSI drivers keep a table of
> known devices in order to remember negotiated transfer settings and
> handle reconnections.
> 
> > I think with a single sim style the target remains a ghost device
> > as long as it is refered, right?
> 
> More or less, yes.  Periph drivers are refcounted and understand the
> idea of going away when a selection fails (i.e. the device got pulled
> from the bus).
> 
> > 
> > In the USB-world we have the problem that a blocking detach blocks
> > other port attachment/detachments on the same bus as well.
> > This is because we currently have a single thread per bus processing
> > these events.
> > We already see this problem with ucom devices where an open tty on a
> > detached device blocks.
> > But it is better than the panic that we have right now.
> > In the tty case we have a timeout, don't know what we can do with CAM.
> > 
> 
> In the sim-per-target model, you need to completely drain the simq and
> devq for the SIM before allowing detach to complete.  This means 
> freezing the simq then waiting until the camisr can run and process any
> pending CCBs on the completion queue.  The camisr is an SWI, so you'll
> need to sleep so that it can run.
> 
> > 
> >>>Technically a shared sim with using targets could be made work for
> >>>umass as it's defined today, but it won't work for USB to SCSI
> >>>converters - that we don't support one of these adapters today doesn't
> >>>solve the problem.
> >>
> >>This is a completely different situation.  A USB-SCSI adapter would
> >>provide its own SCSI bus that is separate from the USB bus with its
> >>own queueing resources and own error recovery mechanisms.
> > 
> > 
> > Many umass devices are ide converters - even some flash drives.
> > 
> > 
> >>>Is is a academical standpoint defining where in the USB/umass
> >>>infrastrukture the SIM is located, but I personally always saw it
> >>>inside the USB-device and not on the USB.
> >>>USB is just a transport medium and not a SIM in the same way as PCI is
> >>>just a transport medium for a classical SCSI-Interface.
> >>>Yes - umass creates a SIM, bus and targed, because that is what a user
> >>>really attaches/detaches.
> >>>
> >>
> >>It is muddy, but for a mass storage class device, you are using the
> >>USB bus as the transport medium and you are using the USB controller
> >>as the transport initiator.  Command queueing and resource arbitration
> >>happens in the USB controller and driver, not in the umass device or
> >>driver.  Same for error recovery.  The USB controller is essentially
> >>acting as a SCSI controller, just with a USB bus instead of a SPI bus.
> >>The whole point of CAM is to assist with queueing and arbitrating bus
> >>resources.  There is no way that the SIM-per-device approach can provide
> >>this information.
> > 
> > 
> > I can follow you to some degree.
> > With the single-sim design we have had the following problems:
> > - probing of LUNs filed on attach and required a manual rescan.
> >   undoubly fixable by someone with good CAM knowledge.
> 
> I'm not parsing this.  Are you referring to the need to do a rescan
> after plugging in a device?  This is easy to solve.  When a umass
> target is attached, you either send an AC_FOUND_DEVICE async event to
> announce the target, or you request a bus rescan from within the driver.
> I think that the ciss driver has an example of this.
> 
> > - CAM needs a max target value, but how many target do we really have?
> >   Each USB has up to 127 devices (pratically 100 useable as we need
> >   some hubs)
> 
> The max target value is really only important for bus rescans.  The SIM 
> can just track what targets it currently knows about and reject CCBs
> for ones that don't exist (it somewhat does this now, though with only
> one target per SIM it's kinda silly).  Setting the max target value to
> 127 and rejecting targets that don't exist won't slow down a bus rescan
> but much at all.
> 
> >   Each device can have multiple functions, which means multiple umass
> >   instances.
> 
> I have a umass device that is a CF+SD card reader.  It shows up in CAM
> as a single target with 2 LUNs.  Is this the kind of thing that you are
> talking about?  If so, then there is no reason not to continue to use
> the model of a single target with multiple LUNs.
> 
> >   Previously we had a small hardcoded number, too big numbers slow
> >   down bus rescans, too small restrict the number of possible devices.
> >   We should have a dynamic way.
> > Don't remember if ther were others.
> > 
> > From the technical standpoint - no matter what we do, there are
> > problems to solve.
> > 
> > 
> >>Your analogy of a PCI bus is correct for the USB-SCSI adapters, where 
> >>the adapter is doing a full conversion and bridge from one bus type to
> >>another.  It's not true for a umass device where it's merely using the
> >>USB bus as a SCSI transport.
> > 
> > 
> > So what is an USB-IDE converter?
> 
> I assumed that you were talking about devices that bridge from USB to
> IDE/SCSI and did not conform to the umass standard.  I have a USB2-IDE
> converter in an external exclosure that speaks umass and is probably
> closer to what you are talking about here.  But again, umass is really
> about using the USB bus to transport SCSI/ATA protocol, not about
> providing full access to a SCSI/IDE bus via a USB tunnel.  That is a
> significant difference, IMHO.  The USB controller is acting in a direct
> role as the SCSI/ATA initiator, vs. just tunnelling to a smart
> initiator.
> 
> > OK - that won't help for a practical solution.
> > In the practical way it sounded easier to go the multiple sim way.
> > sim detach needs to be fixed either way.
> 
> Yes.  It somewhat works now as long as the system is completely idle.
> It breaks down horribly if I/O or error recovery is in progress and
> a periph driver is left with CCBs in flight and/or a dangling
> reference to a SIM.  The only way to deal with this is to allow
> blocking while CAM drains itself.
> 
> > Are there any other technical reasons for doing single sim?
> > You've mentioned rescource arbitration and error recovery.
> > Is there anything that can CAM do for us that it won't with multiple
> > sim?
> > 
> 
> It means that you'll be able to detach umass targets without doing the
> complicated dance of sleeping for CAM to drain itself.  It also will
> mean that it's less fragile to edge cases that are hard to identify and
> deal with.  Fixing CAM detach so that this works reliably is definitely
> something that must be done, but you can't avoid sleeping in order for
> it to work.
> 
> Scott
> _______________________________________________
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"

I'm don't really know the mechanics of CAM, but just for the record this
flash drive works in 5.4, but CAM in current seems to give up after
about 10 minutes with this:

umass0: LEXAR MEDIA JUMPDRIVE2, rev 2.00/1.25, addr 2
(da0:umass-sim0:0:0:0): got CAM status 0x4
(da0:umass-sim0:0:0:0): fatal error, failed to attach to device
(da0:umass-sim0:0:0:0): lost device
(da0:umass-sim0:0:0:0): removing device entry
Opened disk da0 -> 5

sorry i missed this before, didn't keep it in that long, if it helps
attached is a diff file for CAM from 5.4 to current.

--=-FYZp8LaGu/8HvL5hC1wt
Content-Disposition: attachment; filename=cam.diff
Content-Type: text/x-patch; name=cam.diff; charset=us-ascii
Content-Transfer-Encoding: 7bit

diff -ru cam_old/cam.c cam_new/cam.c
--- cam_old/cam.c	Sun Jan 30 00:59:15 2005
+++ cam_new/cam.c	Wed Jan  5 22:34:34 2005
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/cam.c,v 1.8.4.1 2005/01/30 00:59:15 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/cam.c,v 1.9 2005/01/05 22:34:34 imp Exp $");
 
 #include <sys/param.h>
 #ifdef _KERNEL
diff -ru cam_old/cam.h cam_new/cam.h
--- cam_old/cam.h	Sun Jan 30 00:59:15 2005
+++ cam_new/cam.h	Wed Jan  5 22:34:34 2005
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam.h,v 1.10.8.1 2005/01/30 00:59:15 imp Exp $
+ * $FreeBSD: src/sys/cam/cam.h,v 1.11 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _CAM_CAM_H
diff -ru cam_old/cam_ccb.h cam_new/cam_ccb.h
--- cam_old/cam_ccb.h	Sun Jan 30 00:59:15 2005
+++ cam_new/cam_ccb.h	Wed Jan  5 22:34:34 2005
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_ccb.h,v 1.27.2.1 2005/01/30 00:59:15 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_ccb.h,v 1.28 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _CAM_CAM_CCB_H
diff -ru cam_old/cam_debug.h cam_new/cam_debug.h
--- cam_old/cam_debug.h	Sun Jan 30 00:59:15 2005
+++ cam_new/cam_debug.h	Wed Jan  5 22:34:34 2005
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_debug.h,v 1.7.8.1 2005/01/30 00:59:15 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_debug.h,v 1.8 2005/01/05 22:34:34 imp Exp $
  */
 #ifndef	_CAM_CAM_DEBUG_H
 #define _CAM_CAM_DEBUG_H 1
diff -ru cam_old/cam_periph.c cam_new/cam_periph.c
--- cam_old/cam_periph.c	Sat Mar 12 10:01:39 2005
+++ cam_new/cam_periph.c	Fri Jul  1 15:21:29 2005
@@ -28,12 +28,13 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/cam_periph.c,v 1.56.4.3 2005/03/12 10:01:39 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/cam_periph.c,v 1.60 2005/07/01 15:21:29 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/types.h>
 #include <sys/malloc.h>
+#include <sys/kernel.h>
 #include <sys/linker_set.h>
 #include <sys/bio.h>
 #include <sys/lock.h>
@@ -83,6 +84,8 @@
 static int nperiph_drivers;
 struct periph_driver **periph_drivers;
 
+MALLOC_DEFINE(M_CAMPERIPH, "CAM periph", "CAM peripheral buffers");
+
 void
 periphdriver_register(void *data)
 {
@@ -144,7 +147,7 @@
 		return (CAM_REQ_INVALID);
 	}
 	
-	periph = (struct cam_periph *)malloc(sizeof(*periph), M_DEVBUF,
+	periph = (struct cam_periph *)malloc(sizeof(*periph), M_CAMPERIPH,
 					     M_NOWAIT);
 
 	if (periph == NULL)
@@ -220,7 +223,7 @@
 		xpt_free_path(periph->path);
 		/* FALLTHROUGH */
 	case 1:
-		free(periph, M_DEVBUF);
+		free(periph, M_CAMPERIPH);
 		/* FALLTHROUGH */
 	case 0:
 		/* No cleanup to perform. */
@@ -485,7 +488,7 @@
 					  periph->path, arg);
 	}
 	xpt_free_path(periph->path);
-	free(periph, M_DEVBUF);
+	free(periph, M_CAMPERIPH);
 }
 
 /*
diff -ru cam_old/cam_periph.h cam_new/cam_periph.h
--- cam_old/cam_periph.h	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_periph.h	Wed Jan  5 22:34:34 2005
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_periph.h,v 1.14.2.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_periph.h,v 1.16 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _CAM_CAM_PERIPH_H
@@ -81,8 +81,7 @@
 };
 
 typedef enum {
-	CAM_PERIPH_BIO,
-	CAM_PERIPH_NET
+	CAM_PERIPH_BIO
 } cam_periph_type;
 
 /* Generically usefull offsets into the peripheral private area */
diff -ru cam_old/cam_queue.c cam_new/cam_queue.c
--- cam_old/cam_queue.c	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_queue.c	Fri Jul  1 15:21:29 2005
@@ -27,18 +27,23 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/cam_queue.c,v 1.7.4.1 2005/01/30 00:59:16 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/cam_queue.c,v 1.9 2005/07/01 15:21:29 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/types.h>
 #include <sys/malloc.h>
+#include <sys/kernel.h>
 
 #include <cam/cam.h>
 #include <cam/cam_ccb.h>
 #include <cam/cam_queue.h>
 #include <cam/cam_debug.h>
 
+MALLOC_DEFINE(M_CAMQ, "CAM queue", "CAM queue buffers");
+MALLOC_DEFINE(M_CAMDEVQ, "CAM dev queue", "CAM dev queue buffers");
+MALLOC_DEFINE(M_CAMCCBQ, "CAM ccb queue", "CAM ccb queue buffers");
+
 static __inline int
 		queue_cmp(cam_pinfo **queue_array, int i, int j);
 static __inline void
@@ -52,10 +57,10 @@
 {
 	struct camq *camq;
 
-	camq = (struct camq *)malloc(sizeof(*camq), M_DEVBUF, M_NOWAIT);
+	camq = (struct camq *)malloc(sizeof(*camq), M_CAMQ, M_NOWAIT);
 	if (camq != NULL) {
 		if (camq_init(camq, size) != 0) {
-			free(camq, M_DEVBUF);
+			free(camq, M_CAMQ);
 			camq = NULL;
 		}
 	}
@@ -69,7 +74,7 @@
 	camq->array_size = size;
 	if (camq->array_size != 0) {
 		camq->queue_array = (cam_pinfo**)malloc(size*sizeof(cam_pinfo*),
-							M_DEVBUF, M_NOWAIT);
+							M_CAMQ, M_NOWAIT);
 		if (camq->queue_array == NULL) {
 			printf("camq_init: - cannot malloc array!\n");
 			return (1);
@@ -94,7 +99,7 @@
 {
 	if (queue != NULL) {
 		camq_fini(queue);
-		free(queue, M_DEVBUF);
+		free(queue, M_CAMQ);
 	}
 }
 
@@ -107,7 +112,7 @@
 		 * our pointer into the heap array is offset by one element.
 		 */
 		queue->queue_array++;
-		free(queue->queue_array, M_DEVBUF);
+		free(queue->queue_array, M_CAMQ);
 	}
 }
 
@@ -122,7 +127,7 @@
 		      "queued entries.");
 #endif
 	new_array = (cam_pinfo **)malloc(new_size * sizeof(cam_pinfo *),
-					 M_DEVBUF, M_NOWAIT);
+					 M_CAMQ, M_NOWAIT);
 	if (new_array == NULL) {
 		/* Couldn't satisfy request */
 		return (CAM_RESRC_UNAVAIL);
@@ -136,7 +141,7 @@
 		queue->queue_array++;
 		bcopy(queue->queue_array, new_array,
 		      queue->entries * sizeof(cam_pinfo *));
-		free(queue->queue_array, M_DEVBUF);
+		free(queue->queue_array, M_CAMQ);
 	}
 	queue->queue_array = new_array-1;
 	queue->array_size = new_size;
@@ -210,13 +215,13 @@
 {
 	struct cam_devq *devq;
 
-	devq = (struct cam_devq *)malloc(sizeof(*devq), M_DEVBUF, M_NOWAIT);
+	devq = (struct cam_devq *)malloc(sizeof(*devq), M_CAMDEVQ, M_NOWAIT);
 	if (devq == NULL) {
 		printf("cam_devq_alloc: - cannot malloc!\n");
 		return (NULL);
 	}
 	if (cam_devq_init(devq, devices, openings) != 0) {
-		free(devq, M_DEVBUF);
+		free(devq, M_CAMDEVQ);
 		return (NULL);		
 	}
 	
@@ -246,7 +251,7 @@
 {
 	camq_fini(&devq->alloc_queue);
 	camq_fini(&devq->send_queue);
-	free(devq, M_DEVBUF);
+	free(devq, M_CAMDEVQ);
 }
 
 u_int32_t
@@ -267,13 +272,13 @@
 {
 	struct cam_ccbq *ccbq;
 
-	ccbq = (struct cam_ccbq *)malloc(sizeof(*ccbq), M_DEVBUF, M_NOWAIT);
+	ccbq = (struct cam_ccbq *)malloc(sizeof(*ccbq), M_CAMCCBQ, M_NOWAIT);
 	if (ccbq == NULL) {
 		printf("cam_ccbq_alloc: - cannot malloc!\n");
 		return (NULL);
 	}
 	if (cam_ccbq_init(ccbq, openings) != 0) {
-		free(ccbq, M_DEVBUF);
+		free(ccbq, M_CAMCCBQ);
 		return (NULL);		
 	}
 	
@@ -285,7 +290,7 @@
 {
 	if (ccbq) {
 		camq_fini(&ccbq->queue);
-		free(ccbq, M_DEVBUF);
+		free(ccbq, M_CAMCCBQ);
 	}
 }
 
diff -ru cam_old/cam_queue.h cam_new/cam_queue.h
--- cam_old/cam_queue.h	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_queue.h	Wed Jan  5 22:34:34 2005
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_queue.h,v 1.8.8.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_queue.h,v 1.9 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _CAM_CAM_QUEUE_H
diff -ru cam_old/cam_sim.c cam_new/cam_sim.c
--- cam_old/cam_sim.c	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_sim.c	Wed Aug 31 21:25:59 2005
@@ -1,4 +1,4 @@
-/*-
+/*
  * Common functions for SCSI Interface Modules (SIMs).
  *
  * Copyright (c) 1997 Justin T. Gibbs.
@@ -27,11 +27,12 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/cam_sim.c,v 1.7.4.1 2005/01/30 00:59:16 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/cam_sim.c,v 1.9 2005/07/01 15:21:29 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
+#include <sys/kernel.h>
 
 #include <cam/cam.h>
 #include <cam/cam_ccb.h>
@@ -40,6 +41,8 @@
 
 #define CAM_PATH_ANY (u_int32_t)-1
 
+MALLOC_DEFINE(M_CAMSIM, "CAM SIM", "CAM SIM buffers");
+
 struct cam_devq *
 cam_simq_alloc(u_int32_t max_sim_transactions)
 {
@@ -68,10 +71,10 @@
 	 */
 	if (strcmp(sim_name, "xpt") == 0)
 		sim = (struct cam_sim *)malloc(sizeof(struct cam_sim),
-					       M_DEVBUF, M_WAITOK);
+					       M_CAMSIM, M_WAITOK);
 	else
 		sim = (struct cam_sim *)malloc(sizeof(struct cam_sim),
-					       M_DEVBUF, M_NOWAIT);
+					       M_CAMSIM, M_NOWAIT);
 
 	if (sim != NULL) {
 		sim->sim_action = sim_action;
@@ -96,7 +99,7 @@
 {
 	if (free_devq)
 		cam_simq_free(sim->devq);
-	free(sim, M_DEVBUF);
+	free(sim, M_CAMSIM);
 }
 
 void
diff -ru cam_old/cam_sim.h cam_new/cam_sim.h
--- cam_old/cam_sim.h	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_sim.h	Wed Jan  5 22:34:34 2005
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_sim.h,v 1.5.8.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_sim.h,v 1.6 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _CAM_CAM_SIM_H
diff -ru cam_old/cam_xpt.c cam_new/cam_xpt.c
--- cam_old/cam_xpt.c	Fri Apr  1 12:44:03 2005
+++ cam_new/cam_xpt.c	Fri Jul  1 15:21:29 2005
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/cam_xpt.c,v 1.142.2.4 2005/04/01 12:44:03 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/cam_xpt.c,v 1.155 2005/07/01 15:21:29 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -43,6 +43,9 @@
 #include <sys/interrupt.h>
 #include <sys/sbuf.h>
 
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
 #ifdef PC98
 #include <pc98/pc98/pc98_machdep.h>	/* geometry translation */
 #endif
@@ -62,6 +65,7 @@
 #include "opt_cam.h"
 
 /* Datastructures internal to the xpt layer */
+MALLOC_DEFINE(M_CAMXPT, "CAM XPT", "CAM XPT buffers");
 
 /*
  * Definition of an async handler callback block.  These are used to add
@@ -200,10 +204,20 @@
 #define	CAM_QUIRK_NOLUNS	0x01
 #define	CAM_QUIRK_NOSERIAL	0x02
 #define	CAM_QUIRK_HILUNS	0x04
+#define	CAM_QUIRK_NOHILUNS	0x08
 	u_int mintags;
 	u_int maxtags;
 };
 #define	CAM_SCSI2_MAXLUN	8
+/*
+ * If we're not quirked to search <= the first 8 luns
+ * and we are either quirked to search above lun 8,
+ * or we're > SCSI-2, we can look for luns above lun 8.
+ */
+#define	CAN_SRCH_HI(dv)					\
+  (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0) 	\
+  && ((dv->quirk->quirks & CAM_QUIRK_HILUNS)		\
+  || SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2))
 
 typedef enum {
 	XPT_FLAG_OPEN		= 0x01
@@ -552,6 +566,11 @@
 		CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/0
 	},
 	{
+		/* EasyRAID E5A aka. areca ARC-6010 */
+		{ T_DIRECT, SIP_MEDIA_FIXED, "easyRAID", "*", "*" },
+		  CAM_QUIRK_NOHILUNS, /*mintags*/2, /*maxtags*/255
+	},
+	{
 		/* Default tagged queuing parameters for all devices */
 		{
 		  T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
@@ -599,7 +618,7 @@
 /* Queues for our software interrupt handler */
 typedef TAILQ_HEAD(cam_isrq, ccb_hdr) cam_isrq_t;
 static cam_isrq_t cam_bioq;
-static cam_isrq_t cam_netq;
+static struct mtx cam_bioq_lock;
 
 /* "Pool" of inactive ccbs managed by xpt_alloc_ccb and xpt_free_ccb */
 static SLIST_HEAD(,ccb_hdr) ccb_freeq;
@@ -659,7 +678,6 @@
 #endif
 
 /* Pointers to software interrupt handlers */
-static void *camnet_ih;
 static void *cambio_ih;
 
 #if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG)
@@ -1368,10 +1386,11 @@
 
 	TAILQ_INIT(&xpt_busses);
 	TAILQ_INIT(&cam_bioq);
-	TAILQ_INIT(&cam_netq);
 	SLIST_INIT(&ccb_freeq);
 	STAILQ_INIT(&highpowerq);
 
+	mtx_init(&cam_bioq_lock, "CAM BIOQ lock", NULL, MTX_DEF);
+
 	/*
 	 * The xpt layer is, itself, the equivelent of a SIM.
 	 * Allow 16 ccbs in the ccb pool for it.  This should
@@ -1430,7 +1449,6 @@
 	}
 
 	/* Install our software interrupt handlers */
-	swi_add(NULL, "camnet", camisr, &cam_netq, SWI_CAMNET, 0, &camnet_ih);
 	swi_add(NULL, "cambio", camisr, &cam_bioq, SWI_CAMBIO, 0, &cambio_ih);
 }
 
@@ -3384,12 +3402,12 @@
 				SLIST_REMOVE(async_head, cur_entry,
 					     async_node, links);
 				csa->ccb_h.path->device->refcount--;
-				free(cur_entry, M_DEVBUF);
+				free(cur_entry, M_CAMXPT);
 			} else {
 				cur_entry->event_enable = csa->event_enable;
 			}
 		} else {
-			cur_entry = malloc(sizeof(*cur_entry), M_DEVBUF,
+			cur_entry = malloc(sizeof(*cur_entry), M_CAMXPT,
 					   M_NOWAIT);
 			if (cur_entry == NULL) {
 				splx(s);
@@ -3611,7 +3629,6 @@
 	   && (--timeout > 0)) {
 		DELAY(1000);
 		(*(sim->sim_poll))(sim);
-		camisr(&cam_netq);
 		camisr(&cam_bioq);
 	}
 	
@@ -3622,7 +3639,6 @@
 		xpt_action(start_ccb);
 		while(--timeout > 0) {
 			(*(sim->sim_poll))(sim);
-			camisr(&cam_netq);
 			camisr(&cam_bioq);
 			if ((start_ccb->ccb_h.status  & CAM_STATUS_MASK)
 			    != CAM_REQ_INPROG)
@@ -4000,7 +4016,7 @@
 
 	GIANT_REQUIRED;
 
-	path = (struct cam_path *)malloc(sizeof(*path), M_DEVBUF, M_NOWAIT);
+	path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_NOWAIT);
 
 	if (path == NULL) {
 		status = CAM_RESRC_UNAVAIL;
@@ -4008,7 +4024,7 @@
 	}
 	status = xpt_compile_path(path, perph, path_id, target_id, lun_id);
 	if (status != CAM_REQ_CMP) {
-		free(path, M_DEVBUF);
+		free(path, M_CAMXPT);
 		path = NULL;
 	}
 	*new_path_ptr = path;
@@ -4114,7 +4130,7 @@
 
 	CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_free_path\n"));
 	xpt_release_path(path);
-	free(path, M_DEVBUF);
+	free(path, M_CAMXPT);
 }
 
 
@@ -4340,7 +4356,7 @@
 
 	sim->bus_id = bus;
 	new_bus = (struct cam_eb *)malloc(sizeof(*new_bus),
-					  M_DEVBUF, M_NOWAIT);
+					  M_CAMXPT, M_NOWAIT);
 	if (new_bus == NULL) {
 		/* Couldn't satisfy request */
 		return (CAM_RESRC_UNAVAIL);
@@ -4822,8 +4838,6 @@
 {
 	int s;
 
-	GIANT_REQUIRED;
-
 	s = splcam();
 
 	CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_done\n"));
@@ -4834,17 +4848,16 @@
 		 */
 		switch (done_ccb->ccb_h.path->periph->type) {
 		case CAM_PERIPH_BIO:
+			mtx_lock(&cam_bioq_lock);
 			TAILQ_INSERT_TAIL(&cam_bioq, &done_ccb->ccb_h,
 					  sim_links.tqe);
 			done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
+			mtx_unlock(&cam_bioq_lock);
 			swi_sched(cambio_ih, 0);
 			break;
-		case CAM_PERIPH_NET:
-			TAILQ_INSERT_TAIL(&cam_netq, &done_ccb->ccb_h,
-					  sim_links.tqe);
-			done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
-			swi_sched(camnet_ih, 0);
-			break;
+		default:
+			panic("unknown periph type %d",
+			    done_ccb->ccb_h.path->periph->type);
 		}
 	}
 	splx(s);
@@ -4857,14 +4870,25 @@
 
 	GIANT_REQUIRED;
 
-	new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_WAITOK);
+	new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_WAITOK);
+	return (new_ccb);
+}
+
+union ccb *
+xpt_alloc_ccb_nowait()
+{
+	union ccb *new_ccb;
+
+	GIANT_REQUIRED;
+
+	new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_NOWAIT);
 	return (new_ccb);
 }
 
 void
 xpt_free_ccb(union ccb *free_ccb)
 {
-	free(free_ccb, M_DEVBUF);
+	free(free_ccb, M_CAMXPT);
 }
 
 
@@ -4886,7 +4910,7 @@
 
 	s = splsoftcam();
 	if ((new_ccb = (union ccb *)SLIST_FIRST(&ccb_freeq)) == NULL) {
-		new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_NOWAIT);
+		new_ccb = xpt_alloc_ccb_nowait();
                 if (new_ccb == NULL) {
 			splx(s);
 			return (NULL);
@@ -4913,7 +4937,7 @@
 		TAILQ_REMOVE(&xpt_busses, bus, links);
 		bus_generation++;
 		splx(s);
-		free(bus, M_DEVBUF);
+		free(bus, M_CAMXPT);
 	} else
 		splx(s);
 }
@@ -4923,7 +4947,7 @@
 {
 	struct cam_et *target;
 
-	target = (struct cam_et *)malloc(sizeof(*target), M_DEVBUF, M_NOWAIT);
+	target = (struct cam_et *)malloc(sizeof(*target), M_CAMXPT, M_NOWAIT);
 	if (target != NULL) {
 		struct cam_et *cur_target;
 
@@ -4965,7 +4989,7 @@
 		TAILQ_REMOVE(&bus->et_entries, target, links);
 		bus->generation++;
 		splx(s);
-		free(target, M_DEVBUF);
+		free(target, M_CAMXPT);
 		xpt_release_bus(bus);
 	} else
 		splx(s);
@@ -4989,7 +5013,7 @@
 		device = NULL;
 	} else {
 		device = (struct cam_ed *)malloc(sizeof(*device),
-						 M_DEVBUF, M_NOWAIT);
+						 M_CAMXPT, M_NOWAIT);
 	}
 
 	if (device != NULL) {
@@ -5003,13 +5027,13 @@
 		device->lun_id = lun_id;
 		/* Initialize our queues */
 		if (camq_init(&device->drvq, 0) != 0) {
-			free(device, M_DEVBUF);
+			free(device, M_CAMXPT);
 			return (NULL);
 		}
 		if (cam_ccbq_init(&device->ccbq,
 				  bus->sim->max_dev_openings) != 0) {
 			camq_fini(&device->drvq);
-			free(device, M_DEVBUF);
+			free(device, M_CAMXPT);
 			return (NULL);
 		}
 		SLIST_INIT(&device->asyncs);
@@ -5095,7 +5119,9 @@
 		devq = bus->sim->devq;
 		cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
 		splx(s);
-		free(device, M_DEVBUF);
+		camq_fini(&device->drvq);
+		camq_fini(&device->ccbq.queue);
+		free(device, M_CAMXPT);
 		xpt_release_target(bus, target);
 	} else
 		splx(s);
@@ -5308,7 +5334,7 @@
 			s = splcam();
 			device = TAILQ_FIRST(&target->ed_entries);
 			if (device != NULL) {
-				phl = device->quirk->quirks & CAM_QUIRK_HILUNS;
+				phl = CAN_SRCH_HI(device);
 				if (device->lun_id == 0)
 					device = TAILQ_NEXT(device, links);
 			}
@@ -5324,8 +5350,8 @@
 
 			if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) {
 				/* Try the next lun */
-				if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
-				    (device->quirk->quirks & CAM_QUIRK_HILUNS))
+				if (lun_id < (CAM_SCSI2_MAXLUN-1)
+				  || CAN_SRCH_HI(device))
 					lun_id++;
 			}
 		}
@@ -5351,7 +5377,6 @@
 			struct cam_path *path;
 			cam_status status;
 
-			path = request_ccb->ccb_h.path;
 			status = xpt_create_path(&path, xpt_periph,
 						 path_id, target_id, lun_id);
 			if (status != CAM_REQ_CMP) {
@@ -5367,8 +5392,8 @@
 					free(scan_info, M_TEMP);
 					request_ccb->ccb_h.status = CAM_REQ_CMP;
 					xpt_done(request_ccb);
-					break;
 				}
+				break;
 			}
 			xpt_setup_ccb(&request_ccb->ccb_h, path,
 				      request_ccb->ccb_h.pinfo.priority);
@@ -5944,7 +5969,7 @@
 
 		/* Clean up from previous instance of this device */
 		if (path->device->serial_num != NULL) {
-			free(path->device->serial_num, M_DEVBUF);
+			free(path->device->serial_num, M_CAMXPT);
 			path->device->serial_num = NULL;
 			path->device->serial_num_len = 0;
 		}
@@ -5959,7 +5984,7 @@
 			have_serialnum = 1;
 			path->device->serial_num =
 				(u_int8_t *)malloc((serial_buf->length + 1),
-						   M_DEVBUF, M_NOWAIT);
+						   M_CAMXPT, M_NOWAIT);
 			if (path->device->serial_num != NULL) {
 				bcopy(serial_buf->serial_num,
 				      path->device->serial_num,
@@ -6978,15 +7003,26 @@
 static void
 camisr(void *V_queue)
 {
-	cam_isrq_t *queue = V_queue;
+	cam_isrq_t *oqueue = V_queue;
+	cam_isrq_t queue;
 	int	s;
 	struct	ccb_hdr *ccb_h;
 
+	/*
+	 * Transfer the ccb_bioq list to a temporary list so we can operate
+	 * on it without needing to lock/unlock on every loop.  The concat
+	 * function with re-init the real list for us.
+	 */
 	s = splcam();
-	while ((ccb_h = TAILQ_FIRST(queue)) != NULL) {
+	mtx_lock(&cam_bioq_lock);
+	TAILQ_INIT(&queue);
+	TAILQ_CONCAT(&queue, oqueue, sim_links.tqe);
+	mtx_unlock(&cam_bioq_lock);
+
+	while ((ccb_h = TAILQ_FIRST(&queue)) != NULL) {
 		int	runq;
 
-		TAILQ_REMOVE(queue, ccb_h, sim_links.tqe);
+		TAILQ_REMOVE(&queue, ccb_h, sim_links.tqe);
 		ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
 		splx(s);
 
diff -ru cam_old/cam_xpt.h cam_new/cam_xpt.h
--- cam_old/cam_xpt.h	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_xpt.h	Wed Jan  5 22:34:34 2005
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_xpt.h,v 1.4.8.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_xpt.h,v 1.5 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _CAM_CAM_XPT_H
diff -ru cam_old/cam_xpt_periph.h cam_new/cam_xpt_periph.h
--- cam_old/cam_xpt_periph.h	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_xpt_periph.h	Fri Jul  1 15:21:29 2005
@@ -27,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_xpt_periph.h,v 1.3.26.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_xpt_periph.h,v 1.5 2005/07/01 15:21:29 avatar Exp $
  */
 
 #ifndef _CAM_CAM_XPT_PERIPH_H
@@ -39,6 +39,7 @@
 #ifdef _KERNEL
 void		xpt_polled_action(union ccb *ccb);
 union ccb	*xpt_alloc_ccb(void);
+union ccb	*xpt_alloc_ccb_nowait(void);
 void		xpt_free_ccb(union ccb *free_ccb);
 void		xpt_release_ccb(union ccb *released_ccb);
 void		xpt_schedule(struct cam_periph *perph, u_int32_t new_priority);
diff -ru cam_old/cam_xpt_sim.h cam_new/cam_xpt_sim.h
--- cam_old/cam_xpt_sim.h	Sun Jan 30 00:59:16 2005
+++ cam_new/cam_xpt_sim.h	Wed Jan  5 22:34:34 2005
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/cam_xpt_sim.h,v 1.7.26.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/cam_xpt_sim.h,v 1.8 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _CAM_CAM_XPT_SIM_H
diff -ru cam_old/scsi/scsi_all.c cam_new/scsi/scsi_all.c
--- cam_old/scsi/scsi_all.c	Sat Mar 12 10:05:39 2005
+++ cam_new/scsi/scsi_all.c	Thu Apr 14 03:52:50 2005
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.45.2.2 2005/03/12 10:05:39 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.48 2005/04/14 03:52:50 mjacob Exp $");
 
 #include <sys/param.h>
 
@@ -2311,6 +2311,15 @@
 {
 	int i;
 	int num_syncrates;
+
+	/*
+	 * It's a bug if period is zero, but if it is anyway, don't
+	 * die with a divide fault- instead return something which
+	 * 'approximates' async
+	 */
+	if (period_factor == 0) {
+		return (3300);
+	}
 
 	num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
 	/* See if the period is in the "exception" table */
diff -ru cam_old/scsi/scsi_all.h cam_new/scsi/scsi_all.h
--- cam_old/scsi/scsi_all.h	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_all.h	Wed Jan  5 22:34:34 2005
@@ -14,7 +14,7 @@
  *
  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.23.6.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.24 2005/01/05 22:34:34 imp Exp $
  */
 
 /*
diff -ru cam_old/scsi/scsi_cd.c cam_new/scsi/scsi_cd.c
--- cam_old/scsi/scsi_cd.c	Wed Mar 30 14:54:17 2005
+++ cam_new/scsi/scsi_cd.c	Sat Mar 26 06:05:06 2005
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_cd.c,v 1.89.2.3 2005/03/30 14:54:17 ken Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_cd.c,v 1.93 2005/03/26 06:05:06 ken Exp $");
 
 #include "opt_cd.h"
 
@@ -1909,7 +1909,7 @@
 
 	struct 	cam_periph *periph;
 	struct	cd_softc *softc;
-	int	error;
+	int	error, nocopyout;
 
 	periph = (struct cam_periph *)dp->d_drv1;
 	if (periph == NULL)
@@ -1946,6 +1946,7 @@
 		}
 	}
 
+	nocopyout = 0;
 	switch (cmd) {
 
 	case CDIOCPLAYTRACKS:
@@ -2104,6 +2105,9 @@
 			error = cdplay(periph, args->blk, args->len);
 		}
 		break;
+	case CDIOCREADSUBCHANNEL_SYSSPACE:
+		nocopyout = 1;
+		/* Fallthrough */
 	case CDIOCREADSUBCHANNEL:
 		{
 			struct ioc_read_subchannel *args
@@ -2144,8 +2148,12 @@
 			len = min(len, ((data->header.data_len[0] << 8) +
 				data->header.data_len[1] +
 				sizeof(struct cd_sub_channel_header)));
-			if (copyout(data, args->data, len) != 0) {
-				error = EFAULT;
+			if (nocopyout == 0) {
+				if (copyout(data, args->data, len) != 0) {
+					error = EFAULT;
+				}
+			} else {
+				bcopy(data, args->data, len);
 			}
 			free(data, M_TEMP);
 		}
diff -ru cam_old/scsi/scsi_ch.c cam_new/scsi/scsi_ch.c
--- cam_old/scsi/scsi_ch.c	Wed Mar 30 14:52:03 2005
+++ cam_new/scsi/scsi_ch.c	Sat Mar 26 04:21:11 2005
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_ch.c,v 1.40.2.2 2005/03/30 14:52:03 ken Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_ch.c,v 1.42 2005/03/26 04:21:11 ken Exp $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
diff -ru cam_old/scsi/scsi_ch.h cam_new/scsi/scsi_ch.h
--- cam_old/scsi/scsi_ch.h	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_ch.h	Wed Jan  5 22:34:34 2005
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/cam/scsi/scsi_ch.h,v 1.4.4.1 2005/01/30 00:59:16 imp Exp $ */
+/* $FreeBSD: src/sys/cam/scsi/scsi_ch.h,v 1.5 2005/01/05 22:34:34 imp Exp $ */
 /*	$NetBSD: scsi_changer.h,v 1.11 1998/02/13 08:28:32 enami Exp $	*/
 
 /*-
diff -ru cam_old/scsi/scsi_da.c cam_new/scsi/scsi_da.c
--- cam_old/scsi/scsi_da.c	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_da.c	Thu Jun  9 17:35:04 2005
@@ -27,11 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.171.2.1 2005/01/30 00:59:16 imp Exp $");
-
-#ifdef _KERNEL
-#include "opt_hw_wdog.h"
-#endif /* _KERNEL */
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.180 2005/06/09 17:35:04 pjd Exp $");
 
 #include <sys/param.h>
 
@@ -204,6 +200,7 @@
 	{
 		/*
 		 * Doesn't like the synchronize cache command.
+		 * Reported by: Blaz Zupan <blaz@gold.amis.net>
 		 */
 		{T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
 		/*quirks*/ DA_Q_NO_SYNC_CACHE
@@ -217,6 +214,14 @@
 	},
 	{
 		/*
+		 * Doesn't like the synchronize cache command.
+		 * Reported by: walter@pelissero.de
+		 */
+		{T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
+		/*quirks*/ DA_Q_NO_SYNC_CACHE
+	},
+	{
+		/*
 		 * Doesn't work correctly with 6 byte reads/writes.
 		 * Returns illegal request, and points to byte 9 of the
 		 * 6-byte CDB.
@@ -232,6 +237,14 @@
 	},
 	{
 		/*
+		 * Doesn't like the synchronize cache command.
+		 * Reported by: walter@pelissero.de
+		 */
+		{T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
+                /*quirks*/ DA_Q_NO_SYNC_CACHE
+	},
+	{
+		/*
 		 * The CISS RAID controllers do not support SYNC_CACHE
 		 */
 		{T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"},
@@ -315,7 +328,30 @@
 		 * Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01
 		 * PR: kern/70158
 		 */
-		{T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "NexIA+*", "*"},
+		{T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"},
+		/*quirks*/ DA_Q_NO_SYNC_CACHE
+	},
+	{
+		/*
+		 * ZICPlay USB MP3 Player with FM
+		 * PR: kern/75057
+		 */
+		{T_DIRECT, SIP_MEDIA_REMOVABLE, "ACTIONS*" , "USB DISK*", "*"},
+		/*quirks*/ DA_Q_NO_SYNC_CACHE
+	},
+	{
+		/*
+		 * TEAC USB floppy mechanisms
+		 */
+		{T_DIRECT, SIP_MEDIA_REMOVABLE, "TEAC" , "FD-05*", "*"},
+		/*quirks*/ DA_Q_NO_SYNC_CACHE
+	},
+	{
+		/*
+		 * Kingston DataTraveler II+ USB Pen-Drive.
+		 * Reported by: Pawel Jakub Dawidek <pjd@FreeBSD.org>
+		 */
+		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+", "*"},
 		/*quirks*/ DA_Q_NO_SYNC_CACHE
 	},
 };
diff -ru cam_old/scsi/scsi_da.h cam_new/scsi/scsi_da.h
--- cam_old/scsi/scsi_da.h	Sat Feb  5 09:19:04 2005
+++ cam_new/scsi/scsi_da.h	Wed Jan  5 22:34:34 2005
@@ -46,7 +46,7 @@
  *
  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_da.h,v 1.5.8.2 2005/02/05 09:19:04 bms Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_da.h,v 1.8 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef	_SCSI_SCSI_DA_H
diff -ru cam_old/scsi/scsi_dvcfg.h cam_new/scsi/scsi_dvcfg.h
--- cam_old/scsi/scsi_dvcfg.h	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_dvcfg.h	Wed Jan  5 22:34:34 2005
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/cam/scsi/scsi_dvcfg.h,v 1.1.10.1 2005/01/30 00:59:16 imp Exp $	*/
+/*	$FreeBSD: src/sys/cam/scsi/scsi_dvcfg.h,v 1.2 2005/01/05 22:34:34 imp Exp $	*/
 /*	$NecBSD: scsi_dvcfg.h,v 1.4 1998/03/14 07:05:06 kmatsuda Exp $	*/
 /*	$NetBSD$	*/
 
diff -ru cam_old/scsi/scsi_iu.h cam_new/scsi/scsi_iu.h
--- cam_old/scsi/scsi_iu.h	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_iu.h	Wed Jan  5 22:34:34 2005
@@ -1,6 +1,6 @@
 /*-
  * This file is in the public domain.
- * $FreeBSD: src/sys/cam/scsi/scsi_iu.h,v 1.2.6.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_iu.h,v 1.3 2005/01/05 22:34:34 imp Exp $
  */
 #ifndef	_SCSI_SCSI_IU_H
 #define _SCSI_SCSI_IU_H 1
diff -ru cam_old/scsi/scsi_low.c cam_new/scsi/scsi_low.c
--- cam_old/scsi/scsi_low.c	Fri Apr  1 12:29:23 2005
+++ cam_new/scsi/scsi_low.c	Fri Jul  1 15:21:30 2005
@@ -2,7 +2,7 @@
 /*	$NetBSD$	*/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.21.4.2 2005/04/01 12:29:23 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.24 2005/07/01 15:21:30 avatar Exp $");
 
 #define	SCSI_LOW_STATICS
 #define	SCSI_LOW_DEBUG
@@ -111,6 +111,7 @@
 #include <cam/cam_sim.h>
 #include <cam/cam_debug.h>
 #include <cam/cam_periph.h>
+#include <cam/cam_xpt_periph.h>
 
 #include <cam/scsi/scsi_all.h>
 #include <cam/scsi/scsi_message.h>
@@ -144,6 +145,8 @@
 #define	SCSI_LOW_DISK_LFLAGS	0x0000ffff
 #define	SCSI_LOW_DISK_TFLAGS	0xffff0000
 
+MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
+
 /**************************************************************
  * Declarations
  **************************************************************/
@@ -394,8 +397,8 @@
  * SCSI INTERFACE (XS)
  **************************************************************/
 #define	SCSI_LOW_MINPHYS		0x10000
-#define	SCSI_LOW_MALLOC(size)		malloc((size), M_DEVBUF, M_NOWAIT)
-#define	SCSI_LOW_FREE(pt)		free((pt), M_DEVBUF)
+#define	SCSI_LOW_MALLOC(size)		malloc((size), M_SCSILOW, M_NOWAIT)
+#define	SCSI_LOW_FREE(pt)		free((pt), M_SCSILOW)
 #define	SCSI_LOW_ALLOC_CCB(flags)	scsi_low_get_ccb((flags))
 #define	SCSI_LOW_XS_POLL_HZ		1000
 
@@ -884,8 +887,8 @@
 /**************************************************************
  * SCSI INTERFACE (CAM)
  **************************************************************/
-#define	SCSI_LOW_MALLOC(size)		malloc((size), M_DEVBUF, M_NOWAIT)
-#define	SCSI_LOW_FREE(pt)		free((pt), M_DEVBUF)
+#define	SCSI_LOW_MALLOC(size)		malloc((size), M_SCSILOW, M_NOWAIT)
+#define	SCSI_LOW_FREE(pt)		free((pt), M_SCSILOW)
 #define	SCSI_LOW_ALLOC_CCB(flags)	scsi_low_get_ccb()
 
 static void scsi_low_poll_cam(struct cam_sim *);
@@ -955,7 +958,7 @@
 {
 
 	xpt_free_path(ccb->ccb_h.path);
-	free(ccb, M_DEVBUF);
+	xpt_free_ccb(ccb);
 }
 
 static void
@@ -963,7 +966,7 @@
 	struct scsi_low_softc *slp;
 {
   	struct cam_path *path;
-	union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK);
+	union ccb *ccb = xpt_alloc_ccb();
 	cam_status status;
 
 	bzero(ccb, sizeof(union ccb));
@@ -1412,7 +1415,7 @@
 	}
 
 	if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
-		free(slp->sl_si.sim, M_DEVBUF);
+		free(slp->sl_si.sim, M_SCSILOW);
 	 	return ENODEV;
 	}
        
diff -ru cam_old/scsi/scsi_low.h cam_new/scsi/scsi_low.h
--- cam_old/scsi/scsi_low.h	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_low.h	Wed Jan  5 22:34:34 2005
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/cam/scsi/scsi_low.h,v 1.7.2.1 2005/01/30 00:59:16 imp Exp $	*/
+/*	$FreeBSD: src/sys/cam/scsi/scsi_low.h,v 1.8 2005/01/05 22:34:34 imp Exp $	*/
 /*	$NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $	*/
 /*	$NetBSD$	*/
 
diff -ru cam_old/scsi/scsi_low_pisa.c cam_new/scsi/scsi_low_pisa.c
--- cam_old/scsi/scsi_low_pisa.c	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_low_pisa.c	Wed Jan  5 22:34:34 2005
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_low_pisa.c,v 1.7.4.1 2005/01/30 00:59:16 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_low_pisa.c,v 1.8 2005/01/05 22:34:34 imp Exp $");
 
 #ifdef	__NetBSD__
 #include <sys/param.h>
diff -ru cam_old/scsi/scsi_low_pisa.h cam_new/scsi/scsi_low_pisa.h
--- cam_old/scsi/scsi_low_pisa.h	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_low_pisa.h	Wed Jan  5 22:34:34 2005
@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/cam/scsi/scsi_low_pisa.h,v 1.4.8.1 2005/01/30 00:59:16 imp Exp $	*/
+/*	$FreeBSD: src/sys/cam/scsi/scsi_low_pisa.h,v 1.5 2005/01/05 22:34:34 imp Exp $	*/
 /*	$NecBSD: scsi_low_pisa.h,v 1.3.14.1 2001/06/08 06:27:49 honda Exp $	*/
 /*	$NetBSD$	*/
 
diff -ru cam_old/scsi/scsi_message.h cam_new/scsi/scsi_message.h
--- cam_old/scsi/scsi_message.h	Sun Jan 30 00:59:16 2005
+++ cam_new/scsi/scsi_message.h	Wed Jan  5 22:34:34 2005
@@ -1,6 +1,6 @@
 /*-
  * This file is in the public domain.
- * $FreeBSD: src/sys/cam/scsi/scsi_message.h,v 1.6.8.1 2005/01/30 00:59:16 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_message.h,v 1.7 2005/01/05 22:34:34 imp Exp $
  */
 
 /* Messages (1 byte) */		     /* I/T (M)andatory or (O)ptional */
diff -ru cam_old/scsi/scsi_pass.c cam_new/scsi/scsi_pass.c
--- cam_old/scsi/scsi_pass.c	Fri Apr  1 12:40:25 2005
+++ cam_new/scsi/scsi_pass.c	Sat Jan 22 07:21:25 2005
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_pass.c,v 1.41.2.2 2005/04/01 12:40:25 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_pass.c,v 1.43 2005/01/22 07:21:25 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -ru cam_old/scsi/scsi_pass.h cam_new/scsi/scsi_pass.h
--- cam_old/scsi/scsi_pass.h	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_pass.h	Wed Jan  5 22:34:34 2005
@@ -22,7 +22,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_pass.h,v 1.4.8.1 2005/01/30 00:59:17 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_pass.h,v 1.5 2005/01/05 22:34:34 imp Exp $
  */
 
 #ifndef _SCSI_PASS_H
diff -ru cam_old/scsi/scsi_pt.c cam_new/scsi/scsi_pt.c
--- cam_old/scsi/scsi_pt.c	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_pt.c	Wed Jan  5 22:34:34 2005
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_pt.c,v 1.42.2.1 2005/01/30 00:59:17 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_pt.c,v 1.43 2005/01/05 22:34:34 imp Exp $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
diff -ru cam_old/scsi/scsi_pt.h cam_new/scsi/scsi_pt.h
--- cam_old/scsi/scsi_pt.h	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_pt.h	Wed Jan  5 22:34:35 2005
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_pt.h,v 1.3.8.1 2005/01/30 00:59:17 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_pt.h,v 1.4 2005/01/05 22:34:35 imp Exp $
  */
 
 #ifndef	_SCSI_SCSI_PT_H
diff -ru cam_old/scsi/scsi_sa.c cam_new/scsi/scsi_sa.c
--- cam_old/scsi/scsi_sa.c	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_sa.c	Fri Jul  1 15:21:30 2005
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_sa.c,v 1.101.2.1 2005/01/30 00:59:17 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_sa.c,v 1.105 2005/07/01 15:21:30 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -101,6 +101,7 @@
  * Driver states
  */
 
+MALLOC_DEFINE(M_SCSISA, "SCSI sa", "SCSI sequential access buffers");
 
 typedef enum {
 	SA_STATE_NORMAL, SA_STATE_ABNORMAL
@@ -810,10 +811,29 @@
 			}
 			break;
 
+		case MTIOCTOP:
+		{
+			struct mtop *mt = (struct mtop *) arg;
+
+			/*
+			 * Check to make sure it's an OP we can perform
+			 * with no media inserted.
+			 */
+			switch (mt->mt_op) {
+			case MTSETBSIZ:
+			case MTSETDNSTY:
+			case MTCOMP:
+				mt = NULL;
+				/* FALLTHROUGH */
+			default:
+				break;
+			}
+			if (mt != NULL) {
+				break;
+			}
+			/* FALLTHROUGH */
+		}
 		case MTIOCSETEOTMODEL:
-		case MTSETBSIZ:
-		case MTSETDNSTY:
-		case MTCOMP:
 			/*
 			 * We need to acquire the peripheral here rather
 			 * than at open time because we are sharing writable
@@ -1335,7 +1355,7 @@
 
 	xpt_print_path(periph->path);
 	printf("removing device entry\n");
-	free(softc, M_DEVBUF);
+	free(softc, M_SCSISA);
 }
 
 static void
@@ -1401,7 +1421,7 @@
 	}
 
 	softc = (struct sa_softc *)
-	    malloc(sizeof (*softc), M_DEVBUF, M_NOWAIT | M_ZERO);
+	    malloc(sizeof (*softc), M_SCSISA, M_NOWAIT | M_ZERO);
 	if (softc == NULL) {
 		printf("saregister: Unable to probe new device. "
 		       "Unable to allocate softc\n");				
@@ -1822,8 +1842,8 @@
 			 * will now attempt to rewind/load it.
 			 */
 			softc->flags &= ~SA_FLAG_TAPE_MOUNTED;
-			if (CAM_DEBUGGED(ccb->ccb_h.path, CAM_DEBUG_INFO)) {
-				xpt_print_path(ccb->ccb_h.path);
+			if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) {
+				xpt_print_path(periph->path);
 				printf("error %d on TUR in samount\n", error);
 			}
 		}
@@ -1887,7 +1907,7 @@
 		rblim = (struct  scsi_read_block_limits_data *)
 		    malloc(8192, M_TEMP, M_WAITOK);
 		if (rblim == NULL) {
-			xpt_print_path(ccb->ccb_h.path);
+			xpt_print_path(periph->path);
 			printf("no memory for test read\n");
 			xpt_release_ccb(ccb);
 			error = ENOMEM;
@@ -1909,7 +1929,7 @@
 			    softc->device_stats);
 			QFRLS(ccb);
 			if (error) {
-				xpt_print_path(ccb->ccb_h.path);
+				xpt_print_path(periph->path);
 				printf("unable to rewind after test read\n");
 				xpt_release_ccb(ccb);
 				goto exit;
@@ -2074,7 +2094,7 @@
 		if ((softc->max_blk < softc->media_blksize) ||
 		    (softc->min_blk > softc->media_blksize &&
 		    softc->media_blksize)) {
-			xpt_print_path(ccb->ccb_h.path);
+			xpt_print_path(periph->path);
 			printf("BLOCK LIMITS (%d..%d) could not match current "
 			    "block settings (%d)- adjusting\n", softc->min_blk,
 			    softc->max_blk, softc->media_blksize);
@@ -2109,7 +2129,7 @@
 			error = sasetparams(periph, SA_PARAM_BLOCKSIZE,
 			    softc->media_blksize, 0, 0, SF_NO_PRINT);
 			if (error) {
-				xpt_print_path(ccb->ccb_h.path);
+				xpt_print_path(periph->path);
 				printf("unable to set fixed blocksize to %d\n",
 				     softc->media_blksize);
 				goto exit;
@@ -2136,7 +2156,7 @@
 						softc->last_media_blksize = 512;
 					goto tryagain;
 				}
-				xpt_print_path(ccb->ccb_h.path);
+				xpt_print_path(periph->path);
 				printf("unable to set variable blocksize\n");
 				goto exit;
 			}
@@ -2194,7 +2214,7 @@
 			if (error == 0) {
 				softc->buffer_mode = SMH_SA_BUF_MODE_SIBUF;
 			} else {
-				xpt_print_path(ccb->ccb_h.path);
+				xpt_print_path(periph->path);
 				printf("unable to set buffered mode\n");
 			}
 			error = 0;	/* not an error */
diff -ru cam_old/scsi/scsi_sa.h cam_new/scsi/scsi_sa.h
--- cam_old/scsi/scsi_sa.h	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_sa.h	Wed Jan  5 22:34:35 2005
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_sa.h,v 1.9.8.1 2005/01/30 00:59:17 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_sa.h,v 1.10 2005/01/05 22:34:35 imp Exp $
  */
 
 #ifndef	_SCSI_SCSI_SA_H
diff -ru cam_old/scsi/scsi_ses.c cam_new/scsi/scsi_ses.c
--- cam_old/scsi/scsi_ses.c	Fri Apr  1 12:40:25 2005
+++ cam_new/scsi/scsi_ses.c	Fri Jul  1 15:21:30 2005
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_ses.c,v 1.29.2.2 2005/04/01 12:40:25 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_ses.c,v 1.32 2005/07/01 15:21:30 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -51,6 +51,8 @@
 
 #include <opt_ses.h>
 
+MALLOC_DEFINE(M_SCSISES, "SCSI SES", "SCSI SES buffers");
+
 /*
  * Platform Independent Driver Internal Definitions for SES devices.
  */
@@ -120,8 +122,8 @@
 #define	SES_DLOG		if (0) ses_log
 #endif
 #define	SES_VLOG		if (bootverbose) ses_log
-#define	SES_MALLOC(amt)		malloc(amt, M_DEVBUF, M_NOWAIT)
-#define	SES_FREE(ptr, amt)	free(ptr, M_DEVBUF)
+#define	SES_MALLOC(amt)		malloc(amt, M_SCSISES, M_NOWAIT)
+#define	SES_FREE(ptr, amt)	free(ptr, M_SCSISES)
 #define	MEMZERO			bzero
 #define	MEMCPY(dest, src, amt)	bcopy(src, dest, amt)
 
@@ -250,7 +252,7 @@
 
 	xpt_print_path(periph->path);
 	printf("removing device entry\n");
-	free(softc, M_DEVBUF);
+	free(softc, M_SCSISES);
 }
 
 static void
@@ -324,7 +326,7 @@
 		return (CAM_REQ_CMP_ERR);
 	}
 
-	softc = malloc(sizeof (struct ses_softc), M_DEVBUF, M_NOWAIT);
+	softc = malloc(sizeof (struct ses_softc), M_SCSISES, M_NOWAIT);
 	if (softc == NULL) {
 		printf("sesregister: Unable to probe new device. "
 		       "Unable to allocate softc\n");				
@@ -359,7 +361,7 @@
 		break;
 	case SES_NONE:
 	default:
-		free(softc, M_DEVBUF);
+		free(softc, M_SCSISES);
 		return (CAM_REQ_CMP_ERR);
 	}
 
diff -ru cam_old/scsi/scsi_ses.h cam_new/scsi/scsi_ses.h
--- cam_old/scsi/scsi_ses.h	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_ses.h	Wed Jan  5 22:34:35 2005
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/cam/scsi/scsi_ses.h,v 1.2.26.1 2005/01/30 00:59:17 imp Exp $ */
+/* $FreeBSD: src/sys/cam/scsi/scsi_ses.h,v 1.3 2005/01/05 22:34:35 imp Exp $ */
 /*-
  * Copyright (c) 2000 by Matthew Jacob
  * All rights reserved.
diff -ru cam_old/scsi/scsi_targ_bh.c cam_new/scsi/scsi_targ_bh.c
--- cam_old/scsi/scsi_targ_bh.c	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_targ_bh.c	Fri Jul  1 15:21:30 2005
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_targ_bh.c,v 1.20.4.1 2005/01/30 00:59:17 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_targ_bh.c,v 1.22 2005/07/01 15:21:30 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -50,6 +50,8 @@
 #include <cam/scsi/scsi_all.h>
 #include <cam/scsi/scsi_message.h>
 
+MALLOC_DEFINE(M_SCSIBH, "SCSI bh", "SCSI blackhole buffers");
+
 typedef enum {
 	TARGBH_STATE_NORMAL,
 	TARGBH_STATE_EXCEPTION,
@@ -276,7 +278,7 @@
 	for (i = 0; i < MAX_ACCEPT; i++) {
 		struct ccb_accept_tio *atio;
 
-		atio = (struct ccb_accept_tio*)malloc(sizeof(*atio), M_DEVBUF,
+		atio = (struct ccb_accept_tio*)malloc(sizeof(*atio), M_SCSIBH,
 						      M_NOWAIT);
 		if (atio == NULL) {
 			status = CAM_RESRC_UNAVAIL;
@@ -286,7 +288,7 @@
 		atio->ccb_h.ccb_descr = targbhallocdescr();
 
 		if (atio->ccb_h.ccb_descr == NULL) {
-			free(atio, M_DEVBUF);
+			free(atio, M_SCSIBH);
 			status = CAM_RESRC_UNAVAIL;
 			break;
 		}
@@ -298,7 +300,7 @@
 		status = atio->ccb_h.status;
 		if (status != CAM_REQ_INPROG) {
 			targbhfreedescr(atio->ccb_h.ccb_descr);
-			free(atio, M_DEVBUF);
+			free(atio, M_SCSIBH);
 			break;
 		}
 		((struct targbh_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link =
@@ -321,7 +323,7 @@
 	for (i = 0; i < MAX_ACCEPT; i++) {
 		struct ccb_immed_notify *inot;
 
-		inot = (struct ccb_immed_notify*)malloc(sizeof(*inot), M_DEVBUF,
+		inot = (struct ccb_immed_notify*)malloc(sizeof(*inot), M_SCSIBH,
 						        M_NOWAIT);
 
 		if (inot == NULL) {
@@ -335,7 +337,7 @@
 		xpt_action((union ccb *)inot);
 		status = inot->ccb_h.status;
 		if (status != CAM_REQ_INPROG) {
-			free(inot, M_DEVBUF);
+			free(inot, M_SCSIBH);
 			break;
 		}
 		SLIST_INSERT_HEAD(&softc->immed_notify_slist, &inot->ccb_h,
@@ -409,7 +411,7 @@
 
 	/* Allocate our per-instance private storage */
 	softc = (struct targbh_softc *)malloc(sizeof(*softc),
-					      M_DEVBUF, M_NOWAIT);
+					      M_SCSIBH, M_NOWAIT);
 	if (softc == NULL) {
 		printf("targctor: unable to malloc softc\n");
 		return (CAM_REQ_CMP_ERR);
@@ -446,7 +448,7 @@
 	default:
 		/* XXX Wait for callback of targbhdislun() */
 		tsleep(softc, PRIBIO, "targbh", hz/2);
-		free(softc, M_DEVBUF);
+		free(softc, M_SCSIBH);
 		break;
 	}
 }
@@ -576,7 +578,7 @@
 		if (softc->state == TARGBH_STATE_TEARDOWN
 		 || atio->ccb_h.status == CAM_REQ_ABORTED) {
 			targbhfreedescr(descr);
-			free(done_ccb, M_DEVBUF);
+			xpt_free_ccb(done_ccb);
 			return;
 		}
 
@@ -725,7 +727,7 @@
 			break;
 		} else {
 			targbhfreedescr(desc);
-			free(atio, M_DEVBUF);
+			free(atio, M_SCSIBH);
 		}
 		break;
 	}
@@ -737,7 +739,7 @@
 		if (softc->state == TARGBH_STATE_TEARDOWN
 		 || done_ccb->ccb_h.status == CAM_REQ_ABORTED) {
 			printf("Freed an immediate notify\n");
-			free(done_ccb, M_DEVBUF);
+			xpt_free_ccb(done_ccb);
 		} else {
 			/* Requeue for another immediate event */
 			xpt_action(done_ccb);
@@ -771,16 +773,16 @@
 
 	/* Allocate the targbh_descr structure */
 	descr = (struct targbh_cmd_desc *)malloc(sizeof(*descr),
-					       M_DEVBUF, M_NOWAIT);
+					       M_SCSIBH, M_NOWAIT);
 	if (descr == NULL)
 		return (NULL);
 
 	bzero(descr, sizeof(*descr));
 
 	/* Allocate buffer backing store */
-	descr->backing_store = malloc(MAX_BUF_SIZE, M_DEVBUF, M_NOWAIT);
+	descr->backing_store = malloc(MAX_BUF_SIZE, M_SCSIBH, M_NOWAIT);
 	if (descr->backing_store == NULL) {
-		free(descr, M_DEVBUF);
+		free(descr, M_SCSIBH);
 		return (NULL);
 	}
 	descr->max_size = MAX_BUF_SIZE;
@@ -790,6 +792,6 @@
 static void
 targbhfreedescr(struct targbh_cmd_desc *descr)
 {
-	free(descr->backing_store, M_DEVBUF);
-	free(descr, M_DEVBUF);
+	free(descr->backing_store, M_SCSIBH);
+	free(descr, M_SCSIBH);
 }
diff -ru cam_old/scsi/scsi_target.c cam_new/scsi/scsi_target.c
--- cam_old/scsi/scsi_target.c	Sat Mar 12 09:59:33 2005
+++ cam_new/scsi/scsi_target.c	Mon Aug  8 19:55:30 2005
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_target.c,v 1.63.2.2 2005/03/12 09:59:33 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_target.c,v 1.68 2005/08/08 19:55:30 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -141,8 +141,8 @@
 static struct targ_cmd_descr *
 			targgetdescr(struct targ_softc *softc);
 static periph_init_t	targinit;
-static void		targclone(void *arg, char *name, int namelen,
-				  struct cdev **dev);
+static void		targclone(void *arg, struct ucred *cred, char *name,
+				  int namelen, struct cdev **dev);
 static void		targasync(void *callback_arg, u_int32_t code,
 				  struct cam_path *path, void *arg);
 static void		abort_all_pending(struct targ_softc *softc);
@@ -196,7 +196,7 @@
 	TAILQ_INIT(&softc->work_queue);
 	TAILQ_INIT(&softc->abort_queue);
 	TAILQ_INIT(&softc->user_ccb_queue);
-	knlist_init(&softc->read_select.si_note, &softc->mtx);
+	knlist_init(&softc->read_select.si_note, &softc->mtx, NULL, NULL, NULL);
 
 	return (0);
 }
@@ -1025,7 +1025,8 @@
 }
 
 static void
-targclone(void *arg, char *name, int namelen, struct cdev **dev)
+targclone(void *arg, struct ucred *cred, char *name, int namelen,
+    struct cdev **dev)
 {
 	int u;
 
@@ -1035,6 +1036,7 @@
 		return;
 	*dev = make_dev(&targ_cdevsw, unit2minor(u), UID_ROOT, GID_WHEEL,
 			0600, "targ%d", u);
+	dev_ref(*dev);
 	(*dev)->si_flags |= SI_CHEAPCLONE;
 }
 
diff -ru cam_old/scsi/scsi_targetio.h cam_new/scsi/scsi_targetio.h
--- cam_old/scsi/scsi_targetio.h	Sun Jan 30 00:59:17 2005
+++ cam_new/scsi/scsi_targetio.h	Wed Jan  5 22:34:35 2005
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_targetio.h,v 1.11.8.1 2005/01/30 00:59:17 imp Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_targetio.h,v 1.12 2005/01/05 22:34:35 imp Exp $
  */
 
 #ifndef _CAM_SCSI_SCSI_TARGETIO_H_

--=-FYZp8LaGu/8HvL5hC1wt--




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