.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Remote VUB300 SDIO/SDmem Host Controller Driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * based on USB Skeleton driver - 2.2 |
---|
7 | 8 | * |
---|
8 | 9 | * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or |
---|
11 | | - * modify it under the terms of the GNU General Public License as |
---|
12 | | - * published by the Free Software Foundation, version 2 |
---|
13 | 10 | * |
---|
14 | 11 | * VUB300: is a USB 2.0 client device with a single SDIO/SDmem/MMC slot |
---|
15 | 12 | * Any SDIO/SDmem/MMC device plugged into the VUB300 will appear, |
---|
.. | .. |
---|
98 | 95 | u8 port_number; |
---|
99 | 96 | u8 command_type; |
---|
100 | 97 | u8 command_index; |
---|
101 | | - u8 command_response[0]; |
---|
| 98 | + u8 command_response[]; |
---|
102 | 99 | } __packed; |
---|
103 | 100 | |
---|
104 | 101 | struct sd_status_header { |
---|
.. | .. |
---|
1366 | 1363 | int retval; |
---|
1367 | 1364 | for (n = 0; n < sdio_funcs; n++) { |
---|
1368 | 1365 | struct sdio_func *sf = card->sdio_func[n]; |
---|
1369 | | - l += snprintf(vub300->vub_name + l, |
---|
| 1366 | + l += scnprintf(vub300->vub_name + l, |
---|
1370 | 1367 | sizeof(vub300->vub_name) - l, "_%04X%04X", |
---|
1371 | 1368 | sf->vendor, sf->device); |
---|
1372 | 1369 | } |
---|
.. | .. |
---|
1718 | 1715 | int bytes = 3 & less_cmd; |
---|
1719 | 1716 | int words = less_cmd >> 2; |
---|
1720 | 1717 | u8 *r = vub300->resp.response.command_response; |
---|
| 1718 | + |
---|
| 1719 | + if (!resp_len) |
---|
| 1720 | + return; |
---|
1721 | 1721 | if (bytes == 3) { |
---|
1722 | 1722 | cmd->resp[words] = (r[1 + (words << 2)] << 24) |
---|
1723 | 1723 | | (r[2 + (words << 2)] << 16) |
---|
.. | .. |
---|
2052 | 2052 | return; |
---|
2053 | 2053 | kref_get(&vub300->kref); |
---|
2054 | 2054 | if (enable) { |
---|
| 2055 | + set_current_state(TASK_RUNNING); |
---|
2055 | 2056 | mutex_lock(&vub300->irq_mutex); |
---|
2056 | 2057 | if (vub300->irqs_queued) { |
---|
2057 | 2058 | vub300->irqs_queued -= 1; |
---|
.. | .. |
---|
2067 | 2068 | vub300_queue_poll_work(vub300, 0); |
---|
2068 | 2069 | } |
---|
2069 | 2070 | mutex_unlock(&vub300->irq_mutex); |
---|
| 2071 | + set_current_state(TASK_INTERRUPTIBLE); |
---|
2070 | 2072 | } else { |
---|
2071 | 2073 | vub300->irq_enabled = 0; |
---|
2072 | 2074 | } |
---|
2073 | 2075 | kref_put(&vub300->kref, vub300_delete); |
---|
2074 | | -} |
---|
2075 | | - |
---|
2076 | | -static void vub300_init_card(struct mmc_host *mmc, struct mmc_card *card) |
---|
2077 | | -{ /* NOT irq */ |
---|
2078 | | - struct vub300_mmc_host *vub300 = mmc_priv(mmc); |
---|
2079 | | - dev_info(&vub300->udev->dev, "NO host QUIRKS for this card\n"); |
---|
2080 | 2076 | } |
---|
2081 | 2077 | |
---|
2082 | 2078 | static const struct mmc_host_ops vub300_mmc_ops = { |
---|
.. | .. |
---|
2084 | 2080 | .set_ios = vub300_mmc_set_ios, |
---|
2085 | 2081 | .get_ro = vub300_mmc_get_ro, |
---|
2086 | 2082 | .enable_sdio_irq = vub300_enable_sdio_irq, |
---|
2087 | | - .init_card = vub300_init_card, |
---|
2088 | 2083 | }; |
---|
2089 | 2084 | |
---|
2090 | 2085 | static int vub300_probe(struct usb_interface *interface, |
---|
.. | .. |
---|
2309 | 2304 | 0x0000, 0x0000, &vub300->system_port_status, |
---|
2310 | 2305 | sizeof(vub300->system_port_status), 1000); |
---|
2311 | 2306 | if (retval < 0) { |
---|
2312 | | - goto error4; |
---|
| 2307 | + goto error5; |
---|
2313 | 2308 | } else if (sizeof(vub300->system_port_status) == retval) { |
---|
2314 | 2309 | vub300->card_present = |
---|
2315 | 2310 | (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0; |
---|
2316 | 2311 | vub300->read_only = |
---|
2317 | 2312 | (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0; |
---|
2318 | 2313 | } else { |
---|
2319 | | - goto error4; |
---|
| 2314 | + goto error5; |
---|
2320 | 2315 | } |
---|
2321 | 2316 | usb_set_intfdata(interface, vub300); |
---|
2322 | 2317 | INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread); |
---|
.. | .. |
---|
2339 | 2334 | "USB vub300 remote SDIO host controller[%d]" |
---|
2340 | 2335 | "connected with no SD/SDIO card inserted\n", |
---|
2341 | 2336 | interface_to_InterfaceNumber(interface)); |
---|
2342 | | - mmc_add_host(mmc); |
---|
| 2337 | + retval = mmc_add_host(mmc); |
---|
| 2338 | + if (retval) |
---|
| 2339 | + goto error6; |
---|
| 2340 | + |
---|
2343 | 2341 | return 0; |
---|
| 2342 | +error6: |
---|
| 2343 | + del_timer_sync(&vub300->inactivity_timer); |
---|
2344 | 2344 | error5: |
---|
2345 | 2345 | mmc_free_host(mmc); |
---|
2346 | 2346 | /* |
---|