diff options
author | hselasky <hselasky@FreeBSD.org> | 2011-09-02 18:50:44 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2011-09-02 18:50:44 +0000 |
commit | 8335f4b89d8e67c285a31d6b11a370185ce0b949 (patch) | |
tree | c6f2687acbbed316803ce152679d1c321f8174e7 /sys/dev/usb/usb_device.c | |
parent | 56a7a5d12f3bd0a91a39b86bb619324e35c2c6b9 (diff) | |
download | FreeBSD-src-8335f4b89d8e67c285a31d6b11a370185ce0b949.zip FreeBSD-src-8335f4b89d8e67c285a31d6b11a370185ce0b949.tar.gz |
This patch adds automatic detection of USB mass storage devices
which does not support the no synchronize cache SCSI command.
The __FreeBSD_version version macro has been bumped and
external kernel modules needs to be recompiled after
this patch.
Approved by: re (kib)
MFC after: 1 week
PR: usb/160299
Diffstat (limited to 'sys/dev/usb/usb_device.c')
-rw-r--r-- | sys/dev/usb/usb_device.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 34f6265..3be9ba9 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -1239,7 +1239,9 @@ static void usb_init_attach_arg(struct usb_device *udev, struct usb_attach_arg *uaa) { - bzero(uaa, sizeof(*uaa)); + uint8_t x; + + memset(uaa, 0, sizeof(*uaa)); uaa->device = udev; uaa->usb_mode = udev->flags.usb_mode; @@ -1254,6 +1256,9 @@ usb_init_attach_arg(struct usb_device *udev, uaa->info.bDeviceProtocol = udev->ddesc.bDeviceProtocol; uaa->info.bConfigIndex = udev->curr_config_index; uaa->info.bConfigNum = udev->curr_config_no; + + for (x = 0; x != USB_MAX_AUTO_QUIRK; x++) + uaa->info.autoQuirk[x] = udev->autoQuirk[x]; } /*------------------------------------------------------------------------* @@ -1850,6 +1855,20 @@ repeat_set_config: } } } + if (set_config_failed == 0 && config_index == 0 && + usb_test_quirk(&uaa, UQ_MSC_NO_SYNC_CACHE) == 0) { + + /* + * Try to figure out if there are any MSC quirks we + * should apply automatically: + */ + err = usb_msc_auto_quirk(udev, 0); + + if (err != 0) { + set_config_failed = 1; + goto repeat_set_config; + } + } config_done: DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n", @@ -2698,3 +2717,16 @@ usbd_set_pnpinfo(struct usb_device *udev, uint8_t iface_index, const char *pnpin return (0); /* success */ } +usb_error_t +usbd_add_dynamic_quirk(struct usb_device *udev, uint16_t quirk) +{ + uint8_t x; + + for (x = 0; x != USB_MAX_AUTO_QUIRK; x++) { + if (udev->autoQuirk[x] == 0) { + udev->autoQuirk[x] = quirk; + return (0); /* success */ + } + } + return (USB_ERR_NOMEM); +} |