+ usb-ub-drop-bug-and-update-small-things.patch added to -mm tree

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

 



The patch titled
     ub: drop BUG() and update small things
has been added to the -mm tree.  Its filename is
     usb-ub-drop-bug-and-update-small-things.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: ub: drop BUG() and update small things


- Remove the BUG() which trips, borrow the code from scsi_end_request().
  This may break CD burning, because I am not sure residue gets returned
  to cdrecord for successful commands. But everything that's good for SCSI
  should be good for everyone else, right?
- Ignore improper USB level residue. Too many devices have this bug.
- Update cosmetics: spelling, formatting

Signed-off-by: Pete Zaitcev <zaitcev@xxxxxxxxxx>
Cc: Chris Wedgwood <cw@xxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
Cc: Kiyoshi Ueda <k-ueda@xxxxxxxxxxxxx>
Cc: Martin Schwidefsky <schwidefsky@xxxxxxxxxx>
Cc: Jens Axboe <jens.axboe@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 drivers/block/ub.c |   76 +++++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 31 deletions(-)

diff -puN drivers/block/ub.c~usb-ub-drop-bug-and-update-small-things drivers/block/ub.c
--- a/drivers/block/ub.c~usb-ub-drop-bug-and-update-small-things
+++ a/drivers/block/ub.c
@@ -317,6 +317,7 @@ struct ub_dev {
 	int openc;			/* protected by ub_lock! */
 					/* kref is too implicit for our taste */
 	int reset;			/* Reset is running */
+	int bad_resid;
 	unsigned int tagcnt;
 	char name[12];
 	struct usb_device *dev;
@@ -359,7 +360,8 @@ static void ub_cmd_build_block(struct ub
 static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_scsi_cmd *cmd, struct ub_request *urq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
-static void ub_end_rq(struct request *rq, unsigned int status);
+static void ub_end_rq(struct request *rq, unsigned int status,
+    unsigned int act_len);
 static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_request *urq, struct ub_scsi_cmd *cmd);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -642,13 +644,13 @@ static int ub_request_fn_1(struct ub_lun
 
 	if (atomic_read(&sc->poison)) {
 		blkdev_dequeue_request(rq);
-		ub_end_rq(rq, DID_NO_CONNECT << 16);
+		ub_end_rq(rq, DID_NO_CONNECT << 16, 0);
 		return 0;
 	}
 
 	if (lun->changed && !blk_pc_request(rq)) {
 		blkdev_dequeue_request(rq);
-		ub_end_rq(rq, SAM_STAT_CHECK_CONDITION);
+		ub_end_rq(rq, SAM_STAT_CHECK_CONDITION, 0);
 		return 0;
 	}
 
@@ -701,7 +703,7 @@ static int ub_request_fn_1(struct ub_lun
 
 drop:
 	ub_put_cmd(lun, cmd);
-	ub_end_rq(rq, DID_ERROR << 16);
+	ub_end_rq(rq, DID_ERROR << 16, 0);
 	return 0;
 }
 
@@ -770,16 +772,11 @@ static void ub_rw_cmd_done(struct ub_dev
 	struct ub_request *urq = cmd->back;
 	struct request *rq;
 	unsigned int scsi_status;
+	unsigned int act_len;
 
 	rq = urq->rq;
 
 	if (cmd->error == 0) {
-		if (blk_pc_request(rq)) {
-			if (cmd->act_len >= rq->data_len)
-				rq->data_len = 0;
-			else
-				rq->data_len -= cmd->act_len;
-		}
 		scsi_status = 0;
 	} else {
 		if (blk_pc_request(rq)) {
@@ -799,16 +796,21 @@ static void ub_rw_cmd_done(struct ub_dev
 		}
 	}
 
+	if ((act_len = cmd->act_len) > cmd->len)
+		act_len = cmd->len;
+
 	urq->rq = NULL;
 
 	ub_put_cmd(lun, cmd);
-	ub_end_rq(rq, scsi_status);
+	ub_end_rq(rq, scsi_status, act_len);
 	blk_start_queue(lun->disk->queue);
 }
 
-static void ub_end_rq(struct request *rq, unsigned int scsi_status)
+static void ub_end_rq(struct request *rq, unsigned int scsi_status,
+    unsigned int act_len)
 {
 	int error;
+	long rqlen;
 
 	if (scsi_status == 0) {
 		error = 0;
@@ -816,8 +818,18 @@ static void ub_end_rq(struct request *rq
 		error = -EIO;
 		rq->errors = scsi_status;
 	}
-	if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
-		BUG();
+	rqlen = blk_rq_bytes(rq);
+	if (__blk_end_request(rq, error, act_len)) {
+		if (error) {
+			if (__blk_end_request(rq, error, blk_rq_bytes(rq))) {
+				printk(KERN_WARNING DRV_NAME
+				    ": __blk_end_request blew,"
+				    " %s-cmd rqlen %ld act %u\n",
+				    blk_pc_request(rq)? "pc": "fs",
+				    rqlen, act_len);
+			}
+		}
+	}
 }
 
 static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
@@ -1239,14 +1251,19 @@ static void ub_scsi_urb_compl(struct ub_
 			return;
 		}
 
-		len = le32_to_cpu(bcs->Residue);
-		if (len != cmd->len - cmd->act_len) {
-			/*
-			 * It is all right to transfer less, the caller has
-			 * to check. But it's not all right if the device
-			 * counts disagree with our counts.
-			 */
-			goto Bad_End;
+		if (!sc->bad_resid) {
+			len = le32_to_cpu(bcs->Residue);
+			if (len != cmd->len - cmd->act_len) {
+				/*
+				 * Only start ignoring if this cmd ended well.
+				 */
+				if (cmd->len == cmd->act_len) {
+					printk(KERN_NOTICE "%s: "
+					    "bad residual %d of %d, ignoring\n",
+					    sc->name, len, cmd->len);
+					sc->bad_resid = 1;
+				}
+			}
 		}
 
 		switch (bcs->Status) {
@@ -1277,8 +1294,7 @@ static void ub_scsi_urb_compl(struct ub_
 		ub_state_done(sc, cmd, -EIO);
 
 	} else {
-		printk(KERN_WARNING "%s: "
-		    "wrong command state %d\n",
+		printk(KERN_WARNING "%s: wrong command state %d\n",
 		    sc->name, cmd->state);
 		ub_state_done(sc, cmd, -EINVAL);
 		return;
@@ -1495,8 +1511,7 @@ static void ub_top_sense_done(struct ub_
 		return;
 	}
 	if (cmd->state != UB_CMDST_SENSE) {
-		printk(KERN_WARNING "%s: "
-		    "sense done with bad cmd state %d\n",
+		printk(KERN_WARNING "%s: sense done with bad cmd state %d\n",
 		    sc->name, cmd->state);
 		return;
 	}
@@ -1700,7 +1715,7 @@ static int ub_bd_ioctl(struct inode *ino
 }
 
 /*
- * This is called once a new disk was seen by the block layer or by ub_probe().
+ * This is called by check_disk_change if we reported a media change.
  * The main onjective here is to discover the features of the media such as
  * the capacity, read-only status, etc. USB storage generally does not
  * need to be spun up, but if we needed it, this would be the place.
@@ -2116,8 +2131,7 @@ static int ub_get_pipes(struct ub_dev *s
 	}
 
 	if (ep_in == NULL || ep_out == NULL) {
-		printk(KERN_NOTICE "%s: failed endpoint check\n",
-		    sc->name);
+		printk(KERN_NOTICE "%s: failed endpoint check\n", sc->name);
 		return -ENODEV;
 	}
 
@@ -2334,7 +2348,7 @@ static void ub_disconnect(struct usb_int
 	spin_unlock_irqrestore(&ub_lock, flags);
 
 	/*
-	 * Fence stall clearnings, operations triggered by unlinkings and so on.
+	 * Fence stall clearings, operations triggered by unlinkings and so on.
 	 * We do not attempt to unlink any URBs, because we do not trust the
 	 * unlink paths in HC drivers. Also, we get -84 upon disconnect anyway.
 	 */
@@ -2397,7 +2411,7 @@ static void ub_disconnect(struct usb_int
 	spin_unlock_irqrestore(sc->lock, flags);
 
 	/*
-	 * There is virtually no chance that other CPU runs times so long
+	 * There is virtually no chance that other CPU runs a timeout so long
 	 * after ub_urb_complete should have called del_timer, but only if HCD
 	 * didn't forget to deliver a callback on unlink.
 	 */
_

Patches currently in -mm which might be from zaitcev@xxxxxxxxxx are

usb-ub-drop-bug-and-update-small-things.patch
git-hid.patch

--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux