[RFC] Remove SG API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Now that a single URB can transmit a SG list, we can remove the
usb_sg_init / usb_sg_wait / usb_sg_cancel API.  It only has two users --
usb-storage and usbtest.

I have not tested this patch!  I'm currently travelling and would prefer
not to test it on my laptop.  The diffstat is quite compelling though,
and the usb-storage driver gets quite a lot simpler (net -31 lines of
code from that driver).

Not-signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxxxx>

 drivers/usb/core/message.c      |  357 ----------------------------------------
 drivers/usb/misc/usbtest.c      |  103 +++++++----
 drivers/usb/storage/transport.c |   53 +----
 drivers/usb/storage/usb.h       |   12 -
 include/linux/usb.h             |   51 -----
 5 files changed, 83 insertions(+), 493 deletions(-)

diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 9f0ce7d..4c310ce 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -248,363 +248,6 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
 }
 EXPORT_SYMBOL_GPL(usb_bulk_msg);
 
-/*-------------------------------------------------------------------*/
-
-static void sg_clean(struct usb_sg_request *io)
-{
-	if (io->urbs) {
-		while (io->entries--)
-			usb_free_urb(io->urbs [io->entries]);
-		kfree(io->urbs);
-		io->urbs = NULL;
-	}
-	io->dev = NULL;
-}
-
-static void sg_complete(struct urb *urb)
-{
-	struct usb_sg_request *io = urb->context;
-	int status = urb->status;
-
-	spin_lock(&io->lock);
-
-	/* In 2.5 we require hcds' endpoint queues not to progress after fault
-	 * reports, until the completion callback (this!) returns.  That lets
-	 * device driver code (like this routine) unlink queued urbs first,
-	 * if it needs to, since the HC won't work on them at all.  So it's
-	 * not possible for page N+1 to overwrite page N, and so on.
-	 *
-	 * That's only for "hard" faults; "soft" faults (unlinks) sometimes
-	 * complete before the HCD can get requests away from hardware,
-	 * though never during cleanup after a hard fault.
-	 */
-	if (io->status
-			&& (io->status != -ECONNRESET
-				|| status != -ECONNRESET)
-			&& urb->actual_length) {
-		dev_err(io->dev->bus->controller,
-			"dev %s ep%d%s scatterlist error %d/%d\n",
-			io->dev->devpath,
-			usb_endpoint_num(&urb->ep->desc),
-			usb_urb_dir_in(urb) ? "in" : "out",
-			status, io->status);
-		/* BUG (); */
-	}
-
-	if (io->status == 0 && status && status != -ECONNRESET) {
-		int i, found, retval;
-
-		io->status = status;
-
-		/* the previous urbs, and this one, completed already.
-		 * unlink pending urbs so they won't rx/tx bad data.
-		 * careful: unlink can sometimes be synchronous...
-		 */
-		spin_unlock(&io->lock);
-		for (i = 0, found = 0; i < io->entries; i++) {
-			if (!io->urbs [i] || !io->urbs [i]->dev)
-				continue;
-			if (found) {
-				retval = usb_unlink_urb(io->urbs [i]);
-				if (retval != -EINPROGRESS &&
-				    retval != -ENODEV &&
-				    retval != -EBUSY)
-					dev_err(&io->dev->dev,
-						"%s, unlink --> %d\n",
-						__func__, retval);
-			} else if (urb == io->urbs [i])
-				found = 1;
-		}
-		spin_lock(&io->lock);
-	}
-	urb->dev = NULL;
-
-	/* on the last completion, signal usb_sg_wait() */
-	io->bytes += urb->actual_length;
-	io->count--;
-	if (!io->count)
-		complete(&io->complete);
-
-	spin_unlock(&io->lock);
-}
-
-
-/**
- * usb_sg_init - initializes scatterlist-based bulk/interrupt I/O request
- * @io: request block being initialized.  until usb_sg_wait() returns,
- *	treat this as a pointer to an opaque block of memory,
- * @dev: the usb device that will send or receive the data
- * @pipe: endpoint "pipe" used to transfer the data
- * @period: polling rate for interrupt endpoints, in frames or
- * 	(for high speed endpoints) microframes; ignored for bulk
- * @sg: scatterlist entries
- * @nents: how many entries in the scatterlist
- * @length: how many bytes to send from the scatterlist, or zero to
- * 	send every byte identified in the list.
- * @mem_flags: SLAB_* flags affecting memory allocations in this call
- *
- * Returns zero for success, else a negative errno value.  This initializes a
- * scatter/gather request, allocating resources such as I/O mappings and urb
- * memory (except maybe memory used by USB controller drivers).
- *
- * The request must be issued using usb_sg_wait(), which waits for the I/O to
- * complete (or to be canceled) and then cleans up all resources allocated by
- * usb_sg_init().
- *
- * The request may be canceled with usb_sg_cancel(), either before or after
- * usb_sg_wait() is called.
- */
-int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
-		unsigned pipe, unsigned	period, struct scatterlist *sg,
-		int nents, size_t length, gfp_t mem_flags)
-{
-	int i;
-	int urb_flags;
-	int use_sg;
-
-	if (!io || !dev || !sg
-			|| usb_pipecontrol(pipe)
-			|| usb_pipeisoc(pipe)
-			|| nents <= 0)
-		return -EINVAL;
-
-	spin_lock_init(&io->lock);
-	io->dev = dev;
-	io->pipe = pipe;
-
-	if (dev->bus->sg_tablesize > 0) {
-		use_sg = true;
-		io->entries = 1;
-	} else {
-		use_sg = false;
-		io->entries = nents;
-	}
-
-	/* initialize all the urbs we'll use */
-	io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags);
-	if (!io->urbs)
-		goto nomem;
-
-	urb_flags = URB_NO_INTERRUPT;
-	if (usb_pipein(pipe))
-		urb_flags |= URB_SHORT_NOT_OK;
-
-	for_each_sg(sg, sg, io->entries, i) {
-		struct urb *urb;
-		unsigned len;
-
-		urb = usb_alloc_urb(0, mem_flags);
-		if (!urb) {
-			io->entries = i;
-			goto nomem;
-		}
-		io->urbs[i] = urb;
-
-		urb->dev = NULL;
-		urb->pipe = pipe;
-		urb->interval = period;
-		urb->transfer_flags = urb_flags;
-		urb->complete = sg_complete;
-		urb->context = io;
-		urb->sg = sg;
-
-		if (use_sg) {
-			/* There is no single transfer buffer */
-			urb->transfer_buffer = NULL;
-			urb->num_sgs = nents;
-
-			/* A length of zero means transfer the whole sg list */
-			len = length;
-			if (len == 0) {
-				struct scatterlist	*sg2;
-				int			j;
-
-				for_each_sg(sg, sg2, nents, j)
-					len += sg2->length;
-			}
-		} else {
-			/*
-			 * Some systems can't use DMA; they use PIO instead.
-			 * For their sakes, transfer_buffer is set whenever
-			 * possible.
-			 */
-			if (!PageHighMem(sg_page(sg)))
-				urb->transfer_buffer = sg_virt(sg);
-			else
-				urb->transfer_buffer = NULL;
-
-			len = sg->length;
-			if (length) {
-				len = min_t(unsigned, len, length);
-				length -= len;
-				if (length == 0)
-					io->entries = i + 1;
-			}
-		}
-		urb->transfer_buffer_length = len;
-	}
-	io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT;
-
-	/* transaction state */
-	io->count = io->entries;
-	io->status = 0;
-	io->bytes = 0;
-	init_completion(&io->complete);
-	return 0;
-
-nomem:
-	sg_clean(io);
-	return -ENOMEM;
-}
-EXPORT_SYMBOL_GPL(usb_sg_init);
-
-/**
- * usb_sg_wait - synchronously execute scatter/gather request
- * @io: request block handle, as initialized with usb_sg_init().
- * 	some fields become accessible when this call returns.
- * Context: !in_interrupt ()
- *
- * This function blocks until the specified I/O operation completes.  It
- * leverages the grouping of the related I/O requests to get good transfer
- * rates, by queueing the requests.  At higher speeds, such queuing can
- * significantly improve USB throughput.
- *
- * There are three kinds of completion for this function.
- * (1) success, where io->status is zero.  The number of io->bytes
- *     transferred is as requested.
- * (2) error, where io->status is a negative errno value.  The number
- *     of io->bytes transferred before the error is usually less
- *     than requested, and can be nonzero.
- * (3) cancellation, a type of error with status -ECONNRESET that
- *     is initiated by usb_sg_cancel().
- *
- * When this function returns, all memory allocated through usb_sg_init() or
- * this call will have been freed.  The request block parameter may still be
- * passed to usb_sg_cancel(), or it may be freed.  It could also be
- * reinitialized and then reused.
- *
- * Data Transfer Rates:
- *
- * Bulk transfers are valid for full or high speed endpoints.
- * The best full speed data rate is 19 packets of 64 bytes each
- * per frame, or 1216 bytes per millisecond.
- * The best high speed data rate is 13 packets of 512 bytes each
- * per microframe, or 52 KBytes per millisecond.
- *
- * The reason to use interrupt transfers through this API would most likely
- * be to reserve high speed bandwidth, where up to 24 KBytes per millisecond
- * could be transferred.  That capability is less useful for low or full
- * speed interrupt endpoints, which allow at most one packet per millisecond,
- * of at most 8 or 64 bytes (respectively).
- *
- * It is not necessary to call this function to reserve bandwidth for devices
- * under an xHCI host controller, as the bandwidth is reserved when the
- * configuration or interface alt setting is selected.
- */
-void usb_sg_wait(struct usb_sg_request *io)
-{
-	int i;
-	int entries = io->entries;
-
-	/* queue the urbs.  */
-	spin_lock_irq(&io->lock);
-	i = 0;
-	while (i < entries && !io->status) {
-		int retval;
-
-		io->urbs[i]->dev = io->dev;
-		retval = usb_submit_urb(io->urbs [i], GFP_ATOMIC);
-
-		/* after we submit, let completions or cancelations fire;
-		 * we handshake using io->status.
-		 */
-		spin_unlock_irq(&io->lock);
-		switch (retval) {
-			/* maybe we retrying will recover */
-		case -ENXIO:	/* hc didn't queue this one */
-		case -EAGAIN:
-		case -ENOMEM:
-			io->urbs[i]->dev = NULL;
-			retval = 0;
-			yield();
-			break;
-
-			/* no error? continue immediately.
-			 *
-			 * NOTE: to work better with UHCI (4K I/O buffer may
-			 * need 3K of TDs) it may be good to limit how many
-			 * URBs are queued at once; N milliseconds?
-			 */
-		case 0:
-			++i;
-			cpu_relax();
-			break;
-
-			/* fail any uncompleted urbs */
-		default:
-			io->urbs[i]->dev = NULL;
-			io->urbs[i]->status = retval;
-			dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
-				__func__, retval);
-			usb_sg_cancel(io);
-		}
-		spin_lock_irq(&io->lock);
-		if (retval && (io->status == 0 || io->status == -ECONNRESET))
-			io->status = retval;
-	}
-	io->count -= entries - i;
-	if (io->count == 0)
-		complete(&io->complete);
-	spin_unlock_irq(&io->lock);
-
-	/* OK, yes, this could be packaged as non-blocking.
-	 * So could the submit loop above ... but it's easier to
-	 * solve neither problem than to solve both!
-	 */
-	wait_for_completion(&io->complete);
-
-	sg_clean(io);
-}
-EXPORT_SYMBOL_GPL(usb_sg_wait);
-
-/**
- * usb_sg_cancel - stop scatter/gather i/o issued by usb_sg_wait()
- * @io: request block, initialized with usb_sg_init()
- *
- * This stops a request after it has been started by usb_sg_wait().
- * It can also prevents one initialized by usb_sg_init() from starting,
- * so that call just frees resources allocated to the request.
- */
-void usb_sg_cancel(struct usb_sg_request *io)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&io->lock, flags);
-
-	/* shut everything down, if it didn't already */
-	if (!io->status) {
-		int i;
-
-		io->status = -ECONNRESET;
-		spin_unlock(&io->lock);
-		for (i = 0; i < io->entries; i++) {
-			int retval;
-
-			if (!io->urbs [i]->dev)
-				continue;
-			retval = usb_unlink_urb(io->urbs [i]);
-			if (retval != -EINPROGRESS && retval != -EBUSY)
-				dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
-					__func__, retval);
-		}
-		spin_lock(&io->lock);
-	}
-	spin_unlock_irqrestore(&io->lock, flags);
-}
-EXPORT_SYMBOL_GPL(usb_sg_cancel);
-
-/*-------------------------------------------------------------------*/
-
 /**
  * usb_get_descriptor - issues a generic GET_DESCRIPTOR request
  * @dev: the device whose descriptor is being retrieved
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index eef370e..62ab9b3 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -397,29 +397,60 @@ alloc_sglist (int nents, int max, int vary)
 	return sg;
 }
 
+static struct urb *sglist_alloc_urb (
+	struct usb_device	*udev,
+	int			pipe,
+	int			nents,
+	unsigned long		bytes,
+	int			vary)
+{
+	struct urb		*urb;
+
+	urb = usb_alloc_urb (0, GFP_KERNEL);
+	if (!urb)
+		return urb;
+	usb_fill_bulk_urb (urb, udev, pipe, NULL, bytes, simple_callback, NULL);
+	urb->interval = (udev->speed == USB_SPEED_HIGH)
+			? (INTERRUPT_RATE << 3)
+			: INTERRUPT_RATE;
+	if (usb_pipein (pipe))
+		urb->transfer_flags |= URB_SHORT_NOT_OK;
+	urb->sg = alloc_sglist(nents, bytes, vary);
+	if (!urb->sg) {
+		usb_free_urb (urb);
+		urb = NULL;
+	}
+	urb->num_sgs = nents;
+
+	return urb;
+}
+
+static void sglist_free_urb (struct urb *urb)
+{
+	free_sglist(urb->sg, urb->num_sgs);
+	usb_free_urb (urb);
+}
+
 static int perform_sglist (
 	struct usbtest_dev	*tdev,
-	unsigned		iterations,
-	int			pipe,
-	struct usb_sg_request	*req,
-	struct scatterlist	*sg,
-	int			nents
+	struct urb		*urb,
+	unsigned		iterations
 )
 {
-	struct usb_device	*udev = testdev_to_usbdev(tdev);
+	struct usb_device	*udev = urb->dev;
+	struct completion	completion;
 	int			retval = 0;
 
+	urb->context = &completion;
 	while (retval == 0 && iterations-- > 0) {
-		retval = usb_sg_init (req, udev, pipe,
-				(udev->speed == USB_SPEED_HIGH)
-					? (INTERRUPT_RATE << 3)
-					: INTERRUPT_RATE,
-				sg, nents, 0, GFP_KERNEL);
-
-		if (retval)
+		init_completion (&completion);
+		if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0)
 			break;
-		usb_sg_wait (req);
-		retval = req->status;
+
+		/* NOTE:  no timeouts; can't be broken out of by interrupt */
+		wait_for_completion (&completion);
+		retval = urb->status;
+		urb->dev = udev;
 
 		/* FIXME check resulting data pattern */
 
