ChangeSet 1.1867.3.8, 2004/09/14 11:56:06-07:00, [EMAIL PROTECTED] [PATCH] USB: Patch for 3 ub bugs in 2.6.9-rc1-mm4
Actual users of ub quickly found problems, so here's a patch to address some of them. #1: An attempt to mount a CF card, pull the plug, then unmount causes a message "getblk: bad sector size 512" and an oops. This is caused by trying to do put_disk from disconnect instead of using a reference count. The sd.c does it this way (it uses kref). #2: The hald fills /var/log/messages with block device errors. It seems that it happens because ub allowed opens of known offline devices, and then partition checking produced those errors. I hope taking code from sd.c should fix it. Also I replaced usb_unlink_urb with usb_kill_urb. Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]> drivers/block/ub.c | 43 +++++++++++++++++++++++++------------------ 1 files changed, 25 insertions(+), 18 deletions(-) diff -Nru a/drivers/block/ub.c b/drivers/block/ub.c --- a/drivers/block/ub.c 2004-10-19 08:13:47 -07:00 +++ b/drivers/block/ub.c 2004-10-19 08:13:47 -07:00 @@ -490,6 +490,18 @@ */ static void ub_cleanup(struct ub_dev *sc) { + + /* + * If we zero disk->private_data BEFORE put_disk, we have to check + * for NULL all over the place in open, release, check_media and + * revalidate, because the block level semaphore is well inside the + * put_disk. But we cannot zero after the call, because *disk is gone. + * The sd.c is blatantly racy in this area. + */ + /* disk->private_data = NULL; */ + put_disk(sc->disk); + sc->disk = NULL; + ub_id_put(sc->id); kfree(sc); } @@ -1413,7 +1425,15 @@ if (sc->removable || sc->readonly) check_disk_change(inode->i_bdev); - /* XXX sd.c and floppy.c bail on open if media is not present. */ + /* + * The sd.c considers ->media_present and ->changed not equivalent, + * under some pretty murky conditions (a failure of READ CAPACITY). + * We may need it one day. + */ + if (sc->removable && sc->changed && !(filp->f_flags & O_NDELAY)) { + rc = -ENOMEDIUM; + goto err_open; + } if (sc->readonly && (filp->f_mode & FMODE_WRITE)) { rc = -EROFS; @@ -1498,8 +1518,11 @@ printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n", sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize); + /* XXX Support sector size switching like in sr.c */ + // blk_queue_hardsect_size(q, sc->capacity.bsize); set_capacity(disk, sc->capacity.nsec); // set_disk_ro(sdkp->disk, sc->readonly); + return 0; } @@ -1746,12 +1769,7 @@ wait_for_completion(&compl); del_timer_sync(&timer); - /* - * Most of the time, URB was done and dev set to NULL, and so - * the unlink bounces out with ENODEV. We do not call usb_kill_urb - * because we still think about a backport to 2.4. - */ - usb_unlink_urb(&sc->work_urb); + usb_kill_urb(&sc->work_urb); /* reset the endpoint toggle */ usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0); @@ -2009,17 +2027,6 @@ del_gendisk(disk); if (q) blk_cleanup_queue(q); - - /* - * If we zero disk->private_data BEFORE put_disk, we have to check - * for NULL all over the place in open, release, check_media and - * revalidate, because the block level semaphore is well inside the - * put_disk. But we cannot zero after the call, because *disk is gone. - * The sd.c is blatantly racy in this area. - */ - /* disk->private_data = NULL; */ - put_disk(disk); - sc->disk = NULL; /* * We really expect blk_cleanup_queue() to wait, so no amount ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel