Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 19184
b: refs/heads/master
c: 2c2e4a2
h: refs/heads/master
v: v3
  • Loading branch information
Pete Zaitcev authored and Greg Kroah-Hartman committed Feb 1, 2006
1 parent 70493ca commit 6ac347d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b31f821c6dee6f3ecfca6b2583a6552538fb91bf
refs/heads/master: 2c2e4a2e07f4c16486dd2ac859eb9c558b1c9935
66 changes: 59 additions & 7 deletions trunk/drivers/block/ub.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
* -- verify the 13 conditions and do bulk resets
* -- kill last_pipe and simply do two-state clearing on both pipes
* -- verify protocol (bulk) from USB descriptors (maybe...)
* -- highmem
* -- move top_sense and work_bcs into separate allocations (if they survive)
* for cache purists and esoteric architectures.
Expand Down Expand Up @@ -420,11 +419,13 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
int stalled_pipe);
static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
static void ub_reset_enter(struct ub_dev *sc);
static void ub_reset_enter(struct ub_dev *sc, int try);
static void ub_reset_task(void *arg);
static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
struct ub_capacity *ret);
static int ub_sync_reset(struct ub_dev *sc);
static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe);
static int ub_probe_lun(struct ub_dev *sc, int lnum);

/*
Expand Down Expand Up @@ -983,7 +984,7 @@ static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
if (atomic_read(&sc->poison))
return -ENXIO;

ub_reset_enter(sc);
ub_reset_enter(sc, urq->current_try);

if (urq->current_try >= 3)
return -EIO;
Expand Down Expand Up @@ -1019,8 +1020,6 @@ static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
* No exceptions.
*
* Host is assumed locked.
*
* XXX We only support Bulk for the moment.
*/
static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
Expand Down Expand Up @@ -1703,16 +1702,18 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)

/*
* Reset management
* XXX Move usb_reset_device to khubd. Hogging kevent is not a good thing.
* XXX Make usb_sync_reset asynchronous.
*/

static void ub_reset_enter(struct ub_dev *sc)
static void ub_reset_enter(struct ub_dev *sc, int try)
{

if (sc->reset) {
/* This happens often on multi-LUN devices. */
return;
}
sc->reset = 1;
sc->reset = try + 1;

#if 0 /* Not needed because the disconnect waits for us. */
unsigned long flags;
Expand Down Expand Up @@ -1750,6 +1751,11 @@ static void ub_reset_task(void *arg)
if (atomic_read(&sc->poison)) {
printk(KERN_NOTICE "%s: Not resetting disconnected device\n",
sc->name); /* P3 This floods. Remove soon. XXX */
} else if ((sc->reset & 1) == 0) {
ub_sync_reset(sc);
msleep(700); /* usb-storage sleeps 6s (!) */
ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
ub_probe_clear_stall(sc, sc->send_bulk_pipe);
} else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
printk(KERN_NOTICE "%s: Not resetting multi-interface device\n",
sc->name); /* P3 This floods. Remove soon. XXX */
Expand Down Expand Up @@ -2140,6 +2146,52 @@ static void ub_probe_timeout(unsigned long arg)
complete(cop);
}

/*
* Reset with a Bulk reset.
*/
static int ub_sync_reset(struct ub_dev *sc)
{
int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber;
struct usb_ctrlrequest *cr;
struct completion compl;
struct timer_list timer;
int rc;

init_completion(&compl);

cr = &sc->work_cr;
cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
cr->bRequest = US_BULK_RESET_REQUEST;
cr->wValue = cpu_to_le16(0);
cr->wIndex = cpu_to_le16(ifnum);
cr->wLength = cpu_to_le16(0);

usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
(unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);
sc->work_urb.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;

if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
printk(KERN_WARNING
"%s: Unable to submit a bulk reset (%d)\n", sc->name, rc);
return rc;
}

init_timer(&timer);
timer.function = ub_probe_timeout;
timer.data = (unsigned long) &compl;
timer.expires = jiffies + UB_CTRL_TIMEOUT;
add_timer(&timer);

wait_for_completion(&compl);

del_timer_sync(&timer);
usb_kill_urb(&sc->work_urb);

return sc->work_urb.status;
}

/*
* Get number of LUNs by the way of Bulk GetMaxLUN command.
*/
Expand Down

0 comments on commit 6ac347d

Please sign in to comment.