@@ -1564,8 +1595,6 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
 	struct usbtest_param	*param = buf;
 	int			retval = -EOPNOTSUPP;
 	struct urb		*urb;
-	struct scatterlist	*sg;
-	struct usb_sg_request	req;
 	struct timeval		start;
 	unsigned		i;
 
@@ -1694,15 +1723,15 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 5:  write %d sglists %d entries of %d bytes\n",
 				param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist (param->sglen, param->length, 0);
-		if (!sg) {
+		urb = sglist_alloc_urb (udev, dev->out_pipe, param->sglen,
+							param->length, 0);
+		if (!urb) {
 			retval = -ENOMEM;
 			break;
 		}
 		// FIRMWARE:  bulk sink (maybe accepts short writes)
-		retval = perform_sglist(dev, param->iterations, dev->out_pipe,
-				&req, sg, param->sglen);
-		free_sglist (sg, param->sglen);
+		retval = perform_sglist(dev, urb, param->iterations);
+		sglist_free_urb (urb);
 		break;
 
 	case 6:
@@ -1712,15 +1741,15 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 6:  read %d sglists %d entries of %d bytes\n",
 				param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist (param->sglen, param->length, 0);
-		if (!sg) {
+		urb = sglist_alloc_urb (udev, dev->in_pipe, param->sglen,
+							param->length, 0);
+		if (!urb) {
 			retval = -ENOMEM;
 			break;
 		}
 		// FIRMWARE:  bulk source (maybe generates short writes)
-		retval = perform_sglist(dev, param->iterations, dev->in_pipe,
-				&req, sg, param->sglen);
-		free_sglist (sg, param->sglen);
+		retval = perform_sglist(dev, urb, param->iterations);
+		sglist_free_urb (urb);
 		break;
 	case 7:
 		if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0)
@@ -1729,15 +1758,15 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 7:  write/%d %d sglists %d entries 0..%d bytes\n",
 				param->vary, param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist (param->sglen, param->length, param->vary);
-		if (!sg) {
+		urb = sglist_alloc_urb (udev, dev->out_pipe, param->sglen,
+						param->length, param->vary);
+		if (!urb) {
 			retval = -ENOMEM;
 			break;
 		}
 		// FIRMWARE:  bulk sink (maybe accepts short writes)
-		retval = perform_sglist(dev, param->iterations, dev->out_pipe,
-				&req, sg, param->sglen);
-		free_sglist (sg, param->sglen);
+		retval = perform_sglist(dev, urb, param->iterations);
+		sglist_free_urb (urb);
 		break;
 	case 8:
 		if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0)
@@ -1746,15 +1775,15 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 8:  read/%d %d sglists %d entries 0..%d bytes\n",
 				param->vary, param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist (param->sglen, param->length, param->vary);
-		if (!sg) {
+		urb = sglist_alloc_urb (udev, dev->in_pipe, param->sglen,
+						param->length, param->vary);
+		if (!urb) {
 			retval = -ENOMEM;
 			break;
 		}
 		// FIRMWARE:  bulk source (maybe generates short writes)
-		retval = perform_sglist(dev, param->iterations, dev->in_pipe,
-				&req, sg, param->sglen);
-		free_sglist (sg, param->sglen);
+		retval = perform_sglist(dev, urb, param->iterations);
+		sglist_free_urb (urb);
 		break;
 
 	/* non-queued sanity tests for control (chapter 9 subset) */
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 64ec073..66962f5 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -412,7 +412,7 @@ EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_buf);
  * Transfer a scatter-gather list via bulk transfer
  *
  * This function does basically the same thing as usb_stor_bulk_transfer_buf()
- * above, but it uses the usbcore scatter-gather library.
+ * above
  */
 static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 		struct scatterlist *sg, int num_sg, unsigned int length,
@@ -420,43 +420,20 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 {
 	int result;
 
-	/* don't submit s-g requests during abort processing */
-	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
-		return USB_STOR_XFER_ERROR;
-
-	/* initialize the scatter-gather request block */
-	US_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__,
-			length, num_sg);
-	result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
-			sg, num_sg, length, GFP_NOIO);
-	if (result) {
-		US_DEBUGP("usb_sg_init returned %d\n", result);
-		return USB_STOR_XFER_ERROR;
-	}
-
-	/* since the block has been initialized successfully, it's now
-	 * okay to cancel it */
-	set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
-
-	/* did an abort occur during the submission? */
-	if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
-
-		/* cancel the request, if it hasn't been cancelled already */
-		if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
-			US_DEBUGP("-- cancelling sg request\n");
-			usb_sg_cancel(&us->current_sg);
-		}
-	}
+	US_DEBUGP("%s: xfer %u bytes\n", __func__, length);
 
