diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/core/core.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc.c | 8 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio.c | 51 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_bus.c | 33 | ||||
| -rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 12 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 31 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-pxa.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci.c | 54 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci.h | 9 | ||||
| -rw-r--r-- | drivers/mmc/host/ushc.c | 30 | 
11 files changed, 174 insertions, 62 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8f86d702e46e..31ae07a36576 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host)  	if (host->caps & MMC_CAP_DISABLE)  		cancel_delayed_work(&host->disable); -	cancel_delayed_work(&host->detect); +	cancel_delayed_work_sync(&host->detect);  	mmc_flush_scheduled_work();  	/* clear pm flags now and let card drivers set them as needed */ diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 995261f7fd70..77f93c3b8808 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  	struct mmc_card *oldcard)  {  	struct mmc_card *card; -	int err, ddr = MMC_SDR_MODE; +	int err, ddr = 0;  	u32 cid[4];  	unsigned int max_dtr; @@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,  			       1 << bus_width, ddr);  			err = 0;  		} else { -			mmc_card_set_ddr_mode(card); +			if (ddr) +				mmc_card_set_ddr_mode(card); +			else +				ddr = MMC_SDR_MODE; +  			mmc_set_bus_width_ddr(card->host, bus_width, ddr);  		}  	} diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c3ad1058cd31..efef5f94ac42 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host)  	BUG_ON(!host->card);  	/* Make sure card is powered before detecting it */ -	err = pm_runtime_get_sync(&host->card->dev); -	if (err < 0) -		goto out; +	if (host->caps & MMC_CAP_POWER_OFF_CARD) { +		err = pm_runtime_get_sync(&host->card->dev); +		if (err < 0) +			goto out; +	}  	mmc_claim_host(host); @@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_host *host)  	mmc_release_host(host); +	/* +	 * Tell PM core it's OK to power off the card now. +	 * +	 * The _sync variant is used in order to ensure that the card +	 * is left powered off in case an error occurred, and the card +	 * is going to be removed. +	 * +	 * Since there is no specific reason to believe a new user +	 * is about to show up at this point, the _sync variant is +	 * desirable anyway. +	 */ +	if (host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_sync(&host->card->dev); +  out:  	if (err) {  		mmc_sdio_remove(host); @@ -568,9 +584,6 @@ out:  		mmc_detach_bus(host);  		mmc_release_host(host);  	} - -	/* Tell PM core that we're done */ -	pm_runtime_put(&host->card->dev);  }  /* @@ -718,16 +731,21 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)  	card = host->card;  	/* -	 * Let runtime PM core know our card is active +	 * Enable runtime PM only if supported by host+card+board  	 */ -	err = pm_runtime_set_active(&card->dev); -	if (err) -		goto remove; +	if (host->caps & MMC_CAP_POWER_OFF_CARD) { +		/* +		 * Let runtime PM core know our card is active +		 */ +		err = pm_runtime_set_active(&card->dev); +		if (err) +			goto remove; -	/* -	 * Enable runtime PM for this card -	 */ -	pm_runtime_enable(&card->dev); +		/* +		 * Enable runtime PM for this card +		 */ +		pm_runtime_enable(&card->dev); +	}  	/*  	 * The number of functions on the card is encoded inside @@ -745,9 +763,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)  			goto remove;  		/* -		 * Enable Runtime PM for this func +		 * Enable Runtime PM for this func (if supported)  		 */ -		pm_runtime_enable(&card->sdio_func[i]->dev); +		if (host->caps & MMC_CAP_POWER_OFF_CARD) +			pm_runtime_enable(&card->sdio_func[i]->dev);  	}  	mmc_release_host(host); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 2716c7ab6bbf..203da443e339 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -17,6 +17,7 @@  #include <linux/pm_runtime.h>  #include <linux/mmc/card.h> +#include <linux/mmc/host.h>  #include <linux/mmc/sdio_func.h>  #include "sdio_cis.h" @@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev)  	 * it should call pm_runtime_put_noidle() in its probe routine and  	 * pm_runtime_get_noresume() in its remove routine.  	 */ -	ret = pm_runtime_get_sync(dev); -	if (ret < 0) -		goto out; +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { +		ret = pm_runtime_get_sync(dev); +		if (ret < 0) +			goto out; +	}  	/* Set the default block size so the driver is sure it's something  	 * sensible. */ @@ -151,7 +154,8 @@ static int sdio_bus_probe(struct device *dev)  	return 0;  disable_runtimepm: -	pm_runtime_put_noidle(dev); +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_noidle(dev);  out:  	return ret;  } @@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev)  {  	struct sdio_driver *drv = to_sdio_driver(dev->driver);  	struct sdio_func *func = dev_to_sdio_func(dev); -	int ret; +	int ret = 0;  	/* Make sure card is powered before invoking ->remove() */ -	ret = pm_runtime_get_sync(dev); -	if (ret < 0) -		goto out; +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { +		ret = pm_runtime_get_sync(dev); +		if (ret < 0) +			goto out; +	}  	drv->remove(func); @@ -178,10 +184,12 @@ static int sdio_bus_remove(struct device *dev)  	}  	/* First, undo the increment made directly above */ -	pm_runtime_put_noidle(dev); +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_noidle(dev);  	/* Then undo the runtime PM settings in sdio_bus_probe() */ -	pm_runtime_put_noidle(dev); +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_put_noidle(dev);  out:  	return ret; @@ -191,6 +199,8 @@ out:  static int sdio_bus_pm_prepare(struct device *dev)  { +	struct sdio_func *func = dev_to_sdio_func(dev); +  	/*  	 * Resume an SDIO device which was suspended at run time at this  	 * point, in order to allow standard SDIO suspend/resume paths @@ -212,7 +222,8 @@ static int sdio_bus_pm_prepare(struct device *dev)  	 * since there is little point in failing system suspend if a  	 * device can't be resumed.  	 */ -	pm_runtime_resume(dev); +	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) +		pm_runtime_resume(dev);  	return 0;  } diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 82a1079bbdc7..5d46021cbb57 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,  	 * Monitor a 0->1 transition first  	 */  	if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { -		while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit)) +		while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))  					&& (i++ < limit))  			cpu_relax();  	} diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 2e9cca19c90b..9b82910b9dbb 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -17,6 +17,7 @@  #include <linux/clk.h>  #include <linux/mmc/host.h>  #include <linux/mmc/sdhci-pltfm.h> +#include <mach/hardware.h>  #include "sdhci.h"  #include "sdhci-pltfm.h"  #include "sdhci-esdhc.h" @@ -112,6 +113,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd  	clk_enable(clk);  	pltfm_host->clk = clk; +	if (cpu_is_mx35() || cpu_is_mx51()) +		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + +	/* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */ +	if (cpu_is_mx25() || cpu_is_mx35()) +		host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK; +  	return 0;  } @@ -133,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = {  };  struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { -	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK -			| SDHCI_QUIRK_BROKEN_ADMA, +	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,  	/* ADMA has issues. Might be fixable */ -	/* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */  	.ops = &sdhci_esdhc_ops,  	.init = esdhc_pltfm_init,  	.exit = esdhc_pltfm_exit, diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 55746bac2f44..3d9c2460d437 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = {   * ADMA operation is disabled for Moorestown platform due to   * hardware bugs.   */ -static int mrst_hc1_probe(struct sdhci_pci_chip *chip) +static int mrst_hc_probe(struct sdhci_pci_chip *chip)  {  	/* -	 * slots number is fixed here for MRST as SDIO3 is never used and has -	 * hardware bugs. +	 * slots number is fixed here for MRST as SDIO3/5 are never used and +	 * have hardware bugs.  	 */  	chip->num_slots = 1;  	return 0; @@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {  	.quirks		= SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,  }; -static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1 = { +static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {  	.quirks		= SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, -	.probe		= mrst_hc1_probe, +	.probe		= mrst_hc_probe,  };  static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { @@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = {  		.device		= PCI_DEVICE_ID_INTEL_MRST_SD1,  		.subvendor	= PCI_ANY_ID,  		.subdevice	= PCI_ANY_ID, -		.driver_data	= (kernel_ulong_t)&sdhci_intel_mrst_hc1, +		.driver_data	= (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2, +	}, + +	{ +		.vendor		= PCI_VENDOR_ID_INTEL, +		.device		= PCI_DEVICE_ID_INTEL_MRST_SD2, +		.subvendor	= PCI_ANY_ID, +		.subdevice	= PCI_ANY_ID, +		.driver_data	= (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,  	},  	{ @@ -637,6 +645,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)  {  	struct sdhci_pci_chip *chip;  	struct sdhci_pci_slot *slot; +	mmc_pm_flag_t slot_pm_flags;  	mmc_pm_flag_t pm_flags = 0;  	int i, ret; @@ -657,7 +666,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)  			return ret;  		} -		pm_flags |= slot->host->mmc->pm_flags; +		slot_pm_flags = slot->host->mmc->pm_flags; +		if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) +			sdhci_enable_irq_wakeups(slot->host); + +		pm_flags |= slot_pm_flags;  	}  	if (chip->fixes && chip->fixes->suspend) { @@ -671,8 +684,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)  	pci_save_state(pdev);  	if (pm_flags & MMC_PM_KEEP_POWER) { -		if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) +		if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) { +			pci_pme_active(pdev, true);  			pci_enable_wake(pdev, PCI_D3hot, 1); +		}  		pci_set_power_state(pdev, PCI_D3hot);  	} else {  		pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c index fc406ac5d193..5a61208cbc66 100644 --- a/drivers/mmc/host/sdhci-pxa.c +++ b/drivers/mmc/host/sdhci-pxa.c @@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)  	if (pdata->quirks)  		host->quirks |= pdata->quirks; +	/* If slot design supports 8 bit data, indicate this to MMC. */ +	if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT) +		host->mmc->caps |= MMC_CAP_8_BIT_DATA; +  	ret = sdhci_add_host(host);  	if (ret) {  		dev_err(&pdev->dev, "failed to add host\n"); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 782c0ee3c925..a25db426c910 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1185,17 +1185,31 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  	if (host->ops->platform_send_init_74_clocks)  		host->ops->platform_send_init_74_clocks(host, ios->power_mode); -	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - -	if (ios->bus_width == MMC_BUS_WIDTH_8) -		ctrl |= SDHCI_CTRL_8BITBUS; -	else -		ctrl &= ~SDHCI_CTRL_8BITBUS; +	/* +	 * If your platform has 8-bit width support but is not a v3 controller, +	 * or if it requires special setup code, you should implement that in +	 * platform_8bit_width(). +	 */ +	if (host->ops->platform_8bit_width) +		host->ops->platform_8bit_width(host, ios->bus_width); +	else { +		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); +		if (ios->bus_width == MMC_BUS_WIDTH_8) { +			ctrl &= ~SDHCI_CTRL_4BITBUS; +			if (host->version >= SDHCI_SPEC_300) +				ctrl |= SDHCI_CTRL_8BITBUS; +		} else { +			if (host->version >= SDHCI_SPEC_300) +				ctrl &= ~SDHCI_CTRL_8BITBUS; +			if (ios->bus_width == MMC_BUS_WIDTH_4) +				ctrl |= SDHCI_CTRL_4BITBUS; +			else +				ctrl &= ~SDHCI_CTRL_4BITBUS; +		} +		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); +	} -	if (ios->bus_width == MMC_BUS_WIDTH_4) -		ctrl |= SDHCI_CTRL_4BITBUS; -	else -		ctrl &= ~SDHCI_CTRL_4BITBUS; +	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);  	if ((ios->timing == MMC_TIMING_SD_HS ||  	     ios->timing == MMC_TIMING_MMC_HS) @@ -1681,6 +1695,16 @@ int sdhci_resume_host(struct sdhci_host *host)  EXPORT_SYMBOL_GPL(sdhci_resume_host); +void sdhci_enable_irq_wakeups(struct sdhci_host *host) +{ +	u8 val; +	val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); +	val |= SDHCI_WAKE_ON_INT; +	sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); +} + +EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); +  #endif /* CONFIG_PM */  /*****************************************************************************\ @@ -1845,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host)  		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;  	else  		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; +  	mmc->f_max = host->max_clk;  	mmc->caps |= MMC_CAP_SDIO_IRQ; +	/* +	 * A controller may support 8-bit width, but the board itself +	 * might not have the pins brought out.  Boards that support +	 * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in +	 * their platform code before calling sdhci_add_host(), and we +	 * won't assume 8-bit width for hosts without that CAP. +	 */  	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) -		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; +		mmc->caps |= MMC_CAP_4_BIT_DATA;  	if (caps & SDHCI_CAN_DO_HISPD)  		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index b7b8a3b28b01..e42d7f00c060 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -76,7 +76,7 @@  #define   SDHCI_CTRL_ADMA1	0x08  #define   SDHCI_CTRL_ADMA32	0x10  #define   SDHCI_CTRL_ADMA64	0x18 -#define  SDHCI_CTRL_8BITBUS	0x20 +#define   SDHCI_CTRL_8BITBUS	0x20  #define SDHCI_POWER_CONTROL	0x29  #define  SDHCI_POWER_ON		0x01 @@ -87,6 +87,9 @@  #define SDHCI_BLOCK_GAP_CONTROL	0x2A  #define SDHCI_WAKE_UP_CONTROL	0x2B +#define  SDHCI_WAKE_ON_INT	0x01 +#define  SDHCI_WAKE_ON_INSERT	0x02 +#define  SDHCI_WAKE_ON_REMOVE	0x04  #define SDHCI_CLOCK_CONTROL	0x2C  #define  SDHCI_DIVIDER_SHIFT	8 @@ -152,6 +155,7 @@  #define  SDHCI_CLOCK_BASE_SHIFT	8  #define  SDHCI_MAX_BLOCK_MASK	0x00030000  #define  SDHCI_MAX_BLOCK_SHIFT  16 +#define  SDHCI_CAN_DO_8BIT	0x00040000  #define  SDHCI_CAN_DO_ADMA2	0x00080000  #define  SDHCI_CAN_DO_ADMA1	0x00100000  #define  SDHCI_CAN_DO_HISPD	0x00200000 @@ -212,6 +216,8 @@ struct sdhci_ops {  	unsigned int	(*get_max_clock)(struct sdhci_host *host);  	unsigned int	(*get_min_clock)(struct sdhci_host *host);  	unsigned int	(*get_timeout_clock)(struct sdhci_host *host); +	int		(*platform_8bit_width)(struct sdhci_host *host, +					       int width);  	void (*platform_send_init_74_clocks)(struct sdhci_host *host,  					     u8 power_mode);  	unsigned int    (*get_ro)(struct sdhci_host *host); @@ -317,6 +323,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);  #ifdef CONFIG_PM  extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);  extern int sdhci_resume_host(struct sdhci_host *host); +extern void sdhci_enable_irq_wakeups(struct sdhci_host *host);  #endif  #endif /* __SDHCI_HW_H */ diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index b4ead4a13c98..f8f65df9b017 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c @@ -425,7 +425,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id  	struct usb_device *usb_dev = interface_to_usbdev(intf);  	struct mmc_host *mmc;  	struct ushc_data *ushc; -	int ret = -ENOMEM; +	int ret;  	mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);  	if (mmc == NULL) @@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id  	mmc->max_blk_count = 511;  	ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL); -	if (ushc->int_urb == NULL) +	if (ushc->int_urb == NULL) { +		ret = -ENOMEM;  		goto err; +	}  	ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); -	if (ushc->int_data == NULL) +	if (ushc->int_data == NULL) { +		ret = -ENOMEM;  		goto err; +	}  	usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,  			 usb_rcvintpipe(usb_dev,  					intf->cur_altsetting->endpoint[0].desc.bEndpointAddress), @@ -475,11 +479,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id  			 intf->cur_altsetting->endpoint[0].desc.bInterval);  	ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL); -	if (ushc->cbw_urb == NULL) +	if (ushc->cbw_urb == NULL) { +		ret = -ENOMEM;  		goto err; +	}  	ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); -	if (ushc->cbw == NULL) +	if (ushc->cbw == NULL) { +		ret = -ENOMEM;  		goto err; +	}  	ushc->cbw->signature = USHC_CBW_SIGNATURE;  	usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2), @@ -487,15 +495,21 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id  			  cbw_callback, ushc);  	ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL); -	if (ushc->data_urb == NULL) +	if (ushc->data_urb == NULL) { +		ret = -ENOMEM;  		goto err; +	}  	ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL); -	if (ushc->csw_urb == NULL) +	if (ushc->csw_urb == NULL) { +		ret = -ENOMEM;  		goto err; +	}  	ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); -	if (ushc->csw == NULL) +	if (ushc->csw == NULL) { +		ret = -ENOMEM;  		goto err; +	}  	usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),  			  ushc->csw, sizeof(struct ushc_csw),  			  csw_callback, ushc);  | 
