diff options
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/debug.c | 12 | ||||
-rw-r--r-- | drivers/usb/storage/debug.h | 3 | ||||
-rw-r--r-- | drivers/usb/storage/ene_ub6250.c | 4 | ||||
-rw-r--r-- | drivers/usb/storage/scsiglue.c | 2 | ||||
-rw-r--r-- | drivers/usb/storage/sddr09.c | 18 | ||||
-rw-r--r-- | drivers/usb/storage/uas.c | 59 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_uas.h | 7 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 5 |
8 files changed, 77 insertions, 33 deletions
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index 57bf3ad41fb6..5a12c03138f8 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c @@ -57,7 +57,6 @@ void usb_stor_show_command(const struct us_data *us, struct scsi_cmnd *srb) { char *what = NULL; - int i; switch (srb->cmnd[0]) { case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break; @@ -153,10 +152,8 @@ void usb_stor_show_command(const struct us_data *us, struct scsi_cmnd *srb) default: what = "(unknown command)"; break; } usb_stor_dbg(us, "Command %s (%d bytes)\n", what, srb->cmd_len); - usb_stor_dbg(us, "bytes: "); - for (i = 0; i < srb->cmd_len && i < 16; i++) - US_DEBUGPX(" %02x", srb->cmnd[i]); - US_DEBUGPX("\n"); + usb_stor_dbg(us, "bytes: %*ph\n", min_t(int, srb->cmd_len, 16), + (const unsigned char *)srb->cmnd); } void usb_stor_show_sense(const struct us_data *us, @@ -174,11 +171,10 @@ void usb_stor_show_sense(const struct us_data *us, if (what == NULL) what = "(unknown ASC/ASCQ)"; - usb_stor_dbg(us, "%s: ", keystr); if (fmt) - US_DEBUGPX("%s (%s%x)\n", what, fmt, ascq); + usb_stor_dbg(us, "%s: %s (%s%x)\n", keystr, what, fmt, ascq); else - US_DEBUGPX("%s\n", what); + usb_stor_dbg(us, "%s: %s\n", keystr, what); } void usb_stor_dbg(const struct us_data *us, const char *fmt, ...) diff --git a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h index f52520306e1a..6b365ce4e610 100644 --- a/drivers/usb/storage/debug.h +++ b/drivers/usb/storage/debug.h @@ -53,7 +53,6 @@ void usb_stor_show_sense(const struct us_data *us, unsigned char key, __printf(2, 3) void usb_stor_dbg(const struct us_data *us, const char *fmt, ...); -#define US_DEBUGPX(fmt, ...) printk(fmt, ##__VA_ARGS__) #define US_DEBUG(x) x #else __printf(2, 3) @@ -63,8 +62,6 @@ static inline void _usb_stor_dbg(const struct us_data *us, } #define usb_stor_dbg(us, fmt, ...) \ do { if (0) _usb_stor_dbg(us, fmt, ##__VA_ARGS__); } while (0) -#define US_DEBUGPX(fmt, ...) \ - do { if (0) printk(fmt, ##__VA_ARGS__); } while (0) #define US_DEBUG(x) #endif diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index f3cf4cecd2b7..d3a17c65a702 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -1067,12 +1067,12 @@ static void ms_lib_free_writebuf(struct us_data *us) ms_lib_clear_pagemap(info); /* (pdx)->MS_Lib.pagemap memset 0 in ms.h */ if (info->MS_Lib.blkpag) { - kfree((u8 *)(info->MS_Lib.blkpag)); /* Arnold test ... */ + kfree(info->MS_Lib.blkpag); /* Arnold test ... */ info->MS_Lib.blkpag = NULL; } if (info->MS_Lib.blkext) { - kfree((u8 *)(info->MS_Lib.blkext)); /* Arnold test ... */ + kfree(info->MS_Lib.blkext); /* Arnold test ... */ info->MS_Lib.blkext = NULL; } } diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index dba51362d2e2..90901861bfc0 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -123,7 +123,7 @@ static int slave_configure(struct scsi_device *sdev) unsigned int max_sectors = 64; if (us->fflags & US_FL_MAX_SECTORS_MIN) - max_sectors = PAGE_CACHE_SIZE >> 9; + max_sectors = PAGE_SIZE >> 9; if (queue_max_hw_sectors(sdev->request_queue) > max_sectors) blk_queue_max_hw_sectors(sdev->request_queue, max_sectors); diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index b74603689b9e..79224fcf9b59 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1102,24 +1102,24 @@ static int sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { int result; unsigned char status; + const char *wp_fmt; result = sddr09_read_status(us, &status); if (result) { usb_stor_dbg(us, "read_status fails\n"); return result; } - usb_stor_dbg(us, "status 0x%02X", status); if ((status & 0x80) == 0) { info->flags |= SDDR09_WP; /* write protected */ - US_DEBUGPX(" WP"); + wp_fmt = " WP"; + } else { + wp_fmt = ""; } - if (status & 0x40) - US_DEBUGPX(" Ready"); - if (status & LUNBITS) - US_DEBUGPX(" Suspended"); - if (status & 0x1) - US_DEBUGPX(" Error"); - US_DEBUGPX("\n"); + usb_stor_dbg(us, "status 0x%02X%s%s%s%s\n", status, wp_fmt, + status & 0x40 ? " Ready" : "", + status & LUNBITS ? " Suspended" : "", + status & 0x01 ? " Error" : ""); + return 0; } diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 9ff9404f99d7..16bc679dc2fc 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -2,7 +2,7 @@ * USB Attached SCSI * Note that this is not the same as the USB Mass Storage driver * - * Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 - 2014 + * Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 - 2016 * Copyright Matthew Wilcox for Intel Corp, 2010 * Copyright Sarah Sharp for Intel Corp, 2010 * @@ -246,6 +246,29 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, } } +static bool uas_evaluate_response_iu(struct response_iu *riu, struct scsi_cmnd *cmnd) +{ + u8 response_code = riu->response_code; + + switch (response_code) { + case RC_INCORRECT_LUN: + cmnd->result = DID_BAD_TARGET << 16; + break; + case RC_TMF_SUCCEEDED: + cmnd->result = DID_OK << 16; + break; + case RC_TMF_NOT_SUPPORTED: + cmnd->result = DID_TARGET_FAILURE << 16; + break; + default: + uas_log_cmd_state(cmnd, "response iu", response_code); + cmnd->result = DID_ERROR << 16; + break; + } + + return response_code == RC_TMF_SUCCEEDED; +} + static void uas_stat_cmplt(struct urb *urb) { struct iu *iu = urb->transfer_buffer; @@ -258,6 +281,7 @@ static void uas_stat_cmplt(struct urb *urb) unsigned long flags; unsigned int idx; int status = urb->status; + bool success; spin_lock_irqsave(&devinfo->lock, flags); @@ -313,13 +337,13 @@ static void uas_stat_cmplt(struct urb *urb) uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB); break; case IU_ID_RESPONSE: - uas_log_cmd_state(cmnd, "unexpected response iu", - ((struct response_iu *)iu)->response_code); - /* Error, cancel data transfers */ - data_in_urb = usb_get_urb(cmdinfo->data_in_urb); - data_out_urb = usb_get_urb(cmdinfo->data_out_urb); cmdinfo->state &= ~COMMAND_INFLIGHT; - cmnd->result = DID_ERROR << 16; + success = uas_evaluate_response_iu((struct response_iu *)iu, cmnd); + if (!success) { + /* Error, cancel data transfers */ + data_in_urb = usb_get_urb(cmdinfo->data_in_urb); + data_out_urb = usb_get_urb(cmdinfo->data_out_urb); + } uas_try_complete(cmnd, __func__); break; default: @@ -757,6 +781,17 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) return SUCCESS; } +static int uas_target_alloc(struct scsi_target *starget) +{ + struct uas_dev_info *devinfo = (struct uas_dev_info *) + dev_to_shost(starget->dev.parent)->hostdata; + + if (devinfo->flags & US_FL_NO_REPORT_LUNS) + starget->no_report_luns = 1; + + return 0; +} + static int uas_slave_alloc(struct scsi_device *sdev) { struct uas_dev_info *devinfo = @@ -800,7 +835,6 @@ static int uas_slave_configure(struct scsi_device *sdev) if (devinfo->flags & US_FL_BROKEN_FUA) sdev->broken_fua = 1; - scsi_change_queue_depth(sdev, devinfo->qdepth - 2); return 0; } @@ -808,11 +842,12 @@ static struct scsi_host_template uas_host_template = { .module = THIS_MODULE, .name = "uas", .queuecommand = uas_queuecommand, + .target_alloc = uas_target_alloc, .slave_alloc = uas_slave_alloc, .slave_configure = uas_slave_configure, .eh_abort_handler = uas_eh_abort_handler, .eh_bus_reset_handler = uas_eh_bus_reset_handler, - .can_queue = 65536, /* Is there a limit on the _host_ ? */ + .can_queue = MAX_CMNDS, .this_id = -1, .sg_tablesize = SG_NONE, .skip_settle_delay = 1, @@ -932,6 +967,12 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) if (result) goto set_alt0; + /* + * 1 tag is reserved for untagged commands + + * 1 tag to avoid off by one errors in some bridge firmwares + */ + shost->can_queue = devinfo->qdepth - 2; + usb_set_intfdata(intf, shost); result = scsi_add_host(shost, &intf->dev); if (result) diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index ccc113e83d88..53341a77d89f 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -64,6 +64,13 @@ UNUSUAL_DEV(0x0bc2, 0x3312, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: David Webb <djw@noc.ac.uk> */ +UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999, + "Seagate", + "Expansion Desk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_LUNS), + /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ UNUSUAL_DEV(0x0bc2, 0x3320, 0x0000, 0x9999, "Seagate", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 43576ed31ccd..9de988a0f856 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -482,7 +482,7 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | - US_FL_MAX_SECTORS_240); + US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS); p = quirks; while (*p) { @@ -532,6 +532,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) case 'i': f |= US_FL_IGNORE_DEVICE; break; + case 'j': + f |= US_FL_NO_REPORT_LUNS; + break; case 'l': f |= US_FL_NOT_LOCKABLE; break; |