-	/* wait for the completion of the transfer */
-	usb_sg_wait(&us->current_sg);
-	clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
+	/* fill and submit the URB */
+	usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, NULL, length,
+		      usb_stor_blocking_completion, NULL);
+	us->current_urb->num_sgs = num_sg;
+	us->current_urb->sg = sg;
+	result = usb_stor_msg_common(us, 0);
 
-	result = us->current_sg.status;
+	/* store the actual length of the data transferred */
 	if (act_len)
-		*act_len = us->current_sg.bytes;
-	return interpret_urb_result(us, pipe, length, result,
-			us->current_sg.bytes);
+		*act_len = us->current_urb->actual_length;
+	return interpret_urb_result(us, pipe, length, result, 
+			us->current_urb->actual_length);
 }
 
 /*
@@ -868,12 +845,6 @@ void usb_stor_stop_transport(struct us_data *us)
 		US_DEBUGP("-- cancelling URB\n");
 		usb_unlink_urb(us->current_urb);
 	}
-
-	/* If we are waiting for a scatter-gather operation, cancel it. */
-	if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
-		US_DEBUGP("-- cancelling sg request\n");
-		usb_sg_cancel(&us->current_sg);
-	}
 }
 
 /*
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 89d3bff..bd18dcf 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -67,12 +67,11 @@ struct us_unusual_dev {
 
 /* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
 #define US_FLIDX_URB_ACTIVE	0	/* current_urb is in use    */
