usb/160299: commit references a PR

dfilter service dfilter at FreeBSD.ORG
Fri Sep 9 07:50:07 UTC 2011


The following reply was made to PR usb/160299; it has been noted by GNATS.

From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: usb/160299: commit references a PR
Date: Fri,  9 Sep 2011 07:44:24 +0000 (UTC)

 Author: hselasky
 Date: Fri Sep  9 07:44:14 2011
 New Revision: 225458
 URL: http://svn.freebsd.org/changeset/base/225458
 
 Log:
   MFC r225350 and r225400:
   
   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.
   
   PR:	usb/160299
 
 Modified:
   stable/8/sys/dev/usb/quirk/usb_quirk.c
   stable/8/sys/dev/usb/storage/umass.c
   stable/8/sys/dev/usb/usb_device.c
   stable/8/sys/dev/usb/usb_device.h
   stable/8/sys/dev/usb/usb_dynamic.c
   stable/8/sys/dev/usb/usb_dynamic.h
   stable/8/sys/dev/usb/usb_freebsd.h
   stable/8/sys/dev/usb/usb_msctest.c
   stable/8/sys/dev/usb/usb_msctest.h
   stable/8/sys/dev/usb/usbdi.h
   stable/8/sys/sys/param.h
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
 
 Modified: stable/8/sys/dev/usb/quirk/usb_quirk.c
 ==============================================================================
 --- stable/8/sys/dev/usb/quirk/usb_quirk.c	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/quirk/usb_quirk.c	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -148,12 +148,10 @@ static struct usb_quirk_entry usb_quirks
  	    UQ_MSC_FORCE_PROTO_SCSI),
  	USB_QUIRK(AIPTEK, POCKETCAM3M, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI),
 -	USB_QUIRK(AIPTEK2, SUNPLUS_TECH, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(ALCOR, SDCR_6335, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY,
  	    UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(ALCOR, SDCR_6362, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY,
  	    UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(ALCOR, AU6390, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(ALCOR, UMCR_9361, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
  	USB_QUIRK(ALCOR, TRANSCEND, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN,
 @@ -173,14 +171,12 @@ static struct usb_quirk_entry usb_quirks
  	USB_QUIRK(CENTURY, EX35QUAT, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ,
  	    UQ_MSC_NO_START_STOP, UQ_MSC_IGNORE_RESIDUE),
 -	USB_QUIRK(CENTURY, EX35SW4_SB4, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(CYPRESS, XX6830XX, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN,
  	    UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(DESKNOTE, UCR_61S2B, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI),
  	USB_QUIRK(DMI, CFSM_RW, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI,
  	    UQ_MSC_NO_GETMAXLUN),
 -	USB_QUIRK(DMI, DISK, 0x000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(EPSON, STYLUS_875DC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
  	USB_QUIRK(EPSON, STYLUS_895, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 @@ -188,7 +184,6 @@ static struct usb_quirk_entry usb_quirks
  	USB_QUIRK(FEIYA, 5IN1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI),
  	USB_QUIRK(FREECOM, DVD, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI),
 -	USB_QUIRK(FREECOM, HDD, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(FUJIPHOTO, MASS0100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI_I,
  	    UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_RS_CLEAR_UA, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(GENESYS, GL641USB2IDE, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 @@ -232,7 +227,6 @@ static struct usb_quirk_entry usb_quirks
  	USB_QUIRK(IOMEGA, ZIP100, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI,
  	    UQ_MSC_NO_TEST_UNIT_READY), /* XXX ZIP drives can also use ATAPI */
 -	USB_QUIRK(JMICRON, JM20336, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI,
  	    UQ_MSC_NO_SYNC_CACHE),
 @@ -279,8 +273,6 @@ static struct usb_quirk_entry usb_quirks
  	    UQ_MSC_FORCE_PROTO_ATAPI),
  	USB_QUIRK(MYSON, HEDEN, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE,
  	    UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(MYSON, HEDEN_8813, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(MYSON, STARREADER, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(NEODIO, ND3260, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_FORCE_SHORT_INQ),
  	USB_QUIRK(NETAC, CF_CARD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 @@ -317,7 +309,6 @@ static struct usb_quirk_entry usb_quirks
  	USB_QUIRK(PANASONIC, KXLCB35AN, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI),
  	USB_QUIRK(PANASONIC, LS120CAM, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_UFI),
 -	USB_QUIRK(PHILIPS, SPE3030CC, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(PLEXTOR, 40_12_40U, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_TEST_UNIT_READY),
  	USB_QUIRK(PNY, ATTACHE2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 @@ -328,7 +319,6 @@ static struct usb_quirk_entry usb_quirks
  	USB_QUIRK_VP(USB_VENDOR_SAMSUNG_TECHWIN,
  	    USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY),
 -	USB_QUIRK(SAMSUNG, YP_U4, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  	USB_QUIRK(SANDISK, SDDR05A, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1,
  	    UQ_MSC_NO_GETMAXLUN),
 @@ -448,12 +438,6 @@ static struct usb_quirk_entry usb_quirks
  	    UQ_MSC_FORCE_PROTO_ATAPI),
  	USB_QUIRK(MEIZU, M6_SL, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
  	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY, UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(ACTIONS, MP4, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
 -	    UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(ASUS, GMSC, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(CHIPSBANK, USBMEMSTICK, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(CHIPSBANK, USBMEMSTICK1, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
 -	USB_QUIRK(NEWLINK, USB2IDEBRIDGE, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
  
  	/* Non-standard USB MIDI devices */
  	USB_QUIRK(ROLAND, UM1, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
 @@ -567,9 +551,9 @@ usb_test_quirk_by_info(const struct usbd
  	uint16_t x;
  	uint16_t y;
  
 -	if (quirk == UQ_NONE) {
 -		return (0);
 -	}
 +	if (quirk == UQ_NONE)
 +		goto done;
 +
  	mtx_lock(&usb_quirk_mtx);
  
  	for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
 @@ -603,7 +587,8 @@ usb_test_quirk_by_info(const struct usbd
  		break;
  	}
  	mtx_unlock(&usb_quirk_mtx);
 -	return (0);
 +done:
 +	return (usb_test_quirk_w(info, quirk));
  }
  
  static struct usb_quirk_entry *
 
 Modified: stable/8/sys/dev/usb/storage/umass.c
 ==============================================================================
 --- stable/8/sys/dev/usb/storage/umass.c	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/storage/umass.c	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -1025,12 +1025,6 @@ umass_attach(device_t dev)
  	sc->cam_scsi_sense.opcode = REQUEST_SENSE;
  	sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY;
  
 -	/*
 -	 * some devices need a delay after that the configuration value is
 -	 * set to function properly:
 -	 */
 -	usb_pause_mtx(NULL, hz);
 -
  	/* register the SIM */
  	err = umass_cam_attach_sim(sc);
  	if (err) {
 
 Modified: stable/8/sys/dev/usb/usb_device.c
 ==============================================================================
 --- stable/8/sys/dev/usb/usb_device.c	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usb_device.c	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -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 *u
  	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",
 @@ -2773,3 +2792,16 @@ usbd_set_pnpinfo(struct usb_device *udev
  	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);
 +}
 
 Modified: stable/8/sys/dev/usb/usb_device.h
 ==============================================================================
 --- stable/8/sys/dev/usb/usb_device.h	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usb_device.h	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -149,6 +149,7 @@ struct usb_device {
  
  	uint16_t power;			/* mA the device uses */
  	uint16_t langid;		/* language for strings */
 +	uint16_t autoQuirk[USB_MAX_AUTO_QUIRK];		/* dynamic quirks */
  
  	uint8_t	address;		/* device addess */
  	uint8_t	device_index;		/* device index in "bus->devices" */
 
 Modified: stable/8/sys/dev/usb/usb_dynamic.c
 ==============================================================================
 --- stable/8/sys/dev/usb/usb_dynamic.c	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usb_dynamic.c	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -50,12 +50,12 @@
  #include <dev/usb/usb_process.h>
  #include <dev/usb/usb_device.h>
  #include <dev/usb/usb_dynamic.h>
 +#include <dev/usb/quirk/usb_quirk.h>
  
  /* function prototypes */
  static usb_handle_req_t usb_temp_get_desc_w;
  static usb_temp_setup_by_index_t usb_temp_setup_by_index_w;
  static usb_temp_unsetup_t usb_temp_unsetup_w;
 -static usb_test_quirk_t usb_test_quirk_w;
  static usb_quirk_ioctl_t usb_quirk_ioctl_w;
  
  /* global variables */
 @@ -72,9 +72,19 @@ usb_temp_setup_by_index_w(struct usb_dev
  	return (USB_ERR_INVAL);
  }
  
 -static uint8_t
 +uint8_t
  usb_test_quirk_w(const struct usbd_lookup_info *info, uint16_t quirk)
  {
 +	uint8_t x;
 +
 +	if (quirk == UQ_NONE)
 +		return (0);	/* no match */
 +
 +	for (x = 0; x != USB_MAX_AUTO_QUIRK; x++) {
 +		if (info->autoQuirk[x] == quirk)
 +			return (1);	/* match */
 +	}
 +
  	return (0);			/* no match */
  }
  
 
 Modified: stable/8/sys/dev/usb/usb_dynamic.h
 ==============================================================================
 --- stable/8/sys/dev/usb/usb_dynamic.h	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usb_dynamic.h	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -57,5 +57,6 @@ extern devclass_t usb_devclass_ptr;
  void	usb_temp_unload(void *);
  void	usb_quirk_unload(void *);
  void	usb_bus_unload(void *);
 +usb_test_quirk_t usb_test_quirk_w;
  
  #endif					/* _USB_DYNAMIC_H_ */
 
 Modified: stable/8/sys/dev/usb/usb_freebsd.h
 ==============================================================================
 --- stable/8/sys/dev/usb/usb_freebsd.h	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usb_freebsd.h	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -60,6 +60,8 @@
  #define	USB_EP0_BUFSIZE		1024	/* bytes */
  #define	USB_CS_RESET_LIMIT	20	/* failures = 20 * 50 ms = 1sec */
  
 +#define	USB_MAX_AUTO_QUIRK	4	/* maximum number of dynamic quirks */
 +
  typedef uint32_t usb_timeout_t;		/* milliseconds */
  typedef uint32_t usb_frlength_t;	/* bytes */
  typedef uint32_t usb_frcount_t;		/* units */
 
 Modified: stable/8/sys/dev/usb/usb_msctest.c
 ==============================================================================
 --- stable/8/sys/dev/usb/usb_msctest.c	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usb_msctest.c	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -1,6 +1,6 @@
  /* $FreeBSD$ */
  /*-
 - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 + * Copyright (c) 2008,2011 Hans Petter Selasky. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
 @@ -84,7 +84,10 @@ enum {
  	DIR_NONE,
  };
  
 +#define	SCSI_MAX_LEN	0x100
  #define	SCSI_INQ_LEN	0x24
 +#define	SCSI_SENSE_LEN	0xFF
 +
  static uint8_t scsi_test_unit_ready[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  static uint8_t scsi_inquiry[] = { 0x12, 0x00, 0x00, 0x00, SCSI_INQ_LEN, 0x00 };
  static uint8_t scsi_rezero_init[] =     { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
 @@ -97,6 +100,10 @@ static uint8_t scsi_huawei_eject[] =	{ 0
  					  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  					  0x00, 0x00, 0x00, 0x00 };
  static uint8_t scsi_tct_eject[] =	{ 0x06, 0xf5, 0x04, 0x02, 0x52, 0x70 };
 +static uint8_t scsi_sync_cache[] =	{ 0x35, 0x00, 0x00, 0x00, 0x00, 0x00,
 +					  0x00, 0x00, 0x00, 0x00 };
 +static uint8_t scsi_request_sense[] =	{ 0x03, 0x00, 0x00, 0x00, 0x12, 0x00,
 +					  0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  
  #define	BULK_SIZE		64	/* dummy */
  #define	ERR_CSW_FAILED		-1
 @@ -150,7 +157,7 @@ struct bbb_transfer {
  	uint8_t	status_try;
  	int	error;
  
 -	uint8_t	buffer[256];
 +	uint8_t	buffer[SCSI_MAX_LEN] __aligned(4);
  };
  
  static usb_callback_t bbb_command_callback;
 @@ -164,7 +171,7 @@ static void	bbb_done(struct bbb_transfer
  static void	bbb_transfer_start(struct bbb_transfer *, uint8_t);
  static void	bbb_data_clear_stall_callback(struct usb_xfer *, uint8_t,
  		    uint8_t);
 -static uint8_t bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t,
 +static int	bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t,
  		    void *, size_t, void *, size_t, usb_timeout_t);
  static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t);
  static void	bbb_detach(struct bbb_transfer *);
 @@ -455,7 +462,7 @@ bbb_status_callback(struct usb_xfer *xfe
   * 0: Success
   * Else: Failure
   *------------------------------------------------------------------------*/
 -static uint8_t
 +static int
  bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
      void *data_ptr, size_t data_len, void *cmd_ptr, size_t cmd_len,
      usb_timeout_t data_timeout)
 @@ -567,9 +574,10 @@ int
  usb_iface_is_cdrom(struct usb_device *udev, uint8_t iface_index)
  {
  	struct bbb_transfer *sc;
 -	usb_error_t err;
 -	uint8_t timeout, is_cdrom;
 +	uint8_t timeout;
 +	uint8_t is_cdrom;
  	uint8_t sid_type;
 +	int err;
  
  	sc = bbb_attach(udev, iface_index);
  	if (sc == NULL)
 @@ -596,6 +604,114 @@ usb_iface_is_cdrom(struct usb_device *ud
  }
  
  usb_error_t
 +usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index)
 +{
 +	struct bbb_transfer *sc;
 +	uint8_t timeout;
 +	uint8_t is_no_direct;
 +	uint8_t sid_type;
 +	int err;
 +
 +	sc = bbb_attach(udev, iface_index);
 +	if (sc == NULL)
 +		return (0);
 +
 +	/*
 +	 * Some devices need a delay after that the configuration
 +	 * value is set to function properly:
 +	 */
 +	usb_pause_mtx(NULL, hz);
 +
 +	is_no_direct = 1;
 +	for (timeout = 4; timeout; timeout--) {
 +		err = bbb_command_start(sc, DIR_IN, 0, sc->buffer,
 +		    SCSI_INQ_LEN, &scsi_inquiry, sizeof(scsi_inquiry),
 +		    USB_MS_HZ);
 +
 +		if (err == 0 && sc->actlen > 0) {
 +			sid_type = sc->buffer[0] & 0x1F;
 +			if (sid_type == 0x00)
 +				is_no_direct = 0;
 +			break;
 +		} else if (err != ERR_CSW_FAILED)
 +			break;	/* non retryable error */
 +		usb_pause_mtx(NULL, hz);
 +	}
 +
 +	if (is_no_direct) {
 +		DPRINTF("Device is not direct access.\n");
 +		goto done;
 +	}
 +
 +	err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
 +	    &scsi_test_unit_ready, sizeof(scsi_test_unit_ready),
 +	    USB_MS_HZ);
 +
 +	if (err != 0) {
 +
 +		if (err != ERR_CSW_FAILED)
 +			goto error;
 +	}
 +
 +	err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
 +	    &scsi_sync_cache, sizeof(scsi_sync_cache),
 +	    USB_MS_HZ);
 +
 +	if (err != 0) {
 +
 +		if (err != ERR_CSW_FAILED)
 +			goto error;
 +
 +		DPRINTF("Device doesn't handle synchronize cache\n");
 +
 +		usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE);
 +	}
 +
 +	/* clear sense status of any failed commands on the device */
 +
 +	err = bbb_command_start(sc, DIR_IN, 0, sc->buffer,
 +	    SCSI_INQ_LEN, &scsi_inquiry, sizeof(scsi_inquiry),
 +	    USB_MS_HZ);
 +
 +	DPRINTF("Inquiry = %d\n", err);
 +
 +	if (err != 0) {
 +
 +		if (err != ERR_CSW_FAILED)
 +			goto error;
 +	}
 +
 +	err = bbb_command_start(sc, DIR_IN, 0, sc->buffer,
 +	    SCSI_SENSE_LEN, &scsi_request_sense,
 +	    sizeof(scsi_request_sense), USB_MS_HZ);
 +
 +	DPRINTF("Request sense = %d\n", err);
 +
 +	if (err != 0) {
 +
 +		if (err != ERR_CSW_FAILED)
 +			goto error;
 +	}
 +
 +done:
 +	bbb_detach(sc);
 +	return (0);
 +
 +error:
 + 	bbb_detach(sc);
 +
 +	DPRINTF("Device did not respond, enabling all quirks\n");
 +
 +	usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE);
 +	usbd_add_dynamic_quirk(udev, UQ_MSC_NO_TEST_UNIT_READY);
 +
 +	/* Need to re-enumerate the device */
 +	usbd_req_re_enumerate(udev, NULL);
 +
 +	return (USB_ERR_STALLED);
 +}
 +
 +usb_error_t
  usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
  {
  	struct bbb_transfer *sc;
 
 Modified: stable/8/sys/dev/usb/usb_msctest.h
 ==============================================================================
 --- stable/8/sys/dev/usb/usb_msctest.h	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usb_msctest.h	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -40,5 +40,7 @@ int usb_iface_is_cdrom(struct usb_device
  	    uint8_t iface_index);
  usb_error_t usb_msc_eject(struct usb_device *udev,
  	    uint8_t iface_index, int method);
 +usb_error_t usb_msc_auto_quirk(struct usb_device *udev,
 +	    uint8_t iface_index);
  
  #endif					/* _USB_MSCTEST_H_ */
 
 Modified: stable/8/sys/dev/usb/usbdi.h
 ==============================================================================
 --- stable/8/sys/dev/usb/usbdi.h	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/dev/usb/usbdi.h	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -353,6 +353,7 @@ struct usbd_lookup_info {
  	uint16_t idVendor;
  	uint16_t idProduct;
  	uint16_t bcdDevice;
 +	uint16_t autoQuirk[USB_MAX_AUTO_QUIRK];
  	uint8_t	bDeviceClass;
  	uint8_t	bDeviceSubClass;
  	uint8_t	bDeviceProtocol;
 @@ -475,6 +476,8 @@ void	device_set_usb_desc(device_t dev);
  void	usb_pause_mtx(struct mtx *mtx, int _ticks);
  usb_error_t	usbd_set_pnpinfo(struct usb_device *udev,
  			uint8_t iface_index, const char *pnpinfo);
 +usb_error_t	usbd_add_dynamic_quirk(struct usb_device *udev,
 +			uint16_t quirk);
  
  const struct usb_device_id *usbd_lookup_id_by_info(
  	    const struct usb_device_id *id, usb_size_t sizeof_id,
 
 Modified: stable/8/sys/sys/param.h
 ==============================================================================
 --- stable/8/sys/sys/param.h	Fri Sep  9 04:42:11 2011	(r225457)
 +++ stable/8/sys/sys/param.h	Fri Sep  9 07:44:14 2011	(r225458)
 @@ -58,7 +58,7 @@
   *		in the range 5 to 9.
   */
  #undef __FreeBSD_version
 -#define __FreeBSD_version 802510	/* Master, propagated to newvers */
 +#define __FreeBSD_version 802511	/* Master, propagated to newvers */
  
  #ifdef _KERNEL
  #define	P_OSREL_SIGSEGV		700004
 _______________________________________________
 svn-src-all at freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
 


More information about the freebsd-usb mailing list