-#define US_FLIDX_SG_ACTIVE	1	/* current_sg is in use     */
-#define US_FLIDX_ABORTING	2	/* abort is in progress     */
-#define US_FLIDX_DISCONNECTING	3	/* disconnect in progress   */
-#define US_FLIDX_RESETTING	4	/* device reset in progress */
-#define US_FLIDX_TIMED_OUT	5	/* SCSI midlayer timed out  */
-#define US_FLIDX_DONT_SCAN	6	/* don't scan (disconnect)  */
+#define US_FLIDX_ABORTING	1	/* abort is in progress     */
+#define US_FLIDX_DISCONNECTING	2	/* disconnect in progress   */
+#define US_FLIDX_RESETTING	3	/* device reset in progress */
+#define US_FLIDX_TIMED_OUT	4	/* SCSI midlayer timed out  */
+#define US_FLIDX_DONT_SCAN	5	/* don't scan (disconnect)  */
 
 #define USB_STOR_STRING_LEN 32
 
@@ -137,7 +136,6 @@ struct us_data {
 	/* control and bulk communications data */
 	struct urb		*current_urb;	 /* USB requests	 */
 	struct usb_ctrlrequest	*cr;		 /* control requests	 */
-	struct usb_sg_request	current_sg;	 /* scatter-gather req.  */
 	unsigned char		*iobuf;		 /* I/O buffer		 */
 	dma_addr_t		iobuf_dma;	 /* buffer DMA addresses */
 	struct task_struct	*ctl_thread;	 /* the control thread   */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 35fe6ab..ac3ac4f 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1430,57 +1430,6 @@ extern int usb_driver_set_configuration(struct usb_device *udev, int config);
 #define USB_CTRL_GET_TIMEOUT	5000
 #define USB_CTRL_SET_TIMEOUT	5000
 
-
-/**
- * struct usb_sg_request - support for scatter/gather I/O
- * @status: zero indicates success, else negative errno
- * @bytes: counts bytes transferred.
- *
- * These requests are initialized using usb_sg_init(), and then are used
- * as request handles passed to usb_sg_wait() or usb_sg_cancel().  Most
- * members of the request object aren't for driver access.
- *
- * The status and bytecount values are valid only after usb_sg_wait()
- * returns.  If the status is zero, then the bytecount matches the total
- * from the request.
- *
- * After an error completion, drivers may need to clear a halt condition
- * on the endpoint.
- */
-struct usb_sg_request {
-	int			status;
-	size_t			bytes;
-
-	/* private:
-	 * members below are private to usbcore,
-	 * and are not provided for driver access!
-	 */
-	spinlock_t		lock;
-
-	struct usb_device	*dev;
-	int			pipe;
-
-	int			entries;
-	struct urb		**urbs;
-
-	int			count;
-	struct completion	complete;
-};
-
-int usb_sg_init(
-	struct usb_sg_request	*io,
-	struct usb_device	*dev,
-	unsigned		pipe,
-	unsigned		period,
-	struct scatterlist	*sg,
-	int			nents,
-	size_t			length,
-	gfp_t			mem_flags
-);
-void usb_sg_cancel(struct usb_sg_request *io);
-void usb_sg_wait(struct usb_sg_request *io);
-
-
 /* ----------------------------------------------------------------------- */
 
 /*
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux