1a10e763bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 288095e7bSTony Olech /* 388095e7bSTony Olech * Remote VUB300 SDIO/SDmem Host Controller Driver 488095e7bSTony Olech * 588095e7bSTony Olech * Copyright (C) 2010 Elan Digital Systems Limited 688095e7bSTony Olech * 788095e7bSTony Olech * based on USB Skeleton driver - 2.2 888095e7bSTony Olech * 988095e7bSTony Olech * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 1088095e7bSTony Olech * 1188095e7bSTony Olech * VUB300: is a USB 2.0 client device with a single SDIO/SDmem/MMC slot 1288095e7bSTony Olech * Any SDIO/SDmem/MMC device plugged into the VUB300 will appear, 1388095e7bSTony Olech * by virtue of this driver, to have been plugged into a local 1488095e7bSTony Olech * SDIO host controller, similar to, say, a PCI Ricoh controller 1588095e7bSTony Olech * This is because this kernel device driver is both a USB 2.0 1688095e7bSTony Olech * client device driver AND an MMC host controller driver. Thus 1788095e7bSTony Olech * if there is an existing driver for the inserted SDIO/SDmem/MMC 1888095e7bSTony Olech * device then that driver will be used by the kernel to manage 1988095e7bSTony Olech * the device in exactly the same fashion as if it had been 2088095e7bSTony Olech * directly plugged into, say, a local pci bus Ricoh controller 2188095e7bSTony Olech * 2288095e7bSTony Olech * RANT: this driver was written using a display 128x48 - converting it 2388095e7bSTony Olech * to a line width of 80 makes it very difficult to support. In 2488095e7bSTony Olech * particular functions have been broken down into sub functions 2588095e7bSTony Olech * and the original meaningful names have been shortened into 2688095e7bSTony Olech * cryptic ones. 2788095e7bSTony Olech * The problem is that executing a fragment of code subject to 2888095e7bSTony Olech * two conditions means an indentation of 24, thus leaving only 2988095e7bSTony Olech * 56 characters for a C statement. And that is quite ridiculous! 3088095e7bSTony Olech * 3188095e7bSTony Olech * Data types: data passed to/from the VUB300 is fixed to a number of 3288095e7bSTony Olech * bits and driver data fields reflect that limit by using 3388095e7bSTony Olech * u8, u16, u32 3488095e7bSTony Olech */ 3588095e7bSTony Olech #include <linux/kernel.h> 3688095e7bSTony Olech #include <linux/errno.h> 3788095e7bSTony Olech #include <linux/init.h> 3888095e7bSTony Olech #include <linux/slab.h> 3988095e7bSTony Olech #include <linux/module.h> 4088095e7bSTony Olech #include <linux/kref.h> 4188095e7bSTony Olech #include <linux/uaccess.h> 4288095e7bSTony Olech #include <linux/usb.h> 4388095e7bSTony Olech #include <linux/mutex.h> 4488095e7bSTony Olech #include <linux/mmc/host.h> 4588095e7bSTony Olech #include <linux/mmc/card.h> 4688095e7bSTony Olech #include <linux/mmc/sdio_func.h> 4788095e7bSTony Olech #include <linux/mmc/sdio_ids.h> 4888095e7bSTony Olech #include <linux/workqueue.h> 4988095e7bSTony Olech #include <linux/ctype.h> 5088095e7bSTony Olech #include <linux/firmware.h> 5188095e7bSTony Olech #include <linux/scatterlist.h> 5288095e7bSTony Olech 5388095e7bSTony Olech struct host_controller_info { 5488095e7bSTony Olech u8 info_size; 5588095e7bSTony Olech u16 firmware_version; 5688095e7bSTony Olech u8 number_of_ports; 5788095e7bSTony Olech } __packed; 5888095e7bSTony Olech 5988095e7bSTony Olech #define FIRMWARE_BLOCK_BOUNDARY 1024 6088095e7bSTony Olech struct sd_command_header { 6188095e7bSTony Olech u8 header_size; 6288095e7bSTony Olech u8 header_type; 6388095e7bSTony Olech u8 port_number; 6488095e7bSTony Olech u8 command_type; /* Bit7 - Rd/Wr */ 6588095e7bSTony Olech u8 command_index; 6688095e7bSTony Olech u8 transfer_size[4]; /* ReadSize + ReadSize */ 6788095e7bSTony Olech u8 response_type; 6888095e7bSTony Olech u8 arguments[4]; 6988095e7bSTony Olech u8 block_count[2]; 7088095e7bSTony Olech u8 block_size[2]; 7188095e7bSTony Olech u8 block_boundary[2]; 7288095e7bSTony Olech u8 reserved[44]; /* to pad out to 64 bytes */ 7388095e7bSTony Olech } __packed; 7488095e7bSTony Olech 7588095e7bSTony Olech struct sd_irqpoll_header { 7688095e7bSTony Olech u8 header_size; 7788095e7bSTony Olech u8 header_type; 7888095e7bSTony Olech u8 port_number; 7988095e7bSTony Olech u8 command_type; /* Bit7 - Rd/Wr */ 8088095e7bSTony Olech u8 padding[16]; /* don't ask why !! */ 8188095e7bSTony Olech u8 poll_timeout_msb; 8288095e7bSTony Olech u8 poll_timeout_lsb; 8388095e7bSTony Olech u8 reserved[42]; /* to pad out to 64 bytes */ 8488095e7bSTony Olech } __packed; 8588095e7bSTony Olech 8688095e7bSTony Olech struct sd_common_header { 8788095e7bSTony Olech u8 header_size; 8888095e7bSTony Olech u8 header_type; 8988095e7bSTony Olech u8 port_number; 9088095e7bSTony Olech } __packed; 9188095e7bSTony Olech 9288095e7bSTony Olech struct sd_response_header { 9388095e7bSTony Olech u8 header_size; 9488095e7bSTony Olech u8 header_type; 9588095e7bSTony Olech u8 port_number; 9688095e7bSTony Olech u8 command_type; 9788095e7bSTony Olech u8 command_index; 981a91a36aSGustavo A. R. Silva u8 command_response[]; 9988095e7bSTony Olech } __packed; 10088095e7bSTony Olech 10188095e7bSTony Olech struct sd_status_header { 10288095e7bSTony Olech u8 header_size; 10388095e7bSTony Olech u8 header_type; 10488095e7bSTony Olech u8 port_number; 10588095e7bSTony Olech u16 port_flags; 10688095e7bSTony Olech u32 sdio_clock; 10788095e7bSTony Olech u16 host_header_size; 10888095e7bSTony Olech u16 func_header_size; 10988095e7bSTony Olech u16 ctrl_header_size; 11088095e7bSTony Olech } __packed; 11188095e7bSTony Olech 11288095e7bSTony Olech struct sd_error_header { 11388095e7bSTony Olech u8 header_size; 11488095e7bSTony Olech u8 header_type; 11588095e7bSTony Olech u8 port_number; 11688095e7bSTony Olech u8 error_code; 11788095e7bSTony Olech } __packed; 11888095e7bSTony Olech 11988095e7bSTony Olech struct sd_interrupt_header { 12088095e7bSTony Olech u8 header_size; 12188095e7bSTony Olech u8 header_type; 12288095e7bSTony Olech u8 port_number; 12388095e7bSTony Olech } __packed; 12488095e7bSTony Olech 12588095e7bSTony Olech struct offload_registers_access { 12688095e7bSTony Olech u8 command_byte[4]; 12788095e7bSTony Olech u8 Respond_Byte[4]; 12888095e7bSTony Olech } __packed; 12988095e7bSTony Olech 13088095e7bSTony Olech #define INTERRUPT_REGISTER_ACCESSES 15 13188095e7bSTony Olech struct sd_offloaded_interrupt { 13288095e7bSTony Olech u8 header_size; 13388095e7bSTony Olech u8 header_type; 13488095e7bSTony Olech u8 port_number; 13588095e7bSTony Olech struct offload_registers_access reg[INTERRUPT_REGISTER_ACCESSES]; 13688095e7bSTony Olech } __packed; 13788095e7bSTony Olech 13888095e7bSTony Olech struct sd_register_header { 13988095e7bSTony Olech u8 header_size; 14088095e7bSTony Olech u8 header_type; 14188095e7bSTony Olech u8 port_number; 14288095e7bSTony Olech u8 command_type; 14388095e7bSTony Olech u8 command_index; 14488095e7bSTony Olech u8 command_response[6]; 14588095e7bSTony Olech } __packed; 14688095e7bSTony Olech 14788095e7bSTony Olech #define PIGGYBACK_REGISTER_ACCESSES 14 14888095e7bSTony Olech struct sd_offloaded_piggyback { 14988095e7bSTony Olech struct sd_register_header sdio; 15088095e7bSTony Olech struct offload_registers_access reg[PIGGYBACK_REGISTER_ACCESSES]; 15188095e7bSTony Olech } __packed; 15288095e7bSTony Olech 15388095e7bSTony Olech union sd_response { 15488095e7bSTony Olech struct sd_common_header common; 15588095e7bSTony Olech struct sd_status_header status; 15688095e7bSTony Olech struct sd_error_header error; 15788095e7bSTony Olech struct sd_interrupt_header interrupt; 15888095e7bSTony Olech struct sd_response_header response; 15988095e7bSTony Olech struct sd_offloaded_interrupt irq; 16088095e7bSTony Olech struct sd_offloaded_piggyback pig; 16188095e7bSTony Olech } __packed; 16288095e7bSTony Olech 16388095e7bSTony Olech union sd_command { 16488095e7bSTony Olech struct sd_command_header head; 16588095e7bSTony Olech struct sd_irqpoll_header poll; 16688095e7bSTony Olech } __packed; 16788095e7bSTony Olech 16888095e7bSTony Olech enum SD_RESPONSE_TYPE { 16988095e7bSTony Olech SDRT_UNSPECIFIED = 0, 17088095e7bSTony Olech SDRT_NONE, 17188095e7bSTony Olech SDRT_1, 17288095e7bSTony Olech SDRT_1B, 17388095e7bSTony Olech SDRT_2, 17488095e7bSTony Olech SDRT_3, 17588095e7bSTony Olech SDRT_4, 17688095e7bSTony Olech SDRT_5, 17788095e7bSTony Olech SDRT_5B, 17888095e7bSTony Olech SDRT_6, 17988095e7bSTony Olech SDRT_7, 18088095e7bSTony Olech }; 18188095e7bSTony Olech 18288095e7bSTony Olech #define RESPONSE_INTERRUPT 0x01 18388095e7bSTony Olech #define RESPONSE_ERROR 0x02 18488095e7bSTony Olech #define RESPONSE_STATUS 0x03 18588095e7bSTony Olech #define RESPONSE_IRQ_DISABLED 0x05 18688095e7bSTony Olech #define RESPONSE_IRQ_ENABLED 0x06 18788095e7bSTony Olech #define RESPONSE_PIGGYBACKED 0x07 18888095e7bSTony Olech #define RESPONSE_NO_INTERRUPT 0x08 18988095e7bSTony Olech #define RESPONSE_PIG_DISABLED 0x09 19088095e7bSTony Olech #define RESPONSE_PIG_ENABLED 0x0A 19188095e7bSTony Olech #define SD_ERROR_1BIT_TIMEOUT 0x01 19288095e7bSTony Olech #define SD_ERROR_4BIT_TIMEOUT 0x02 19388095e7bSTony Olech #define SD_ERROR_1BIT_CRC_WRONG 0x03 19488095e7bSTony Olech #define SD_ERROR_4BIT_CRC_WRONG 0x04 19588095e7bSTony Olech #define SD_ERROR_1BIT_CRC_ERROR 0x05 19688095e7bSTony Olech #define SD_ERROR_4BIT_CRC_ERROR 0x06 19788095e7bSTony Olech #define SD_ERROR_NO_CMD_ENDBIT 0x07 19888095e7bSTony Olech #define SD_ERROR_NO_1BIT_DATEND 0x08 19988095e7bSTony Olech #define SD_ERROR_NO_4BIT_DATEND 0x09 20088095e7bSTony Olech #define SD_ERROR_1BIT_UNEXPECTED_TIMEOUT 0x0A 20188095e7bSTony Olech #define SD_ERROR_4BIT_UNEXPECTED_TIMEOUT 0x0B 20288095e7bSTony Olech #define SD_ERROR_ILLEGAL_COMMAND 0x0C 20388095e7bSTony Olech #define SD_ERROR_NO_DEVICE 0x0D 20488095e7bSTony Olech #define SD_ERROR_TRANSFER_LENGTH 0x0E 20588095e7bSTony Olech #define SD_ERROR_1BIT_DATA_TIMEOUT 0x0F 20688095e7bSTony Olech #define SD_ERROR_4BIT_DATA_TIMEOUT 0x10 20788095e7bSTony Olech #define SD_ERROR_ILLEGAL_STATE 0x11 20888095e7bSTony Olech #define SD_ERROR_UNKNOWN_ERROR 0x12 20988095e7bSTony Olech #define SD_ERROR_RESERVED_ERROR 0x13 21088095e7bSTony Olech #define SD_ERROR_INVALID_FUNCTION 0x14 21188095e7bSTony Olech #define SD_ERROR_OUT_OF_RANGE 0x15 21288095e7bSTony Olech #define SD_ERROR_STAT_CMD 0x16 21388095e7bSTony Olech #define SD_ERROR_STAT_DATA 0x17 21488095e7bSTony Olech #define SD_ERROR_STAT_CMD_TIMEOUT 0x18 21588095e7bSTony Olech #define SD_ERROR_SDCRDY_STUCK 0x19 21688095e7bSTony Olech #define SD_ERROR_UNHANDLED 0x1A 21788095e7bSTony Olech #define SD_ERROR_OVERRUN 0x1B 21888095e7bSTony Olech #define SD_ERROR_PIO_TIMEOUT 0x1C 21988095e7bSTony Olech 22088095e7bSTony Olech #define FUN(c) (0x000007 & (c->arg>>28)) 22188095e7bSTony Olech #define REG(c) (0x01FFFF & (c->arg>>9)) 22288095e7bSTony Olech 22390ab5ee9SRusty Russell static bool limit_speed_to_24_MHz; 22488095e7bSTony Olech module_param(limit_speed_to_24_MHz, bool, 0644); 22588095e7bSTony Olech MODULE_PARM_DESC(limit_speed_to_24_MHz, "Limit Max SDIO Clock Speed to 24 MHz"); 22688095e7bSTony Olech 22790ab5ee9SRusty Russell static bool pad_input_to_usb_pkt; 22888095e7bSTony Olech module_param(pad_input_to_usb_pkt, bool, 0644); 22988095e7bSTony Olech MODULE_PARM_DESC(pad_input_to_usb_pkt, 23088095e7bSTony Olech "Pad USB data input transfers to whole USB Packet"); 23188095e7bSTony Olech 23290ab5ee9SRusty Russell static bool disable_offload_processing; 23388095e7bSTony Olech module_param(disable_offload_processing, bool, 0644); 23488095e7bSTony Olech MODULE_PARM_DESC(disable_offload_processing, "Disable Offload Processing"); 23588095e7bSTony Olech 23690ab5ee9SRusty Russell static bool force_1_bit_data_xfers; 23788095e7bSTony Olech module_param(force_1_bit_data_xfers, bool, 0644); 23888095e7bSTony Olech MODULE_PARM_DESC(force_1_bit_data_xfers, 23988095e7bSTony Olech "Force SDIO Data Transfers to 1-bit Mode"); 24088095e7bSTony Olech 24190ab5ee9SRusty Russell static bool force_polling_for_irqs; 24288095e7bSTony Olech module_param(force_polling_for_irqs, bool, 0644); 24388095e7bSTony Olech MODULE_PARM_DESC(force_polling_for_irqs, "Force Polling for SDIO interrupts"); 24488095e7bSTony Olech 24588095e7bSTony Olech static int firmware_irqpoll_timeout = 1024; 24688095e7bSTony Olech module_param(firmware_irqpoll_timeout, int, 0644); 24788095e7bSTony Olech MODULE_PARM_DESC(firmware_irqpoll_timeout, "VUB300 firmware irqpoll timeout"); 24888095e7bSTony Olech 24988095e7bSTony Olech static int force_max_req_size = 128; 25088095e7bSTony Olech module_param(force_max_req_size, int, 0644); 25188095e7bSTony Olech MODULE_PARM_DESC(force_max_req_size, "set max request size in kBytes"); 25288095e7bSTony Olech 25388095e7bSTony Olech #ifdef SMSC_DEVELOPMENT_BOARD 25488095e7bSTony Olech static int firmware_rom_wait_states = 0x04; 25588095e7bSTony Olech #else 25688095e7bSTony Olech static int firmware_rom_wait_states = 0x1C; 25788095e7bSTony Olech #endif 25888095e7bSTony Olech 25961074287SRusty Russell module_param(firmware_rom_wait_states, int, 0644); 26088095e7bSTony Olech MODULE_PARM_DESC(firmware_rom_wait_states, 26188095e7bSTony Olech "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); 26288095e7bSTony Olech 26388095e7bSTony Olech #define ELAN_VENDOR_ID 0x2201 26488095e7bSTony Olech #define VUB300_VENDOR_ID 0x0424 26588095e7bSTony Olech #define VUB300_PRODUCT_ID 0x012C 266dde6256bSArvind Yadav static const struct usb_device_id vub300_table[] = { 26788095e7bSTony Olech {USB_DEVICE(ELAN_VENDOR_ID, VUB300_PRODUCT_ID)}, 26888095e7bSTony Olech {USB_DEVICE(VUB300_VENDOR_ID, VUB300_PRODUCT_ID)}, 26988095e7bSTony Olech {} /* Terminating entry */ 27088095e7bSTony Olech }; 27188095e7bSTony Olech MODULE_DEVICE_TABLE(usb, vub300_table); 27288095e7bSTony Olech 27388095e7bSTony Olech static struct workqueue_struct *cmndworkqueue; 27488095e7bSTony Olech static struct workqueue_struct *pollworkqueue; 27588095e7bSTony Olech static struct workqueue_struct *deadworkqueue; 27688095e7bSTony Olech 27788095e7bSTony Olech static inline int interface_to_InterfaceNumber(struct usb_interface *interface) 27888095e7bSTony Olech { 27988095e7bSTony Olech if (!interface) 28088095e7bSTony Olech return -1; 28188095e7bSTony Olech if (!interface->cur_altsetting) 28288095e7bSTony Olech return -1; 28388095e7bSTony Olech return interface->cur_altsetting->desc.bInterfaceNumber; 28488095e7bSTony Olech } 28588095e7bSTony Olech 28688095e7bSTony Olech struct sdio_register { 28788095e7bSTony Olech unsigned func_num:3; 28888095e7bSTony Olech unsigned sdio_reg:17; 28988095e7bSTony Olech unsigned activate:1; 29088095e7bSTony Olech unsigned prepared:1; 29188095e7bSTony Olech unsigned regvalue:8; 29288095e7bSTony Olech unsigned response:8; 29388095e7bSTony Olech unsigned sparebit:26; 29488095e7bSTony Olech }; 29588095e7bSTony Olech 29688095e7bSTony Olech struct vub300_mmc_host { 29788095e7bSTony Olech struct usb_device *udev; 29888095e7bSTony Olech struct usb_interface *interface; 29988095e7bSTony Olech struct kref kref; 30088095e7bSTony Olech struct mutex cmd_mutex; 30188095e7bSTony Olech struct mutex irq_mutex; 30288095e7bSTony Olech char vub_name[3 + (9 * 8) + 4 + 1]; /* max of 7 sdio fn's */ 30388095e7bSTony Olech u8 cmnd_out_ep; /* EndPoint for commands */ 30488095e7bSTony Olech u8 cmnd_res_ep; /* EndPoint for responses */ 30588095e7bSTony Olech u8 data_out_ep; /* EndPoint for out data */ 30688095e7bSTony Olech u8 data_inp_ep; /* EndPoint for inp data */ 30788095e7bSTony Olech bool card_powered; 30888095e7bSTony Olech bool card_present; 30988095e7bSTony Olech bool read_only; 31088095e7bSTony Olech bool large_usb_packets; 31188095e7bSTony Olech bool app_spec; /* ApplicationSpecific */ 31288095e7bSTony Olech bool irq_enabled; /* by the MMC CORE */ 31388095e7bSTony Olech bool irq_disabled; /* in the firmware */ 31488095e7bSTony Olech unsigned bus_width:4; 31588095e7bSTony Olech u8 total_offload_count; 31688095e7bSTony Olech u8 dynamic_register_count; 31788095e7bSTony Olech u8 resp_len; 31888095e7bSTony Olech u32 datasize; 31988095e7bSTony Olech int errors; 32088095e7bSTony Olech int usb_transport_fail; 32188095e7bSTony Olech int usb_timed_out; 32288095e7bSTony Olech int irqs_queued; 32388095e7bSTony Olech struct sdio_register sdio_register[16]; 32488095e7bSTony Olech struct offload_interrupt_function_register { 32588095e7bSTony Olech #define MAXREGBITS 4 32688095e7bSTony Olech #define MAXREGS (1<<MAXREGBITS) 32788095e7bSTony Olech #define MAXREGMASK (MAXREGS-1) 32888095e7bSTony Olech u8 offload_count; 32988095e7bSTony Olech u32 offload_point; 33088095e7bSTony Olech struct offload_registers_access reg[MAXREGS]; 33188095e7bSTony Olech } fn[8]; 33288095e7bSTony Olech u16 fbs[8]; /* Function Block Size */ 33388095e7bSTony Olech struct mmc_command *cmd; 33488095e7bSTony Olech struct mmc_request *req; 33588095e7bSTony Olech struct mmc_data *data; 33688095e7bSTony Olech struct mmc_host *mmc; 33788095e7bSTony Olech struct urb *urb; 33888095e7bSTony Olech struct urb *command_out_urb; 33988095e7bSTony Olech struct urb *command_res_urb; 34088095e7bSTony Olech struct completion command_complete; 34188095e7bSTony Olech struct completion irqpoll_complete; 34288095e7bSTony Olech union sd_command cmnd; 34388095e7bSTony Olech union sd_response resp; 34488095e7bSTony Olech struct timer_list sg_transfer_timer; 34588095e7bSTony Olech struct usb_sg_request sg_request; 34688095e7bSTony Olech struct timer_list inactivity_timer; 34788095e7bSTony Olech struct work_struct deadwork; 34888095e7bSTony Olech struct work_struct cmndwork; 34988095e7bSTony Olech struct delayed_work pollwork; 35088095e7bSTony Olech struct host_controller_info hc_info; 35188095e7bSTony Olech struct sd_status_header system_port_status; 35288095e7bSTony Olech u8 padded_buffer[64]; 35388095e7bSTony Olech }; 35488095e7bSTony Olech 35588095e7bSTony Olech #define kref_to_vub300_mmc_host(d) container_of(d, struct vub300_mmc_host, kref) 35688095e7bSTony Olech #define SET_TRANSFER_PSEUDOCODE 21 35788095e7bSTony Olech #define SET_INTERRUPT_PSEUDOCODE 20 35888095e7bSTony Olech #define SET_FAILURE_MODE 18 35988095e7bSTony Olech #define SET_ROM_WAIT_STATES 16 36088095e7bSTony Olech #define SET_IRQ_ENABLE 13 36188095e7bSTony Olech #define SET_CLOCK_SPEED 11 36288095e7bSTony Olech #define SET_FUNCTION_BLOCK_SIZE 9 36388095e7bSTony Olech #define SET_SD_DATA_MODE 6 36488095e7bSTony Olech #define SET_SD_POWER 4 36588095e7bSTony Olech #define ENTER_DFU_MODE 3 36688095e7bSTony Olech #define GET_HC_INF0 1 36788095e7bSTony Olech #define GET_SYSTEM_PORT_STATUS 0 36888095e7bSTony Olech 36988095e7bSTony Olech static void vub300_delete(struct kref *kref) 37088095e7bSTony Olech { /* kref callback - softirq */ 37188095e7bSTony Olech struct vub300_mmc_host *vub300 = kref_to_vub300_mmc_host(kref); 37288095e7bSTony Olech struct mmc_host *mmc = vub300->mmc; 37388095e7bSTony Olech usb_free_urb(vub300->command_out_urb); 37488095e7bSTony Olech vub300->command_out_urb = NULL; 37588095e7bSTony Olech usb_free_urb(vub300->command_res_urb); 37688095e7bSTony Olech vub300->command_res_urb = NULL; 37788095e7bSTony Olech usb_put_dev(vub300->udev); 37888095e7bSTony Olech mmc_free_host(mmc); 37988095e7bSTony Olech /* 38088095e7bSTony Olech * and hence also frees vub300 38188095e7bSTony Olech * which is contained at the end of struct mmc 38288095e7bSTony Olech */ 38388095e7bSTony Olech } 38488095e7bSTony Olech 38588095e7bSTony Olech static void vub300_queue_cmnd_work(struct vub300_mmc_host *vub300) 38688095e7bSTony Olech { 38788095e7bSTony Olech kref_get(&vub300->kref); 38888095e7bSTony Olech if (queue_work(cmndworkqueue, &vub300->cmndwork)) { 38988095e7bSTony Olech /* 39088095e7bSTony Olech * then the cmndworkqueue was not previously 39188095e7bSTony Olech * running and the above get ref is obvious 39288095e7bSTony Olech * required and will be put when the thread 39388095e7bSTony Olech * terminates by a specific call 39488095e7bSTony Olech */ 39588095e7bSTony Olech } else { 39688095e7bSTony Olech /* 39788095e7bSTony Olech * the cmndworkqueue was already running from 39888095e7bSTony Olech * a previous invocation and thus to keep the 39988095e7bSTony Olech * kref counts correct we must undo the get 40088095e7bSTony Olech */ 40188095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 40288095e7bSTony Olech } 40388095e7bSTony Olech } 40488095e7bSTony Olech 40588095e7bSTony Olech static void vub300_queue_poll_work(struct vub300_mmc_host *vub300, int delay) 40688095e7bSTony Olech { 40788095e7bSTony Olech kref_get(&vub300->kref); 40888095e7bSTony Olech if (queue_delayed_work(pollworkqueue, &vub300->pollwork, delay)) { 40988095e7bSTony Olech /* 41088095e7bSTony Olech * then the pollworkqueue was not previously 41188095e7bSTony Olech * running and the above get ref is obvious 41288095e7bSTony Olech * required and will be put when the thread 41388095e7bSTony Olech * terminates by a specific call 41488095e7bSTony Olech */ 41588095e7bSTony Olech } else { 41688095e7bSTony Olech /* 41788095e7bSTony Olech * the pollworkqueue was already running from 41888095e7bSTony Olech * a previous invocation and thus to keep the 41988095e7bSTony Olech * kref counts correct we must undo the get 42088095e7bSTony Olech */ 42188095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 42288095e7bSTony Olech } 42388095e7bSTony Olech } 42488095e7bSTony Olech 42588095e7bSTony Olech static void vub300_queue_dead_work(struct vub300_mmc_host *vub300) 42688095e7bSTony Olech { 42788095e7bSTony Olech kref_get(&vub300->kref); 42888095e7bSTony Olech if (queue_work(deadworkqueue, &vub300->deadwork)) { 42988095e7bSTony Olech /* 43088095e7bSTony Olech * then the deadworkqueue was not previously 43188095e7bSTony Olech * running and the above get ref is obvious 43288095e7bSTony Olech * required and will be put when the thread 43388095e7bSTony Olech * terminates by a specific call 43488095e7bSTony Olech */ 43588095e7bSTony Olech } else { 43688095e7bSTony Olech /* 43788095e7bSTony Olech * the deadworkqueue was already running from 43888095e7bSTony Olech * a previous invocation and thus to keep the 43988095e7bSTony Olech * kref counts correct we must undo the get 44088095e7bSTony Olech */ 44188095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 44288095e7bSTony Olech } 44388095e7bSTony Olech } 44488095e7bSTony Olech 44588095e7bSTony Olech static void irqpoll_res_completed(struct urb *urb) 44688095e7bSTony Olech { /* urb completion handler - hardirq */ 44788095e7bSTony Olech struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; 44888095e7bSTony Olech if (urb->status) 44988095e7bSTony Olech vub300->usb_transport_fail = urb->status; 45088095e7bSTony Olech complete(&vub300->irqpoll_complete); 45188095e7bSTony Olech } 45288095e7bSTony Olech 45388095e7bSTony Olech static void irqpoll_out_completed(struct urb *urb) 45488095e7bSTony Olech { /* urb completion handler - hardirq */ 45588095e7bSTony Olech struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; 45688095e7bSTony Olech if (urb->status) { 45788095e7bSTony Olech vub300->usb_transport_fail = urb->status; 45888095e7bSTony Olech complete(&vub300->irqpoll_complete); 45988095e7bSTony Olech return; 46088095e7bSTony Olech } else { 46188095e7bSTony Olech int ret; 46288095e7bSTony Olech unsigned int pipe = 46388095e7bSTony Olech usb_rcvbulkpipe(vub300->udev, vub300->cmnd_res_ep); 46488095e7bSTony Olech usb_fill_bulk_urb(vub300->command_res_urb, vub300->udev, pipe, 46588095e7bSTony Olech &vub300->resp, sizeof(vub300->resp), 46688095e7bSTony Olech irqpoll_res_completed, vub300); 46788095e7bSTony Olech vub300->command_res_urb->actual_length = 0; 46888095e7bSTony Olech ret = usb_submit_urb(vub300->command_res_urb, GFP_ATOMIC); 46988095e7bSTony Olech if (ret) { 47088095e7bSTony Olech vub300->usb_transport_fail = ret; 47188095e7bSTony Olech complete(&vub300->irqpoll_complete); 47288095e7bSTony Olech } 47388095e7bSTony Olech return; 47488095e7bSTony Olech } 47588095e7bSTony Olech } 47688095e7bSTony Olech 47788095e7bSTony Olech static void send_irqpoll(struct vub300_mmc_host *vub300) 47888095e7bSTony Olech { 47988095e7bSTony Olech /* cmd_mutex is held by vub300_pollwork_thread */ 48088095e7bSTony Olech int retval; 48188095e7bSTony Olech int timeout = 0xFFFF & (0x0001FFFF - firmware_irqpoll_timeout); 48288095e7bSTony Olech vub300->cmnd.poll.header_size = 22; 48388095e7bSTony Olech vub300->cmnd.poll.header_type = 1; 48488095e7bSTony Olech vub300->cmnd.poll.port_number = 0; 48588095e7bSTony Olech vub300->cmnd.poll.command_type = 2; 48688095e7bSTony Olech vub300->cmnd.poll.poll_timeout_lsb = 0xFF & (unsigned)timeout; 48788095e7bSTony Olech vub300->cmnd.poll.poll_timeout_msb = 0xFF & (unsigned)(timeout >> 8); 48888095e7bSTony Olech usb_fill_bulk_urb(vub300->command_out_urb, vub300->udev, 48988095e7bSTony Olech usb_sndbulkpipe(vub300->udev, vub300->cmnd_out_ep) 49088095e7bSTony Olech , &vub300->cmnd, sizeof(vub300->cmnd) 49188095e7bSTony Olech , irqpoll_out_completed, vub300); 49288095e7bSTony Olech retval = usb_submit_urb(vub300->command_out_urb, GFP_KERNEL); 49388095e7bSTony Olech if (0 > retval) { 49488095e7bSTony Olech vub300->usb_transport_fail = retval; 49588095e7bSTony Olech vub300_queue_poll_work(vub300, 1); 49688095e7bSTony Olech complete(&vub300->irqpoll_complete); 49788095e7bSTony Olech return; 49888095e7bSTony Olech } else { 49988095e7bSTony Olech return; 50088095e7bSTony Olech } 50188095e7bSTony Olech } 50288095e7bSTony Olech 50388095e7bSTony Olech static void new_system_port_status(struct vub300_mmc_host *vub300) 50488095e7bSTony Olech { 50588095e7bSTony Olech int old_card_present = vub300->card_present; 50688095e7bSTony Olech int new_card_present = 50788095e7bSTony Olech (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0; 50888095e7bSTony Olech vub300->read_only = 50988095e7bSTony Olech (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0; 51088095e7bSTony Olech if (new_card_present && !old_card_present) { 51188095e7bSTony Olech dev_info(&vub300->udev->dev, "card just inserted\n"); 51288095e7bSTony Olech vub300->card_present = 1; 51388095e7bSTony Olech vub300->bus_width = 0; 51488095e7bSTony Olech if (disable_offload_processing) 51588095e7bSTony Olech strncpy(vub300->vub_name, "EMPTY Processing Disabled", 51688095e7bSTony Olech sizeof(vub300->vub_name)); 51788095e7bSTony Olech else 51888095e7bSTony Olech vub300->vub_name[0] = 0; 51988095e7bSTony Olech mmc_detect_change(vub300->mmc, 1); 52088095e7bSTony Olech } else if (!new_card_present && old_card_present) { 52188095e7bSTony Olech dev_info(&vub300->udev->dev, "card just ejected\n"); 52288095e7bSTony Olech vub300->card_present = 0; 52388095e7bSTony Olech mmc_detect_change(vub300->mmc, 0); 52488095e7bSTony Olech } else { 52588095e7bSTony Olech /* no change */ 52688095e7bSTony Olech } 52788095e7bSTony Olech } 52888095e7bSTony Olech 52988095e7bSTony Olech static void __add_offloaded_reg_to_fifo(struct vub300_mmc_host *vub300, 53088095e7bSTony Olech struct offload_registers_access 53188095e7bSTony Olech *register_access, u8 func) 53288095e7bSTony Olech { 53388095e7bSTony Olech u8 r = vub300->fn[func].offload_point + vub300->fn[func].offload_count; 53488095e7bSTony Olech memcpy(&vub300->fn[func].reg[MAXREGMASK & r], register_access, 53588095e7bSTony Olech sizeof(struct offload_registers_access)); 53688095e7bSTony Olech vub300->fn[func].offload_count += 1; 53788095e7bSTony Olech vub300->total_offload_count += 1; 53888095e7bSTony Olech } 53988095e7bSTony Olech 54088095e7bSTony Olech static void add_offloaded_reg(struct vub300_mmc_host *vub300, 54188095e7bSTony Olech struct offload_registers_access *register_access) 54288095e7bSTony Olech { 54388095e7bSTony Olech u32 Register = ((0x03 & register_access->command_byte[0]) << 15) 54488095e7bSTony Olech | ((0xFF & register_access->command_byte[1]) << 7) 54588095e7bSTony Olech | ((0xFE & register_access->command_byte[2]) >> 1); 54688095e7bSTony Olech u8 func = ((0x70 & register_access->command_byte[0]) >> 4); 54788095e7bSTony Olech u8 regs = vub300->dynamic_register_count; 54888095e7bSTony Olech u8 i = 0; 54988095e7bSTony Olech while (0 < regs-- && 1 == vub300->sdio_register[i].activate) { 55088095e7bSTony Olech if (vub300->sdio_register[i].func_num == func && 55188095e7bSTony Olech vub300->sdio_register[i].sdio_reg == Register) { 55288095e7bSTony Olech if (vub300->sdio_register[i].prepared == 0) 55388095e7bSTony Olech vub300->sdio_register[i].prepared = 1; 55488095e7bSTony Olech vub300->sdio_register[i].response = 55588095e7bSTony Olech register_access->Respond_Byte[2]; 55688095e7bSTony Olech vub300->sdio_register[i].regvalue = 55788095e7bSTony Olech register_access->Respond_Byte[3]; 55888095e7bSTony Olech return; 55988095e7bSTony Olech } else { 56088095e7bSTony Olech i += 1; 56188095e7bSTony Olech continue; 56288095e7bSTony Olech } 5637eece8d0SJavier Martinez Canillas } 56488095e7bSTony Olech __add_offloaded_reg_to_fifo(vub300, register_access, func); 56588095e7bSTony Olech } 56688095e7bSTony Olech 56788095e7bSTony Olech static void check_vub300_port_status(struct vub300_mmc_host *vub300) 56888095e7bSTony Olech { 56988095e7bSTony Olech /* 57088095e7bSTony Olech * cmd_mutex is held by vub300_pollwork_thread, 57188095e7bSTony Olech * vub300_deadwork_thread or vub300_cmndwork_thread 57288095e7bSTony Olech */ 57388095e7bSTony Olech int retval; 57488095e7bSTony Olech retval = 57588095e7bSTony Olech usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), 57688095e7bSTony Olech GET_SYSTEM_PORT_STATUS, 57788095e7bSTony Olech USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 57888095e7bSTony Olech 0x0000, 0x0000, &vub300->system_port_status, 57988095e7bSTony Olech sizeof(vub300->system_port_status), HZ); 58088095e7bSTony Olech if (sizeof(vub300->system_port_status) == retval) 58188095e7bSTony Olech new_system_port_status(vub300); 58288095e7bSTony Olech } 58388095e7bSTony Olech 58488095e7bSTony Olech static void __vub300_irqpoll_response(struct vub300_mmc_host *vub300) 58588095e7bSTony Olech { 58688095e7bSTony Olech /* cmd_mutex is held by vub300_pollwork_thread */ 58788095e7bSTony Olech if (vub300->command_res_urb->actual_length == 0) 58888095e7bSTony Olech return; 58988095e7bSTony Olech 59088095e7bSTony Olech switch (vub300->resp.common.header_type) { 59188095e7bSTony Olech case RESPONSE_INTERRUPT: 59288095e7bSTony Olech mutex_lock(&vub300->irq_mutex); 59388095e7bSTony Olech if (vub300->irq_enabled) 59488095e7bSTony Olech mmc_signal_sdio_irq(vub300->mmc); 59588095e7bSTony Olech else 59688095e7bSTony Olech vub300->irqs_queued += 1; 59788095e7bSTony Olech vub300->irq_disabled = 1; 59888095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 59988095e7bSTony Olech break; 60088095e7bSTony Olech case RESPONSE_ERROR: 60188095e7bSTony Olech if (vub300->resp.error.error_code == SD_ERROR_NO_DEVICE) 60288095e7bSTony Olech check_vub300_port_status(vub300); 60388095e7bSTony Olech break; 60488095e7bSTony Olech case RESPONSE_STATUS: 60588095e7bSTony Olech vub300->system_port_status = vub300->resp.status; 60688095e7bSTony Olech new_system_port_status(vub300); 60788095e7bSTony Olech if (!vub300->card_present) 60888095e7bSTony Olech vub300_queue_poll_work(vub300, HZ / 5); 60988095e7bSTony Olech break; 61088095e7bSTony Olech case RESPONSE_IRQ_DISABLED: 61188095e7bSTony Olech { 61288095e7bSTony Olech int offloaded_data_length = vub300->resp.common.header_size - 3; 61388095e7bSTony Olech int register_count = offloaded_data_length >> 3; 61488095e7bSTony Olech int ri = 0; 61588095e7bSTony Olech while (register_count--) { 61688095e7bSTony Olech add_offloaded_reg(vub300, &vub300->resp.irq.reg[ri]); 61788095e7bSTony Olech ri += 1; 61888095e7bSTony Olech } 61988095e7bSTony Olech mutex_lock(&vub300->irq_mutex); 62088095e7bSTony Olech if (vub300->irq_enabled) 62188095e7bSTony Olech mmc_signal_sdio_irq(vub300->mmc); 62288095e7bSTony Olech else 62388095e7bSTony Olech vub300->irqs_queued += 1; 62488095e7bSTony Olech vub300->irq_disabled = 1; 62588095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 62688095e7bSTony Olech break; 62788095e7bSTony Olech } 62888095e7bSTony Olech case RESPONSE_IRQ_ENABLED: 62988095e7bSTony Olech { 63088095e7bSTony Olech int offloaded_data_length = vub300->resp.common.header_size - 3; 63188095e7bSTony Olech int register_count = offloaded_data_length >> 3; 63288095e7bSTony Olech int ri = 0; 63388095e7bSTony Olech while (register_count--) { 63488095e7bSTony Olech add_offloaded_reg(vub300, &vub300->resp.irq.reg[ri]); 63588095e7bSTony Olech ri += 1; 63688095e7bSTony Olech } 63788095e7bSTony Olech mutex_lock(&vub300->irq_mutex); 63888095e7bSTony Olech if (vub300->irq_enabled) 63988095e7bSTony Olech mmc_signal_sdio_irq(vub300->mmc); 64088095e7bSTony Olech else 64188095e7bSTony Olech vub300->irqs_queued += 1; 64288095e7bSTony Olech vub300->irq_disabled = 0; 64388095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 64488095e7bSTony Olech break; 64588095e7bSTony Olech } 64688095e7bSTony Olech case RESPONSE_NO_INTERRUPT: 64788095e7bSTony Olech vub300_queue_poll_work(vub300, 1); 64888095e7bSTony Olech break; 64988095e7bSTony Olech default: 65088095e7bSTony Olech break; 65188095e7bSTony Olech } 65288095e7bSTony Olech } 65388095e7bSTony Olech 65488095e7bSTony Olech static void __do_poll(struct vub300_mmc_host *vub300) 65588095e7bSTony Olech { 65688095e7bSTony Olech /* cmd_mutex is held by vub300_pollwork_thread */ 6576bb836d6SNicholas Mc Guire unsigned long commretval; 65888095e7bSTony Olech mod_timer(&vub300->inactivity_timer, jiffies + HZ); 65988095e7bSTony Olech init_completion(&vub300->irqpoll_complete); 66088095e7bSTony Olech send_irqpoll(vub300); 66188095e7bSTony Olech commretval = wait_for_completion_timeout(&vub300->irqpoll_complete, 66288095e7bSTony Olech msecs_to_jiffies(500)); 66388095e7bSTony Olech if (vub300->usb_transport_fail) { 66488095e7bSTony Olech /* no need to do anything */ 66588095e7bSTony Olech } else if (commretval == 0) { 66688095e7bSTony Olech vub300->usb_timed_out = 1; 66788095e7bSTony Olech usb_kill_urb(vub300->command_out_urb); 66888095e7bSTony Olech usb_kill_urb(vub300->command_res_urb); 66988095e7bSTony Olech } else { /* commretval > 0 */ 67088095e7bSTony Olech __vub300_irqpoll_response(vub300); 67188095e7bSTony Olech } 67288095e7bSTony Olech } 67388095e7bSTony Olech 67488095e7bSTony Olech /* this thread runs only when the driver 67588095e7bSTony Olech * is trying to poll the device for an IRQ 67688095e7bSTony Olech */ 67788095e7bSTony Olech static void vub300_pollwork_thread(struct work_struct *work) 67888095e7bSTony Olech { /* NOT irq */ 67988095e7bSTony Olech struct vub300_mmc_host *vub300 = container_of(work, 68088095e7bSTony Olech struct vub300_mmc_host, pollwork.work); 68188095e7bSTony Olech if (!vub300->interface) { 68288095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 68388095e7bSTony Olech return; 68488095e7bSTony Olech } 68588095e7bSTony Olech mutex_lock(&vub300->cmd_mutex); 68688095e7bSTony Olech if (vub300->cmd) { 68788095e7bSTony Olech vub300_queue_poll_work(vub300, 1); 68888095e7bSTony Olech } else if (!vub300->card_present) { 68988095e7bSTony Olech /* no need to do anything */ 69088095e7bSTony Olech } else { /* vub300->card_present */ 69188095e7bSTony Olech mutex_lock(&vub300->irq_mutex); 69288095e7bSTony Olech if (!vub300->irq_enabled) { 69388095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 69488095e7bSTony Olech } else if (vub300->irqs_queued) { 69588095e7bSTony Olech vub300->irqs_queued -= 1; 69688095e7bSTony Olech mmc_signal_sdio_irq(vub300->mmc); 69788095e7bSTony Olech mod_timer(&vub300->inactivity_timer, jiffies + HZ); 69888095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 69988095e7bSTony Olech } else { /* NOT vub300->irqs_queued */ 70088095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 70188095e7bSTony Olech __do_poll(vub300); 70288095e7bSTony Olech } 70388095e7bSTony Olech } 70488095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 70588095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 70688095e7bSTony Olech } 70788095e7bSTony Olech 70888095e7bSTony Olech static void vub300_deadwork_thread(struct work_struct *work) 70988095e7bSTony Olech { /* NOT irq */ 71088095e7bSTony Olech struct vub300_mmc_host *vub300 = 71188095e7bSTony Olech container_of(work, struct vub300_mmc_host, deadwork); 71288095e7bSTony Olech if (!vub300->interface) { 71388095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 71488095e7bSTony Olech return; 71588095e7bSTony Olech } 71688095e7bSTony Olech mutex_lock(&vub300->cmd_mutex); 71788095e7bSTony Olech if (vub300->cmd) { 71888095e7bSTony Olech /* 71988095e7bSTony Olech * a command got in as the inactivity 72088095e7bSTony Olech * timer expired - so we just let the 72188095e7bSTony Olech * processing of the command show if 72288095e7bSTony Olech * the device is dead 72388095e7bSTony Olech */ 72488095e7bSTony Olech } else if (vub300->card_present) { 72588095e7bSTony Olech check_vub300_port_status(vub300); 7262e4af7b6SUlf Hansson } else if (vub300->mmc && vub300->mmc->card) { 72788095e7bSTony Olech /* 72888095e7bSTony Olech * the MMC core must not have responded 72988095e7bSTony Olech * to the previous indication - lets 73088095e7bSTony Olech * hope that it eventually does so we 73188095e7bSTony Olech * will just ignore this for now 73288095e7bSTony Olech */ 73388095e7bSTony Olech } else { 73488095e7bSTony Olech check_vub300_port_status(vub300); 73588095e7bSTony Olech } 73688095e7bSTony Olech mod_timer(&vub300->inactivity_timer, jiffies + HZ); 73788095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 73888095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 73988095e7bSTony Olech } 74088095e7bSTony Olech 7412ee4f620SKees Cook static void vub300_inactivity_timer_expired(struct timer_list *t) 74288095e7bSTony Olech { /* softirq */ 7432ee4f620SKees Cook struct vub300_mmc_host *vub300 = from_timer(vub300, t, 7442ee4f620SKees Cook inactivity_timer); 74588095e7bSTony Olech if (!vub300->interface) { 74688095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 74788095e7bSTony Olech } else if (vub300->cmd) { 74888095e7bSTony Olech mod_timer(&vub300->inactivity_timer, jiffies + HZ); 74988095e7bSTony Olech } else { 75088095e7bSTony Olech vub300_queue_dead_work(vub300); 75188095e7bSTony Olech mod_timer(&vub300->inactivity_timer, jiffies + HZ); 75288095e7bSTony Olech } 75388095e7bSTony Olech } 75488095e7bSTony Olech 75588095e7bSTony Olech static int vub300_response_error(u8 error_code) 75688095e7bSTony Olech { 75788095e7bSTony Olech switch (error_code) { 75888095e7bSTony Olech case SD_ERROR_PIO_TIMEOUT: 75988095e7bSTony Olech case SD_ERROR_1BIT_TIMEOUT: 76088095e7bSTony Olech case SD_ERROR_4BIT_TIMEOUT: 76188095e7bSTony Olech return -ETIMEDOUT; 76288095e7bSTony Olech case SD_ERROR_STAT_DATA: 76388095e7bSTony Olech case SD_ERROR_OVERRUN: 76488095e7bSTony Olech case SD_ERROR_STAT_CMD: 76588095e7bSTony Olech case SD_ERROR_STAT_CMD_TIMEOUT: 76688095e7bSTony Olech case SD_ERROR_SDCRDY_STUCK: 76788095e7bSTony Olech case SD_ERROR_UNHANDLED: 76888095e7bSTony Olech case SD_ERROR_1BIT_CRC_WRONG: 76988095e7bSTony Olech case SD_ERROR_4BIT_CRC_WRONG: 77088095e7bSTony Olech case SD_ERROR_1BIT_CRC_ERROR: 77188095e7bSTony Olech case SD_ERROR_4BIT_CRC_ERROR: 77288095e7bSTony Olech case SD_ERROR_NO_CMD_ENDBIT: 77388095e7bSTony Olech case SD_ERROR_NO_1BIT_DATEND: 77488095e7bSTony Olech case SD_ERROR_NO_4BIT_DATEND: 77588095e7bSTony Olech case SD_ERROR_1BIT_DATA_TIMEOUT: 77688095e7bSTony Olech case SD_ERROR_4BIT_DATA_TIMEOUT: 77788095e7bSTony Olech case SD_ERROR_1BIT_UNEXPECTED_TIMEOUT: 77888095e7bSTony Olech case SD_ERROR_4BIT_UNEXPECTED_TIMEOUT: 77988095e7bSTony Olech return -EILSEQ; 78088095e7bSTony Olech case 33: 78188095e7bSTony Olech return -EILSEQ; 78288095e7bSTony Olech case SD_ERROR_ILLEGAL_COMMAND: 78388095e7bSTony Olech return -EINVAL; 78488095e7bSTony Olech case SD_ERROR_NO_DEVICE: 78588095e7bSTony Olech return -ENOMEDIUM; 78688095e7bSTony Olech default: 78788095e7bSTony Olech return -ENODEV; 78888095e7bSTony Olech } 78988095e7bSTony Olech } 79088095e7bSTony Olech 79188095e7bSTony Olech static void command_res_completed(struct urb *urb) 79288095e7bSTony Olech { /* urb completion handler - hardirq */ 79388095e7bSTony Olech struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; 79488095e7bSTony Olech if (urb->status) { 79588095e7bSTony Olech /* we have to let the initiator handle the error */ 79688095e7bSTony Olech } else if (vub300->command_res_urb->actual_length == 0) { 79788095e7bSTony Olech /* 79888095e7bSTony Olech * we have seen this happen once or twice and 79988095e7bSTony Olech * we suspect a buggy USB host controller 80088095e7bSTony Olech */ 80188095e7bSTony Olech } else if (!vub300->data) { 8027122bbb0SMasanari Iida /* this means that the command (typically CMD52) succeeded */ 80388095e7bSTony Olech } else if (vub300->resp.common.header_type != 0x02) { 80488095e7bSTony Olech /* 80588095e7bSTony Olech * this is an error response from the VUB300 chip 80688095e7bSTony Olech * and we let the initiator handle it 80788095e7bSTony Olech */ 80888095e7bSTony Olech } else if (vub300->urb) { 80988095e7bSTony Olech vub300->cmd->error = 81088095e7bSTony Olech vub300_response_error(vub300->resp.error.error_code); 81188095e7bSTony Olech usb_unlink_urb(vub300->urb); 81288095e7bSTony Olech } else { 81388095e7bSTony Olech vub300->cmd->error = 81488095e7bSTony Olech vub300_response_error(vub300->resp.error.error_code); 81588095e7bSTony Olech usb_sg_cancel(&vub300->sg_request); 81688095e7bSTony Olech } 81788095e7bSTony Olech complete(&vub300->command_complete); /* got_response_in */ 81888095e7bSTony Olech } 81988095e7bSTony Olech 82088095e7bSTony Olech static void command_out_completed(struct urb *urb) 82188095e7bSTony Olech { /* urb completion handler - hardirq */ 82288095e7bSTony Olech struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; 82388095e7bSTony Olech if (urb->status) { 82488095e7bSTony Olech complete(&vub300->command_complete); 82588095e7bSTony Olech } else { 82688095e7bSTony Olech int ret; 82788095e7bSTony Olech unsigned int pipe = 82888095e7bSTony Olech usb_rcvbulkpipe(vub300->udev, vub300->cmnd_res_ep); 82988095e7bSTony Olech usb_fill_bulk_urb(vub300->command_res_urb, vub300->udev, pipe, 83088095e7bSTony Olech &vub300->resp, sizeof(vub300->resp), 83188095e7bSTony Olech command_res_completed, vub300); 83288095e7bSTony Olech vub300->command_res_urb->actual_length = 0; 83388095e7bSTony Olech ret = usb_submit_urb(vub300->command_res_urb, GFP_ATOMIC); 83488095e7bSTony Olech if (ret == 0) { 83588095e7bSTony Olech /* 83688095e7bSTony Olech * the urb completion handler will call 83788095e7bSTony Olech * our completion handler 83888095e7bSTony Olech */ 83988095e7bSTony Olech } else { 84088095e7bSTony Olech /* 84188095e7bSTony Olech * and thus we only call it directly 84288095e7bSTony Olech * when it will not be called 84388095e7bSTony Olech */ 84488095e7bSTony Olech complete(&vub300->command_complete); 84588095e7bSTony Olech } 84688095e7bSTony Olech } 84788095e7bSTony Olech } 84888095e7bSTony Olech 84988095e7bSTony Olech /* 85088095e7bSTony Olech * the STUFF bits are masked out for the comparisons 85188095e7bSTony Olech */ 85288095e7bSTony Olech static void snoop_block_size_and_bus_width(struct vub300_mmc_host *vub300, 85388095e7bSTony Olech u32 cmd_arg) 85488095e7bSTony Olech { 85588095e7bSTony Olech if ((0xFBFFFE00 & cmd_arg) == 0x80022200) 85688095e7bSTony Olech vub300->fbs[1] = (cmd_arg << 8) | (0x00FF & vub300->fbs[1]); 85788095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x80022000) 85888095e7bSTony Olech vub300->fbs[1] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[1]); 85988095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x80042200) 86088095e7bSTony Olech vub300->fbs[2] = (cmd_arg << 8) | (0x00FF & vub300->fbs[2]); 86188095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x80042000) 86288095e7bSTony Olech vub300->fbs[2] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[2]); 86388095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x80062200) 86488095e7bSTony Olech vub300->fbs[3] = (cmd_arg << 8) | (0x00FF & vub300->fbs[3]); 86588095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x80062000) 86688095e7bSTony Olech vub300->fbs[3] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[3]); 86788095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x80082200) 86888095e7bSTony Olech vub300->fbs[4] = (cmd_arg << 8) | (0x00FF & vub300->fbs[4]); 86988095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x80082000) 87088095e7bSTony Olech vub300->fbs[4] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[4]); 87188095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x800A2200) 87288095e7bSTony Olech vub300->fbs[5] = (cmd_arg << 8) | (0x00FF & vub300->fbs[5]); 87388095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x800A2000) 87488095e7bSTony Olech vub300->fbs[5] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[5]); 87588095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x800C2200) 87688095e7bSTony Olech vub300->fbs[6] = (cmd_arg << 8) | (0x00FF & vub300->fbs[6]); 87788095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x800C2000) 87888095e7bSTony Olech vub300->fbs[6] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[6]); 87988095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x800E2200) 88088095e7bSTony Olech vub300->fbs[7] = (cmd_arg << 8) | (0x00FF & vub300->fbs[7]); 88188095e7bSTony Olech else if ((0xFBFFFE00 & cmd_arg) == 0x800E2000) 88288095e7bSTony Olech vub300->fbs[7] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[7]); 88388095e7bSTony Olech else if ((0xFBFFFE03 & cmd_arg) == 0x80000E00) 88488095e7bSTony Olech vub300->bus_width = 1; 88588095e7bSTony Olech else if ((0xFBFFFE03 & cmd_arg) == 0x80000E02) 88688095e7bSTony Olech vub300->bus_width = 4; 88788095e7bSTony Olech } 88888095e7bSTony Olech 88988095e7bSTony Olech static void send_command(struct vub300_mmc_host *vub300) 89088095e7bSTony Olech { 89188095e7bSTony Olech /* cmd_mutex is held by vub300_cmndwork_thread */ 89288095e7bSTony Olech struct mmc_command *cmd = vub300->cmd; 89388095e7bSTony Olech struct mmc_data *data = vub300->data; 89488095e7bSTony Olech int retval; 89588095e7bSTony Olech int i; 89688095e7bSTony Olech u8 response_type; 89788095e7bSTony Olech if (vub300->app_spec) { 89888095e7bSTony Olech switch (cmd->opcode) { 89988095e7bSTony Olech case 6: 90088095e7bSTony Olech response_type = SDRT_1; 90188095e7bSTony Olech vub300->resp_len = 6; 90288095e7bSTony Olech if (0x00000000 == (0x00000003 & cmd->arg)) 90388095e7bSTony Olech vub300->bus_width = 1; 90488095e7bSTony Olech else if (0x00000002 == (0x00000003 & cmd->arg)) 90588095e7bSTony Olech vub300->bus_width = 4; 90688095e7bSTony Olech else 90788095e7bSTony Olech dev_err(&vub300->udev->dev, 90888095e7bSTony Olech "unexpected ACMD6 bus_width=%d\n", 90988095e7bSTony Olech 0x00000003 & cmd->arg); 91088095e7bSTony Olech break; 91188095e7bSTony Olech case 13: 91288095e7bSTony Olech response_type = SDRT_1; 91388095e7bSTony Olech vub300->resp_len = 6; 91488095e7bSTony Olech break; 91588095e7bSTony Olech case 22: 91688095e7bSTony Olech response_type = SDRT_1; 91788095e7bSTony Olech vub300->resp_len = 6; 91888095e7bSTony Olech break; 91988095e7bSTony Olech case 23: 92088095e7bSTony Olech response_type = SDRT_1; 92188095e7bSTony Olech vub300->resp_len = 6; 92288095e7bSTony Olech break; 92388095e7bSTony Olech case 41: 92488095e7bSTony Olech response_type = SDRT_3; 92588095e7bSTony Olech vub300->resp_len = 6; 92688095e7bSTony Olech break; 92788095e7bSTony Olech case 42: 92888095e7bSTony Olech response_type = SDRT_1; 92988095e7bSTony Olech vub300->resp_len = 6; 93088095e7bSTony Olech break; 93188095e7bSTony Olech case 51: 93288095e7bSTony Olech response_type = SDRT_1; 93388095e7bSTony Olech vub300->resp_len = 6; 93488095e7bSTony Olech break; 93588095e7bSTony Olech case 55: 93688095e7bSTony Olech response_type = SDRT_1; 93788095e7bSTony Olech vub300->resp_len = 6; 93888095e7bSTony Olech break; 93988095e7bSTony Olech default: 94088095e7bSTony Olech vub300->resp_len = 0; 94188095e7bSTony Olech cmd->error = -EINVAL; 94288095e7bSTony Olech complete(&vub300->command_complete); 94388095e7bSTony Olech return; 94488095e7bSTony Olech } 94588095e7bSTony Olech vub300->app_spec = 0; 94688095e7bSTony Olech } else { 94788095e7bSTony Olech switch (cmd->opcode) { 94888095e7bSTony Olech case 0: 94988095e7bSTony Olech response_type = SDRT_NONE; 95088095e7bSTony Olech vub300->resp_len = 0; 95188095e7bSTony Olech break; 95288095e7bSTony Olech case 1: 95388095e7bSTony Olech response_type = SDRT_3; 95488095e7bSTony Olech vub300->resp_len = 6; 95588095e7bSTony Olech break; 95688095e7bSTony Olech case 2: 95788095e7bSTony Olech response_type = SDRT_2; 95888095e7bSTony Olech vub300->resp_len = 17; 95988095e7bSTony Olech break; 96088095e7bSTony Olech case 3: 96188095e7bSTony Olech response_type = SDRT_6; 96288095e7bSTony Olech vub300->resp_len = 6; 96388095e7bSTony Olech break; 96488095e7bSTony Olech case 4: 96588095e7bSTony Olech response_type = SDRT_NONE; 96688095e7bSTony Olech vub300->resp_len = 0; 96788095e7bSTony Olech break; 96888095e7bSTony Olech case 5: 96988095e7bSTony Olech response_type = SDRT_4; 97088095e7bSTony Olech vub300->resp_len = 6; 97188095e7bSTony Olech break; 97288095e7bSTony Olech case 6: 97388095e7bSTony Olech response_type = SDRT_1; 97488095e7bSTony Olech vub300->resp_len = 6; 97588095e7bSTony Olech break; 97688095e7bSTony Olech case 7: 97788095e7bSTony Olech response_type = SDRT_1B; 97888095e7bSTony Olech vub300->resp_len = 6; 97988095e7bSTony Olech break; 98088095e7bSTony Olech case 8: 98188095e7bSTony Olech response_type = SDRT_7; 98288095e7bSTony Olech vub300->resp_len = 6; 98388095e7bSTony Olech break; 98488095e7bSTony Olech case 9: 98588095e7bSTony Olech response_type = SDRT_2; 98688095e7bSTony Olech vub300->resp_len = 17; 98788095e7bSTony Olech break; 98888095e7bSTony Olech case 10: 98988095e7bSTony Olech response_type = SDRT_2; 99088095e7bSTony Olech vub300->resp_len = 17; 99188095e7bSTony Olech break; 99288095e7bSTony Olech case 12: 99388095e7bSTony Olech response_type = SDRT_1B; 99488095e7bSTony Olech vub300->resp_len = 6; 99588095e7bSTony Olech break; 99688095e7bSTony Olech case 13: 99788095e7bSTony Olech response_type = SDRT_1; 99888095e7bSTony Olech vub300->resp_len = 6; 99988095e7bSTony Olech break; 100088095e7bSTony Olech case 15: 100188095e7bSTony Olech response_type = SDRT_NONE; 100288095e7bSTony Olech vub300->resp_len = 0; 100388095e7bSTony Olech break; 100488095e7bSTony Olech case 16: 100588095e7bSTony Olech for (i = 0; i < ARRAY_SIZE(vub300->fbs); i++) 100688095e7bSTony Olech vub300->fbs[i] = 0xFFFF & cmd->arg; 100788095e7bSTony Olech response_type = SDRT_1; 100888095e7bSTony Olech vub300->resp_len = 6; 100988095e7bSTony Olech break; 101088095e7bSTony Olech case 17: 101188095e7bSTony Olech case 18: 101288095e7bSTony Olech case 24: 101388095e7bSTony Olech case 25: 101488095e7bSTony Olech case 27: 101588095e7bSTony Olech response_type = SDRT_1; 101688095e7bSTony Olech vub300->resp_len = 6; 101788095e7bSTony Olech break; 101888095e7bSTony Olech case 28: 101988095e7bSTony Olech case 29: 102088095e7bSTony Olech response_type = SDRT_1B; 102188095e7bSTony Olech vub300->resp_len = 6; 102288095e7bSTony Olech break; 102388095e7bSTony Olech case 30: 102488095e7bSTony Olech case 32: 102588095e7bSTony Olech case 33: 102688095e7bSTony Olech response_type = SDRT_1; 102788095e7bSTony Olech vub300->resp_len = 6; 102888095e7bSTony Olech break; 102988095e7bSTony Olech case 38: 103088095e7bSTony Olech response_type = SDRT_1B; 103188095e7bSTony Olech vub300->resp_len = 6; 103288095e7bSTony Olech break; 103388095e7bSTony Olech case 42: 103488095e7bSTony Olech response_type = SDRT_1; 103588095e7bSTony Olech vub300->resp_len = 6; 103688095e7bSTony Olech break; 103788095e7bSTony Olech case 52: 103888095e7bSTony Olech response_type = SDRT_5; 103988095e7bSTony Olech vub300->resp_len = 6; 104088095e7bSTony Olech snoop_block_size_and_bus_width(vub300, cmd->arg); 104188095e7bSTony Olech break; 104288095e7bSTony Olech case 53: 104388095e7bSTony Olech response_type = SDRT_5; 104488095e7bSTony Olech vub300->resp_len = 6; 104588095e7bSTony Olech break; 104688095e7bSTony Olech case 55: 104788095e7bSTony Olech response_type = SDRT_1; 104888095e7bSTony Olech vub300->resp_len = 6; 104988095e7bSTony Olech vub300->app_spec = 1; 105088095e7bSTony Olech break; 105188095e7bSTony Olech case 56: 105288095e7bSTony Olech response_type = SDRT_1; 105388095e7bSTony Olech vub300->resp_len = 6; 105488095e7bSTony Olech break; 105588095e7bSTony Olech default: 105688095e7bSTony Olech vub300->resp_len = 0; 105788095e7bSTony Olech cmd->error = -EINVAL; 105888095e7bSTony Olech complete(&vub300->command_complete); 105988095e7bSTony Olech return; 106088095e7bSTony Olech } 106188095e7bSTony Olech } 106288095e7bSTony Olech /* 106388095e7bSTony Olech * it is a shame that we can not use "sizeof(struct sd_command_header)" 106488095e7bSTony Olech * this is because the packet _must_ be padded to 64 bytes 106588095e7bSTony Olech */ 106688095e7bSTony Olech vub300->cmnd.head.header_size = 20; 106788095e7bSTony Olech vub300->cmnd.head.header_type = 0x00; 106888095e7bSTony Olech vub300->cmnd.head.port_number = 0; /* "0" means port 1 */ 106988095e7bSTony Olech vub300->cmnd.head.command_type = 0x00; /* standard read command */ 107088095e7bSTony Olech vub300->cmnd.head.response_type = response_type; 107188095e7bSTony Olech vub300->cmnd.head.command_index = cmd->opcode; 107288095e7bSTony Olech vub300->cmnd.head.arguments[0] = cmd->arg >> 24; 107388095e7bSTony Olech vub300->cmnd.head.arguments[1] = cmd->arg >> 16; 107488095e7bSTony Olech vub300->cmnd.head.arguments[2] = cmd->arg >> 8; 107588095e7bSTony Olech vub300->cmnd.head.arguments[3] = cmd->arg >> 0; 107688095e7bSTony Olech if (cmd->opcode == 52) { 107788095e7bSTony Olech int fn = 0x7 & (cmd->arg >> 28); 107888095e7bSTony Olech vub300->cmnd.head.block_count[0] = 0; 107988095e7bSTony Olech vub300->cmnd.head.block_count[1] = 0; 108088095e7bSTony Olech vub300->cmnd.head.block_size[0] = (vub300->fbs[fn] >> 8) & 0xFF; 108188095e7bSTony Olech vub300->cmnd.head.block_size[1] = (vub300->fbs[fn] >> 0) & 0xFF; 108288095e7bSTony Olech vub300->cmnd.head.command_type = 0x00; 108388095e7bSTony Olech vub300->cmnd.head.transfer_size[0] = 0; 108488095e7bSTony Olech vub300->cmnd.head.transfer_size[1] = 0; 108588095e7bSTony Olech vub300->cmnd.head.transfer_size[2] = 0; 108688095e7bSTony Olech vub300->cmnd.head.transfer_size[3] = 0; 108788095e7bSTony Olech } else if (!data) { 108888095e7bSTony Olech vub300->cmnd.head.block_count[0] = 0; 108988095e7bSTony Olech vub300->cmnd.head.block_count[1] = 0; 109088095e7bSTony Olech vub300->cmnd.head.block_size[0] = (vub300->fbs[0] >> 8) & 0xFF; 109188095e7bSTony Olech vub300->cmnd.head.block_size[1] = (vub300->fbs[0] >> 0) & 0xFF; 109288095e7bSTony Olech vub300->cmnd.head.command_type = 0x00; 109388095e7bSTony Olech vub300->cmnd.head.transfer_size[0] = 0; 109488095e7bSTony Olech vub300->cmnd.head.transfer_size[1] = 0; 109588095e7bSTony Olech vub300->cmnd.head.transfer_size[2] = 0; 109688095e7bSTony Olech vub300->cmnd.head.transfer_size[3] = 0; 109788095e7bSTony Olech } else if (cmd->opcode == 53) { 109888095e7bSTony Olech int fn = 0x7 & (cmd->arg >> 28); 109988095e7bSTony Olech if (0x08 & vub300->cmnd.head.arguments[0]) { /* BLOCK MODE */ 110088095e7bSTony Olech vub300->cmnd.head.block_count[0] = 110188095e7bSTony Olech (data->blocks >> 8) & 0xFF; 110288095e7bSTony Olech vub300->cmnd.head.block_count[1] = 110388095e7bSTony Olech (data->blocks >> 0) & 0xFF; 110488095e7bSTony Olech vub300->cmnd.head.block_size[0] = 110588095e7bSTony Olech (data->blksz >> 8) & 0xFF; 110688095e7bSTony Olech vub300->cmnd.head.block_size[1] = 110788095e7bSTony Olech (data->blksz >> 0) & 0xFF; 110888095e7bSTony Olech } else { /* BYTE MODE */ 110988095e7bSTony Olech vub300->cmnd.head.block_count[0] = 0; 111088095e7bSTony Olech vub300->cmnd.head.block_count[1] = 0; 111188095e7bSTony Olech vub300->cmnd.head.block_size[0] = 111288095e7bSTony Olech (vub300->datasize >> 8) & 0xFF; 111388095e7bSTony Olech vub300->cmnd.head.block_size[1] = 111488095e7bSTony Olech (vub300->datasize >> 0) & 0xFF; 111588095e7bSTony Olech } 111688095e7bSTony Olech vub300->cmnd.head.command_type = 111788095e7bSTony Olech (MMC_DATA_READ & data->flags) ? 0x00 : 0x80; 111888095e7bSTony Olech vub300->cmnd.head.transfer_size[0] = 111988095e7bSTony Olech (vub300->datasize >> 24) & 0xFF; 112088095e7bSTony Olech vub300->cmnd.head.transfer_size[1] = 112188095e7bSTony Olech (vub300->datasize >> 16) & 0xFF; 112288095e7bSTony Olech vub300->cmnd.head.transfer_size[2] = 112388095e7bSTony Olech (vub300->datasize >> 8) & 0xFF; 112488095e7bSTony Olech vub300->cmnd.head.transfer_size[3] = 112588095e7bSTony Olech (vub300->datasize >> 0) & 0xFF; 112688095e7bSTony Olech if (vub300->datasize < vub300->fbs[fn]) { 112788095e7bSTony Olech vub300->cmnd.head.block_count[0] = 0; 112888095e7bSTony Olech vub300->cmnd.head.block_count[1] = 0; 112988095e7bSTony Olech } 113088095e7bSTony Olech } else { 113188095e7bSTony Olech vub300->cmnd.head.block_count[0] = (data->blocks >> 8) & 0xFF; 113288095e7bSTony Olech vub300->cmnd.head.block_count[1] = (data->blocks >> 0) & 0xFF; 113388095e7bSTony Olech vub300->cmnd.head.block_size[0] = (data->blksz >> 8) & 0xFF; 113488095e7bSTony Olech vub300->cmnd.head.block_size[1] = (data->blksz >> 0) & 0xFF; 113588095e7bSTony Olech vub300->cmnd.head.command_type = 113688095e7bSTony Olech (MMC_DATA_READ & data->flags) ? 0x00 : 0x80; 113788095e7bSTony Olech vub300->cmnd.head.transfer_size[0] = 113888095e7bSTony Olech (vub300->datasize >> 24) & 0xFF; 113988095e7bSTony Olech vub300->cmnd.head.transfer_size[1] = 114088095e7bSTony Olech (vub300->datasize >> 16) & 0xFF; 114188095e7bSTony Olech vub300->cmnd.head.transfer_size[2] = 114288095e7bSTony Olech (vub300->datasize >> 8) & 0xFF; 114388095e7bSTony Olech vub300->cmnd.head.transfer_size[3] = 114488095e7bSTony Olech (vub300->datasize >> 0) & 0xFF; 114588095e7bSTony Olech if (vub300->datasize < vub300->fbs[0]) { 114688095e7bSTony Olech vub300->cmnd.head.block_count[0] = 0; 114788095e7bSTony Olech vub300->cmnd.head.block_count[1] = 0; 114888095e7bSTony Olech } 114988095e7bSTony Olech } 115088095e7bSTony Olech if (vub300->cmnd.head.block_size[0] || vub300->cmnd.head.block_size[1]) { 115188095e7bSTony Olech u16 block_size = vub300->cmnd.head.block_size[1] | 115288095e7bSTony Olech (vub300->cmnd.head.block_size[0] << 8); 115388095e7bSTony Olech u16 block_boundary = FIRMWARE_BLOCK_BOUNDARY - 115488095e7bSTony Olech (FIRMWARE_BLOCK_BOUNDARY % block_size); 115588095e7bSTony Olech vub300->cmnd.head.block_boundary[0] = 115688095e7bSTony Olech (block_boundary >> 8) & 0xFF; 115788095e7bSTony Olech vub300->cmnd.head.block_boundary[1] = 115888095e7bSTony Olech (block_boundary >> 0) & 0xFF; 115988095e7bSTony Olech } else { 116088095e7bSTony Olech vub300->cmnd.head.block_boundary[0] = 0; 116188095e7bSTony Olech vub300->cmnd.head.block_boundary[1] = 0; 116288095e7bSTony Olech } 116388095e7bSTony Olech usb_fill_bulk_urb(vub300->command_out_urb, vub300->udev, 116488095e7bSTony Olech usb_sndbulkpipe(vub300->udev, vub300->cmnd_out_ep), 116588095e7bSTony Olech &vub300->cmnd, sizeof(vub300->cmnd), 116688095e7bSTony Olech command_out_completed, vub300); 116788095e7bSTony Olech retval = usb_submit_urb(vub300->command_out_urb, GFP_KERNEL); 116888095e7bSTony Olech if (retval < 0) { 116988095e7bSTony Olech cmd->error = retval; 117088095e7bSTony Olech complete(&vub300->command_complete); 117188095e7bSTony Olech return; 117288095e7bSTony Olech } else { 117388095e7bSTony Olech return; 117488095e7bSTony Olech } 117588095e7bSTony Olech } 117688095e7bSTony Olech 117788095e7bSTony Olech /* 117888095e7bSTony Olech * timer callback runs in atomic mode 117988095e7bSTony Olech * so it cannot call usb_kill_urb() 118088095e7bSTony Olech */ 11812ee4f620SKees Cook static void vub300_sg_timed_out(struct timer_list *t) 118288095e7bSTony Olech { 11832ee4f620SKees Cook struct vub300_mmc_host *vub300 = from_timer(vub300, t, 11842ee4f620SKees Cook sg_transfer_timer); 118588095e7bSTony Olech vub300->usb_timed_out = 1; 118688095e7bSTony Olech usb_sg_cancel(&vub300->sg_request); 118788095e7bSTony Olech usb_unlink_urb(vub300->command_out_urb); 118888095e7bSTony Olech usb_unlink_urb(vub300->command_res_urb); 118988095e7bSTony Olech } 119088095e7bSTony Olech 119188095e7bSTony Olech static u16 roundup_to_multiple_of_64(u16 number) 119288095e7bSTony Olech { 119388095e7bSTony Olech return 0xFFC0 & (0x3F + number); 119488095e7bSTony Olech } 119588095e7bSTony Olech 119688095e7bSTony Olech /* 119788095e7bSTony Olech * this is a separate function to solve the 80 column width restriction 119888095e7bSTony Olech */ 119988095e7bSTony Olech static void __download_offload_pseudocode(struct vub300_mmc_host *vub300, 120088095e7bSTony Olech const struct firmware *fw) 120188095e7bSTony Olech { 120288095e7bSTony Olech u8 register_count = 0; 120388095e7bSTony Olech u16 ts = 0; 120488095e7bSTony Olech u16 interrupt_size = 0; 120588095e7bSTony Olech const u8 *data = fw->data; 120688095e7bSTony Olech int size = fw->size; 120788095e7bSTony Olech u8 c; 120888095e7bSTony Olech dev_info(&vub300->udev->dev, "using %s for SDIO offload processing\n", 120988095e7bSTony Olech vub300->vub_name); 121088095e7bSTony Olech do { 121188095e7bSTony Olech c = *data++; 121288095e7bSTony Olech } while (size-- && c); /* skip comment */ 121388095e7bSTony Olech dev_info(&vub300->udev->dev, "using offload firmware %s %s\n", fw->data, 121488095e7bSTony Olech vub300->vub_name); 121588095e7bSTony Olech if (size < 4) { 121688095e7bSTony Olech dev_err(&vub300->udev->dev, 121788095e7bSTony Olech "corrupt offload pseudocode in firmware %s\n", 121888095e7bSTony Olech vub300->vub_name); 121988095e7bSTony Olech strncpy(vub300->vub_name, "corrupt offload pseudocode", 122088095e7bSTony Olech sizeof(vub300->vub_name)); 122188095e7bSTony Olech return; 122288095e7bSTony Olech } 122388095e7bSTony Olech interrupt_size += *data++; 122488095e7bSTony Olech size -= 1; 122588095e7bSTony Olech interrupt_size <<= 8; 122688095e7bSTony Olech interrupt_size += *data++; 122788095e7bSTony Olech size -= 1; 122888095e7bSTony Olech if (interrupt_size < size) { 122988095e7bSTony Olech u16 xfer_length = roundup_to_multiple_of_64(interrupt_size); 123088095e7bSTony Olech u8 *xfer_buffer = kmalloc(xfer_length, GFP_KERNEL); 123188095e7bSTony Olech if (xfer_buffer) { 123288095e7bSTony Olech int retval; 123388095e7bSTony Olech memcpy(xfer_buffer, data, interrupt_size); 123488095e7bSTony Olech memset(xfer_buffer + interrupt_size, 0, 123588095e7bSTony Olech xfer_length - interrupt_size); 123688095e7bSTony Olech size -= interrupt_size; 123788095e7bSTony Olech data += interrupt_size; 123888095e7bSTony Olech retval = 123988095e7bSTony Olech usb_control_msg(vub300->udev, 124088095e7bSTony Olech usb_sndctrlpipe(vub300->udev, 0), 124188095e7bSTony Olech SET_INTERRUPT_PSEUDOCODE, 124288095e7bSTony Olech USB_DIR_OUT | USB_TYPE_VENDOR | 124388095e7bSTony Olech USB_RECIP_DEVICE, 0x0000, 0x0000, 124488095e7bSTony Olech xfer_buffer, xfer_length, HZ); 124588095e7bSTony Olech kfree(xfer_buffer); 12462d1d31ddSMarkus Elfring if (retval < 0) 12472d1d31ddSMarkus Elfring goto copy_error_message; 124888095e7bSTony Olech } else { 124988095e7bSTony Olech dev_err(&vub300->udev->dev, 125088095e7bSTony Olech "not enough memory for xfer buffer to send" 125188095e7bSTony Olech " INTERRUPT_PSEUDOCODE for %s %s\n", fw->data, 125288095e7bSTony Olech vub300->vub_name); 125388095e7bSTony Olech strncpy(vub300->vub_name, 125488095e7bSTony Olech "SDIO interrupt pseudocode download failed", 125588095e7bSTony Olech sizeof(vub300->vub_name)); 125688095e7bSTony Olech return; 125788095e7bSTony Olech } 125888095e7bSTony Olech } else { 125988095e7bSTony Olech dev_err(&vub300->udev->dev, 126088095e7bSTony Olech "corrupt interrupt pseudocode in firmware %s %s\n", 126188095e7bSTony Olech fw->data, vub300->vub_name); 126288095e7bSTony Olech strncpy(vub300->vub_name, "corrupt interrupt pseudocode", 126388095e7bSTony Olech sizeof(vub300->vub_name)); 126488095e7bSTony Olech return; 126588095e7bSTony Olech } 126688095e7bSTony Olech ts += *data++; 126788095e7bSTony Olech size -= 1; 126888095e7bSTony Olech ts <<= 8; 126988095e7bSTony Olech ts += *data++; 127088095e7bSTony Olech size -= 1; 127188095e7bSTony Olech if (ts < size) { 127288095e7bSTony Olech u16 xfer_length = roundup_to_multiple_of_64(ts); 127388095e7bSTony Olech u8 *xfer_buffer = kmalloc(xfer_length, GFP_KERNEL); 127488095e7bSTony Olech if (xfer_buffer) { 127588095e7bSTony Olech int retval; 127688095e7bSTony Olech memcpy(xfer_buffer, data, ts); 127788095e7bSTony Olech memset(xfer_buffer + ts, 0, 127888095e7bSTony Olech xfer_length - ts); 127988095e7bSTony Olech size -= ts; 128088095e7bSTony Olech data += ts; 128188095e7bSTony Olech retval = 128288095e7bSTony Olech usb_control_msg(vub300->udev, 128388095e7bSTony Olech usb_sndctrlpipe(vub300->udev, 0), 128488095e7bSTony Olech SET_TRANSFER_PSEUDOCODE, 128588095e7bSTony Olech USB_DIR_OUT | USB_TYPE_VENDOR | 128688095e7bSTony Olech USB_RECIP_DEVICE, 0x0000, 0x0000, 128788095e7bSTony Olech xfer_buffer, xfer_length, HZ); 128888095e7bSTony Olech kfree(xfer_buffer); 12892d1d31ddSMarkus Elfring if (retval < 0) 12902d1d31ddSMarkus Elfring goto copy_error_message; 129188095e7bSTony Olech } else { 129288095e7bSTony Olech dev_err(&vub300->udev->dev, 129388095e7bSTony Olech "not enough memory for xfer buffer to send" 129488095e7bSTony Olech " TRANSFER_PSEUDOCODE for %s %s\n", fw->data, 129588095e7bSTony Olech vub300->vub_name); 129688095e7bSTony Olech strncpy(vub300->vub_name, 129788095e7bSTony Olech "SDIO transfer pseudocode download failed", 129888095e7bSTony Olech sizeof(vub300->vub_name)); 129988095e7bSTony Olech return; 130088095e7bSTony Olech } 130188095e7bSTony Olech } else { 130288095e7bSTony Olech dev_err(&vub300->udev->dev, 130388095e7bSTony Olech "corrupt transfer pseudocode in firmware %s %s\n", 130488095e7bSTony Olech fw->data, vub300->vub_name); 130588095e7bSTony Olech strncpy(vub300->vub_name, "corrupt transfer pseudocode", 130688095e7bSTony Olech sizeof(vub300->vub_name)); 130788095e7bSTony Olech return; 130888095e7bSTony Olech } 130988095e7bSTony Olech register_count += *data++; 131088095e7bSTony Olech size -= 1; 131188095e7bSTony Olech if (register_count * 4 == size) { 131288095e7bSTony Olech int I = vub300->dynamic_register_count = register_count; 131388095e7bSTony Olech int i = 0; 131488095e7bSTony Olech while (I--) { 131588095e7bSTony Olech unsigned int func_num = 0; 131688095e7bSTony Olech vub300->sdio_register[i].func_num = *data++; 131788095e7bSTony Olech size -= 1; 131888095e7bSTony Olech func_num += *data++; 131988095e7bSTony Olech size -= 1; 132088095e7bSTony Olech func_num <<= 8; 132188095e7bSTony Olech func_num += *data++; 132288095e7bSTony Olech size -= 1; 132388095e7bSTony Olech func_num <<= 8; 132488095e7bSTony Olech func_num += *data++; 132588095e7bSTony Olech size -= 1; 132688095e7bSTony Olech vub300->sdio_register[i].sdio_reg = func_num; 132788095e7bSTony Olech vub300->sdio_register[i].activate = 1; 132888095e7bSTony Olech vub300->sdio_register[i].prepared = 0; 132988095e7bSTony Olech i += 1; 133088095e7bSTony Olech } 133188095e7bSTony Olech dev_info(&vub300->udev->dev, 133288095e7bSTony Olech "initialized %d dynamic pseudocode registers\n", 133388095e7bSTony Olech vub300->dynamic_register_count); 133488095e7bSTony Olech return; 133588095e7bSTony Olech } else { 133688095e7bSTony Olech dev_err(&vub300->udev->dev, 133788095e7bSTony Olech "corrupt dynamic registers in firmware %s\n", 133888095e7bSTony Olech vub300->vub_name); 133988095e7bSTony Olech strncpy(vub300->vub_name, "corrupt dynamic registers", 134088095e7bSTony Olech sizeof(vub300->vub_name)); 134188095e7bSTony Olech return; 134288095e7bSTony Olech } 13432d1d31ddSMarkus Elfring 13442d1d31ddSMarkus Elfring return; 13452d1d31ddSMarkus Elfring 13462d1d31ddSMarkus Elfring copy_error_message: 13472d1d31ddSMarkus Elfring strncpy(vub300->vub_name, "SDIO pseudocode download failed", 13482d1d31ddSMarkus Elfring sizeof(vub300->vub_name)); 134988095e7bSTony Olech } 135088095e7bSTony Olech 135188095e7bSTony Olech /* 135288095e7bSTony Olech * if the binary containing the EMPTY PseudoCode can not be found 135388095e7bSTony Olech * vub300->vub_name is set anyway in order to prevent an automatic retry 135488095e7bSTony Olech */ 135588095e7bSTony Olech static void download_offload_pseudocode(struct vub300_mmc_host *vub300) 135688095e7bSTony Olech { 135788095e7bSTony Olech struct mmc_card *card = vub300->mmc->card; 135888095e7bSTony Olech int sdio_funcs = card->sdio_funcs; 135988095e7bSTony Olech const struct firmware *fw = NULL; 136088095e7bSTony Olech int l = snprintf(vub300->vub_name, sizeof(vub300->vub_name), 136188095e7bSTony Olech "vub_%04X%04X", card->cis.vendor, card->cis.device); 136288095e7bSTony Olech int n = 0; 136388095e7bSTony Olech int retval; 136488095e7bSTony Olech for (n = 0; n < sdio_funcs; n++) { 136588095e7bSTony Olech struct sdio_func *sf = card->sdio_func[n]; 13666bbcf74dSTakashi Iwai l += scnprintf(vub300->vub_name + l, 136788095e7bSTony Olech sizeof(vub300->vub_name) - l, "_%04X%04X", 136888095e7bSTony Olech sf->vendor, sf->device); 13697eece8d0SJavier Martinez Canillas } 137088095e7bSTony Olech snprintf(vub300->vub_name + l, sizeof(vub300->vub_name) - l, ".bin"); 137188095e7bSTony Olech dev_info(&vub300->udev->dev, "requesting offload firmware %s\n", 137288095e7bSTony Olech vub300->vub_name); 137388095e7bSTony Olech retval = request_firmware(&fw, vub300->vub_name, &card->dev); 137488095e7bSTony Olech if (retval < 0) { 137588095e7bSTony Olech strncpy(vub300->vub_name, "vub_default.bin", 137688095e7bSTony Olech sizeof(vub300->vub_name)); 137788095e7bSTony Olech retval = request_firmware(&fw, vub300->vub_name, &card->dev); 137888095e7bSTony Olech if (retval < 0) { 137988095e7bSTony Olech strncpy(vub300->vub_name, 138088095e7bSTony Olech "no SDIO offload firmware found", 138188095e7bSTony Olech sizeof(vub300->vub_name)); 138288095e7bSTony Olech } else { 138388095e7bSTony Olech __download_offload_pseudocode(vub300, fw); 138488095e7bSTony Olech release_firmware(fw); 138588095e7bSTony Olech } 138688095e7bSTony Olech } else { 138788095e7bSTony Olech __download_offload_pseudocode(vub300, fw); 138888095e7bSTony Olech release_firmware(fw); 138988095e7bSTony Olech } 139088095e7bSTony Olech } 139188095e7bSTony Olech 139288095e7bSTony Olech static void vub300_usb_bulk_msg_completion(struct urb *urb) 139388095e7bSTony Olech { /* urb completion handler - hardirq */ 139488095e7bSTony Olech complete((struct completion *)urb->context); 139588095e7bSTony Olech } 139688095e7bSTony Olech 139788095e7bSTony Olech static int vub300_usb_bulk_msg(struct vub300_mmc_host *vub300, 139888095e7bSTony Olech unsigned int pipe, void *data, int len, 139988095e7bSTony Olech int *actual_length, int timeout_msecs) 140088095e7bSTony Olech { 140188095e7bSTony Olech /* cmd_mutex is held by vub300_cmndwork_thread */ 140288095e7bSTony Olech struct usb_device *usb_dev = vub300->udev; 140388095e7bSTony Olech struct completion done; 140488095e7bSTony Olech int retval; 140588095e7bSTony Olech vub300->urb = usb_alloc_urb(0, GFP_KERNEL); 140688095e7bSTony Olech if (!vub300->urb) 140788095e7bSTony Olech return -ENOMEM; 140888095e7bSTony Olech usb_fill_bulk_urb(vub300->urb, usb_dev, pipe, data, len, 140988095e7bSTony Olech vub300_usb_bulk_msg_completion, NULL); 141088095e7bSTony Olech init_completion(&done); 141188095e7bSTony Olech vub300->urb->context = &done; 141288095e7bSTony Olech vub300->urb->actual_length = 0; 141388095e7bSTony Olech retval = usb_submit_urb(vub300->urb, GFP_KERNEL); 141488095e7bSTony Olech if (unlikely(retval)) 141588095e7bSTony Olech goto out; 141688095e7bSTony Olech if (!wait_for_completion_timeout 141788095e7bSTony Olech (&done, msecs_to_jiffies(timeout_msecs))) { 141888095e7bSTony Olech retval = -ETIMEDOUT; 141988095e7bSTony Olech usb_kill_urb(vub300->urb); 142088095e7bSTony Olech } else { 142188095e7bSTony Olech retval = vub300->urb->status; 142288095e7bSTony Olech } 142388095e7bSTony Olech out: 142488095e7bSTony Olech *actual_length = vub300->urb->actual_length; 142588095e7bSTony Olech usb_free_urb(vub300->urb); 142688095e7bSTony Olech vub300->urb = NULL; 142788095e7bSTony Olech return retval; 142888095e7bSTony Olech } 142988095e7bSTony Olech 143088095e7bSTony Olech static int __command_read_data(struct vub300_mmc_host *vub300, 143188095e7bSTony Olech struct mmc_command *cmd, struct mmc_data *data) 143288095e7bSTony Olech { 143388095e7bSTony Olech /* cmd_mutex is held by vub300_cmndwork_thread */ 143488095e7bSTony Olech int linear_length = vub300->datasize; 143588095e7bSTony Olech int padded_length = vub300->large_usb_packets ? 143688095e7bSTony Olech ((511 + linear_length) >> 9) << 9 : 143788095e7bSTony Olech ((63 + linear_length) >> 6) << 6; 143888095e7bSTony Olech if ((padded_length == linear_length) || !pad_input_to_usb_pkt) { 143988095e7bSTony Olech int result; 144088095e7bSTony Olech unsigned pipe; 144188095e7bSTony Olech pipe = usb_rcvbulkpipe(vub300->udev, vub300->data_inp_ep); 144288095e7bSTony Olech result = usb_sg_init(&vub300->sg_request, vub300->udev, 144388095e7bSTony Olech pipe, 0, data->sg, 144488095e7bSTony Olech data->sg_len, 0, GFP_KERNEL); 144588095e7bSTony Olech if (result < 0) { 144688095e7bSTony Olech usb_unlink_urb(vub300->command_out_urb); 144788095e7bSTony Olech usb_unlink_urb(vub300->command_res_urb); 144888095e7bSTony Olech cmd->error = result; 144988095e7bSTony Olech data->bytes_xfered = 0; 145088095e7bSTony Olech return 0; 145188095e7bSTony Olech } else { 145288095e7bSTony Olech vub300->sg_transfer_timer.expires = 145388095e7bSTony Olech jiffies + msecs_to_jiffies(2000 + 145488095e7bSTony Olech (linear_length / 16384)); 145588095e7bSTony Olech add_timer(&vub300->sg_transfer_timer); 145688095e7bSTony Olech usb_sg_wait(&vub300->sg_request); 145788095e7bSTony Olech del_timer(&vub300->sg_transfer_timer); 145888095e7bSTony Olech if (vub300->sg_request.status < 0) { 145988095e7bSTony Olech cmd->error = vub300->sg_request.status; 146088095e7bSTony Olech data->bytes_xfered = 0; 146188095e7bSTony Olech return 0; 146288095e7bSTony Olech } else { 146388095e7bSTony Olech data->bytes_xfered = vub300->datasize; 146488095e7bSTony Olech return linear_length; 146588095e7bSTony Olech } 146688095e7bSTony Olech } 146788095e7bSTony Olech } else { 146888095e7bSTony Olech u8 *buf = kmalloc(padded_length, GFP_KERNEL); 146988095e7bSTony Olech if (buf) { 147088095e7bSTony Olech int result; 147188095e7bSTony Olech unsigned pipe = usb_rcvbulkpipe(vub300->udev, 147288095e7bSTony Olech vub300->data_inp_ep); 147388095e7bSTony Olech int actual_length = 0; 147488095e7bSTony Olech result = vub300_usb_bulk_msg(vub300, pipe, buf, 147588095e7bSTony Olech padded_length, &actual_length, 147688095e7bSTony Olech 2000 + (padded_length / 16384)); 147788095e7bSTony Olech if (result < 0) { 147888095e7bSTony Olech cmd->error = result; 147988095e7bSTony Olech data->bytes_xfered = 0; 148088095e7bSTony Olech kfree(buf); 148188095e7bSTony Olech return 0; 148288095e7bSTony Olech } else if (actual_length < linear_length) { 148388095e7bSTony Olech cmd->error = -EREMOTEIO; 148488095e7bSTony Olech data->bytes_xfered = 0; 148588095e7bSTony Olech kfree(buf); 148688095e7bSTony Olech return 0; 148788095e7bSTony Olech } else { 148888095e7bSTony Olech sg_copy_from_buffer(data->sg, data->sg_len, buf, 148988095e7bSTony Olech linear_length); 149088095e7bSTony Olech kfree(buf); 149188095e7bSTony Olech data->bytes_xfered = vub300->datasize; 149288095e7bSTony Olech return linear_length; 149388095e7bSTony Olech } 149488095e7bSTony Olech } else { 149588095e7bSTony Olech cmd->error = -ENOMEM; 149688095e7bSTony Olech data->bytes_xfered = 0; 149788095e7bSTony Olech return 0; 149888095e7bSTony Olech } 149988095e7bSTony Olech } 150088095e7bSTony Olech } 150188095e7bSTony Olech 150288095e7bSTony Olech static int __command_write_data(struct vub300_mmc_host *vub300, 150388095e7bSTony Olech struct mmc_command *cmd, struct mmc_data *data) 150488095e7bSTony Olech { 150588095e7bSTony Olech /* cmd_mutex is held by vub300_cmndwork_thread */ 150688095e7bSTony Olech unsigned pipe = usb_sndbulkpipe(vub300->udev, vub300->data_out_ep); 150788095e7bSTony Olech int linear_length = vub300->datasize; 150888095e7bSTony Olech int modulo_64_length = linear_length & 0x003F; 150988095e7bSTony Olech int modulo_512_length = linear_length & 0x01FF; 151088095e7bSTony Olech if (linear_length < 64) { 151188095e7bSTony Olech int result; 151288095e7bSTony Olech int actual_length; 151388095e7bSTony Olech sg_copy_to_buffer(data->sg, data->sg_len, 151488095e7bSTony Olech vub300->padded_buffer, 151588095e7bSTony Olech sizeof(vub300->padded_buffer)); 151688095e7bSTony Olech memset(vub300->padded_buffer + linear_length, 0, 151788095e7bSTony Olech sizeof(vub300->padded_buffer) - linear_length); 151888095e7bSTony Olech result = vub300_usb_bulk_msg(vub300, pipe, vub300->padded_buffer, 151988095e7bSTony Olech sizeof(vub300->padded_buffer), 152088095e7bSTony Olech &actual_length, 2000 + 152188095e7bSTony Olech (sizeof(vub300->padded_buffer) / 152288095e7bSTony Olech 16384)); 152388095e7bSTony Olech if (result < 0) { 152488095e7bSTony Olech cmd->error = result; 152588095e7bSTony Olech data->bytes_xfered = 0; 152688095e7bSTony Olech } else { 152788095e7bSTony Olech data->bytes_xfered = vub300->datasize; 152888095e7bSTony Olech } 152988095e7bSTony Olech } else if ((!vub300->large_usb_packets && (0 < modulo_64_length)) || 153088095e7bSTony Olech (vub300->large_usb_packets && (64 > modulo_512_length)) 153188095e7bSTony Olech ) { /* don't you just love these work-rounds */ 153288095e7bSTony Olech int padded_length = ((63 + linear_length) >> 6) << 6; 153388095e7bSTony Olech u8 *buf = kmalloc(padded_length, GFP_KERNEL); 153488095e7bSTony Olech if (buf) { 153588095e7bSTony Olech int result; 153688095e7bSTony Olech int actual_length; 153788095e7bSTony Olech sg_copy_to_buffer(data->sg, data->sg_len, buf, 153888095e7bSTony Olech padded_length); 153988095e7bSTony Olech memset(buf + linear_length, 0, 154088095e7bSTony Olech padded_length - linear_length); 154188095e7bSTony Olech result = 154288095e7bSTony Olech vub300_usb_bulk_msg(vub300, pipe, buf, 154388095e7bSTony Olech padded_length, &actual_length, 154488095e7bSTony Olech 2000 + padded_length / 16384); 154588095e7bSTony Olech kfree(buf); 154688095e7bSTony Olech if (result < 0) { 154788095e7bSTony Olech cmd->error = result; 154888095e7bSTony Olech data->bytes_xfered = 0; 154988095e7bSTony Olech } else { 155088095e7bSTony Olech data->bytes_xfered = vub300->datasize; 155188095e7bSTony Olech } 155288095e7bSTony Olech } else { 155388095e7bSTony Olech cmd->error = -ENOMEM; 155488095e7bSTony Olech data->bytes_xfered = 0; 155588095e7bSTony Olech } 155688095e7bSTony Olech } else { /* no data padding required */ 155788095e7bSTony Olech int result; 155888095e7bSTony Olech unsigned char buf[64 * 4]; 155988095e7bSTony Olech sg_copy_to_buffer(data->sg, data->sg_len, buf, sizeof(buf)); 156088095e7bSTony Olech result = usb_sg_init(&vub300->sg_request, vub300->udev, 156188095e7bSTony Olech pipe, 0, data->sg, 156288095e7bSTony Olech data->sg_len, 0, GFP_KERNEL); 156388095e7bSTony Olech if (result < 0) { 156488095e7bSTony Olech usb_unlink_urb(vub300->command_out_urb); 156588095e7bSTony Olech usb_unlink_urb(vub300->command_res_urb); 156688095e7bSTony Olech cmd->error = result; 156788095e7bSTony Olech data->bytes_xfered = 0; 156888095e7bSTony Olech } else { 156988095e7bSTony Olech vub300->sg_transfer_timer.expires = 157088095e7bSTony Olech jiffies + msecs_to_jiffies(2000 + 157188095e7bSTony Olech linear_length / 16384); 157288095e7bSTony Olech add_timer(&vub300->sg_transfer_timer); 157388095e7bSTony Olech usb_sg_wait(&vub300->sg_request); 157488095e7bSTony Olech if (cmd->error) { 157588095e7bSTony Olech data->bytes_xfered = 0; 157688095e7bSTony Olech } else { 157788095e7bSTony Olech del_timer(&vub300->sg_transfer_timer); 157888095e7bSTony Olech if (vub300->sg_request.status < 0) { 157988095e7bSTony Olech cmd->error = vub300->sg_request.status; 158088095e7bSTony Olech data->bytes_xfered = 0; 158188095e7bSTony Olech } else { 158288095e7bSTony Olech data->bytes_xfered = vub300->datasize; 158388095e7bSTony Olech } 158488095e7bSTony Olech } 158588095e7bSTony Olech } 158688095e7bSTony Olech } 158788095e7bSTony Olech return linear_length; 158888095e7bSTony Olech } 158988095e7bSTony Olech 159088095e7bSTony Olech static void __vub300_command_response(struct vub300_mmc_host *vub300, 159188095e7bSTony Olech struct mmc_command *cmd, 159288095e7bSTony Olech struct mmc_data *data, int data_length) 159388095e7bSTony Olech { 159488095e7bSTony Olech /* cmd_mutex is held by vub300_cmndwork_thread */ 159588095e7bSTony Olech long respretval; 159688095e7bSTony Olech int msec_timeout = 1000 + data_length / 4; 159788095e7bSTony Olech respretval = 159888095e7bSTony Olech wait_for_completion_timeout(&vub300->command_complete, 159988095e7bSTony Olech msecs_to_jiffies(msec_timeout)); 160088095e7bSTony Olech if (respretval == 0) { /* TIMED OUT */ 160188095e7bSTony Olech /* we don't know which of "out" and "res" if any failed */ 160288095e7bSTony Olech int result; 160388095e7bSTony Olech vub300->usb_timed_out = 1; 160488095e7bSTony Olech usb_kill_urb(vub300->command_out_urb); 160588095e7bSTony Olech usb_kill_urb(vub300->command_res_urb); 160688095e7bSTony Olech cmd->error = -ETIMEDOUT; 160788095e7bSTony Olech result = usb_lock_device_for_reset(vub300->udev, 160888095e7bSTony Olech vub300->interface); 160988095e7bSTony Olech if (result == 0) { 161088095e7bSTony Olech result = usb_reset_device(vub300->udev); 161188095e7bSTony Olech usb_unlock_device(vub300->udev); 161288095e7bSTony Olech } 161388095e7bSTony Olech } else if (respretval < 0) { 161488095e7bSTony Olech /* we don't know which of "out" and "res" if any failed */ 161588095e7bSTony Olech usb_kill_urb(vub300->command_out_urb); 161688095e7bSTony Olech usb_kill_urb(vub300->command_res_urb); 161788095e7bSTony Olech cmd->error = respretval; 161888095e7bSTony Olech } else if (cmd->error) { 161988095e7bSTony Olech /* 1620dbc6221bSJoe Perches * the error occurred sending the command 1621dbc6221bSJoe Perches * or receiving the response 162288095e7bSTony Olech */ 162388095e7bSTony Olech } else if (vub300->command_out_urb->status) { 162488095e7bSTony Olech vub300->usb_transport_fail = vub300->command_out_urb->status; 162588095e7bSTony Olech cmd->error = -EPROTO == vub300->command_out_urb->status ? 162688095e7bSTony Olech -ESHUTDOWN : vub300->command_out_urb->status; 162788095e7bSTony Olech } else if (vub300->command_res_urb->status) { 162888095e7bSTony Olech vub300->usb_transport_fail = vub300->command_res_urb->status; 162988095e7bSTony Olech cmd->error = -EPROTO == vub300->command_res_urb->status ? 163088095e7bSTony Olech -ESHUTDOWN : vub300->command_res_urb->status; 163188095e7bSTony Olech } else if (vub300->resp.common.header_type == 0x00) { 163288095e7bSTony Olech /* 163388095e7bSTony Olech * the command completed successfully 163488095e7bSTony Olech * and there was no piggybacked data 163588095e7bSTony Olech */ 163688095e7bSTony Olech } else if (vub300->resp.common.header_type == RESPONSE_ERROR) { 163788095e7bSTony Olech cmd->error = 163888095e7bSTony Olech vub300_response_error(vub300->resp.error.error_code); 163988095e7bSTony Olech if (vub300->data) 164088095e7bSTony Olech usb_sg_cancel(&vub300->sg_request); 164188095e7bSTony Olech } else if (vub300->resp.common.header_type == RESPONSE_PIGGYBACKED) { 164288095e7bSTony Olech int offloaded_data_length = 164388095e7bSTony Olech vub300->resp.common.header_size - 164488095e7bSTony Olech sizeof(struct sd_register_header); 164588095e7bSTony Olech int register_count = offloaded_data_length >> 3; 164688095e7bSTony Olech int ri = 0; 164788095e7bSTony Olech while (register_count--) { 164888095e7bSTony Olech add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]); 164988095e7bSTony Olech ri += 1; 165088095e7bSTony Olech } 165188095e7bSTony Olech vub300->resp.common.header_size = 165288095e7bSTony Olech sizeof(struct sd_register_header); 165388095e7bSTony Olech vub300->resp.common.header_type = 0x00; 165488095e7bSTony Olech cmd->error = 0; 165588095e7bSTony Olech } else if (vub300->resp.common.header_type == RESPONSE_PIG_DISABLED) { 165688095e7bSTony Olech int offloaded_data_length = 165788095e7bSTony Olech vub300->resp.common.header_size - 165888095e7bSTony Olech sizeof(struct sd_register_header); 165988095e7bSTony Olech int register_count = offloaded_data_length >> 3; 166088095e7bSTony Olech int ri = 0; 166188095e7bSTony Olech while (register_count--) { 166288095e7bSTony Olech add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]); 166388095e7bSTony Olech ri += 1; 166488095e7bSTony Olech } 166588095e7bSTony Olech mutex_lock(&vub300->irq_mutex); 166688095e7bSTony Olech if (vub300->irqs_queued) { 166788095e7bSTony Olech vub300->irqs_queued += 1; 166888095e7bSTony Olech } else if (vub300->irq_enabled) { 166988095e7bSTony Olech vub300->irqs_queued += 1; 167088095e7bSTony Olech vub300_queue_poll_work(vub300, 0); 167188095e7bSTony Olech } else { 167288095e7bSTony Olech vub300->irqs_queued += 1; 167388095e7bSTony Olech } 167488095e7bSTony Olech vub300->irq_disabled = 1; 167588095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 167688095e7bSTony Olech vub300->resp.common.header_size = 167788095e7bSTony Olech sizeof(struct sd_register_header); 167888095e7bSTony Olech vub300->resp.common.header_type = 0x00; 167988095e7bSTony Olech cmd->error = 0; 168088095e7bSTony Olech } else if (vub300->resp.common.header_type == RESPONSE_PIG_ENABLED) { 168188095e7bSTony Olech int offloaded_data_length = 168288095e7bSTony Olech vub300->resp.common.header_size - 168388095e7bSTony Olech sizeof(struct sd_register_header); 168488095e7bSTony Olech int register_count = offloaded_data_length >> 3; 168588095e7bSTony Olech int ri = 0; 168688095e7bSTony Olech while (register_count--) { 168788095e7bSTony Olech add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]); 168888095e7bSTony Olech ri += 1; 168988095e7bSTony Olech } 169088095e7bSTony Olech mutex_lock(&vub300->irq_mutex); 169188095e7bSTony Olech if (vub300->irqs_queued) { 169288095e7bSTony Olech vub300->irqs_queued += 1; 169388095e7bSTony Olech } else if (vub300->irq_enabled) { 169488095e7bSTony Olech vub300->irqs_queued += 1; 169588095e7bSTony Olech vub300_queue_poll_work(vub300, 0); 169688095e7bSTony Olech } else { 169788095e7bSTony Olech vub300->irqs_queued += 1; 169888095e7bSTony Olech } 169988095e7bSTony Olech vub300->irq_disabled = 0; 170088095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 170188095e7bSTony Olech vub300->resp.common.header_size = 170288095e7bSTony Olech sizeof(struct sd_register_header); 170388095e7bSTony Olech vub300->resp.common.header_type = 0x00; 170488095e7bSTony Olech cmd->error = 0; 170588095e7bSTony Olech } else { 170688095e7bSTony Olech cmd->error = -EINVAL; 170788095e7bSTony Olech } 170888095e7bSTony Olech } 170988095e7bSTony Olech 171088095e7bSTony Olech static void construct_request_response(struct vub300_mmc_host *vub300, 171188095e7bSTony Olech struct mmc_command *cmd) 171288095e7bSTony Olech { 171388095e7bSTony Olech int resp_len = vub300->resp_len; 171488095e7bSTony Olech int less_cmd = (17 == resp_len) ? resp_len : resp_len - 1; 171588095e7bSTony Olech int bytes = 3 & less_cmd; 171688095e7bSTony Olech int words = less_cmd >> 2; 171788095e7bSTony Olech u8 *r = vub300->resp.response.command_response; 171888095e7bSTony Olech if (bytes == 3) { 171988095e7bSTony Olech cmd->resp[words] = (r[1 + (words << 2)] << 24) 172088095e7bSTony Olech | (r[2 + (words << 2)] << 16) 172188095e7bSTony Olech | (r[3 + (words << 2)] << 8); 172288095e7bSTony Olech } else if (bytes == 2) { 172388095e7bSTony Olech cmd->resp[words] = (r[1 + (words << 2)] << 24) 172488095e7bSTony Olech | (r[2 + (words << 2)] << 16); 172588095e7bSTony Olech } else if (bytes == 1) { 172688095e7bSTony Olech cmd->resp[words] = (r[1 + (words << 2)] << 24); 172788095e7bSTony Olech } 172888095e7bSTony Olech while (words-- > 0) { 172988095e7bSTony Olech cmd->resp[words] = (r[1 + (words << 2)] << 24) 173088095e7bSTony Olech | (r[2 + (words << 2)] << 16) 173188095e7bSTony Olech | (r[3 + (words << 2)] << 8) 173288095e7bSTony Olech | (r[4 + (words << 2)] << 0); 173388095e7bSTony Olech } 173488095e7bSTony Olech if ((cmd->opcode == 53) && (0x000000FF & cmd->resp[0])) 173588095e7bSTony Olech cmd->resp[0] &= 0xFFFFFF00; 173688095e7bSTony Olech } 173788095e7bSTony Olech 173888095e7bSTony Olech /* this thread runs only when there is an upper level command req outstanding */ 173988095e7bSTony Olech static void vub300_cmndwork_thread(struct work_struct *work) 174088095e7bSTony Olech { 174188095e7bSTony Olech struct vub300_mmc_host *vub300 = 174288095e7bSTony Olech container_of(work, struct vub300_mmc_host, cmndwork); 174388095e7bSTony Olech if (!vub300->interface) { 174488095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 174588095e7bSTony Olech return; 174688095e7bSTony Olech } else { 174788095e7bSTony Olech struct mmc_request *req = vub300->req; 174888095e7bSTony Olech struct mmc_command *cmd = vub300->cmd; 174988095e7bSTony Olech struct mmc_data *data = vub300->data; 175088095e7bSTony Olech int data_length; 175188095e7bSTony Olech mutex_lock(&vub300->cmd_mutex); 175288095e7bSTony Olech init_completion(&vub300->command_complete); 17532e4af7b6SUlf Hansson if (likely(vub300->vub_name[0]) || !vub300->mmc->card) { 175488095e7bSTony Olech /* 175588095e7bSTony Olech * the name of the EMPTY Pseudo firmware file 175688095e7bSTony Olech * is used as a flag to indicate that the file 175788095e7bSTony Olech * has been already downloaded to the VUB300 chip 175888095e7bSTony Olech */ 175988095e7bSTony Olech } else if (0 == vub300->mmc->card->sdio_funcs) { 176088095e7bSTony Olech strncpy(vub300->vub_name, "SD memory device", 176188095e7bSTony Olech sizeof(vub300->vub_name)); 176288095e7bSTony Olech } else { 176388095e7bSTony Olech download_offload_pseudocode(vub300); 176488095e7bSTony Olech } 176588095e7bSTony Olech send_command(vub300); 176688095e7bSTony Olech if (!data) 176788095e7bSTony Olech data_length = 0; 176888095e7bSTony Olech else if (MMC_DATA_READ & data->flags) 176988095e7bSTony Olech data_length = __command_read_data(vub300, cmd, data); 177088095e7bSTony Olech else 177188095e7bSTony Olech data_length = __command_write_data(vub300, cmd, data); 177288095e7bSTony Olech __vub300_command_response(vub300, cmd, data, data_length); 177388095e7bSTony Olech vub300->req = NULL; 177488095e7bSTony Olech vub300->cmd = NULL; 177588095e7bSTony Olech vub300->data = NULL; 177688095e7bSTony Olech if (cmd->error) { 177788095e7bSTony Olech if (cmd->error == -ENOMEDIUM) 177888095e7bSTony Olech check_vub300_port_status(vub300); 177988095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 178088095e7bSTony Olech mmc_request_done(vub300->mmc, req); 178188095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 178288095e7bSTony Olech return; 178388095e7bSTony Olech } else { 178488095e7bSTony Olech construct_request_response(vub300, cmd); 178588095e7bSTony Olech vub300->resp_len = 0; 178688095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 178788095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 178888095e7bSTony Olech mmc_request_done(vub300->mmc, req); 178988095e7bSTony Olech return; 179088095e7bSTony Olech } 179188095e7bSTony Olech } 179288095e7bSTony Olech } 179388095e7bSTony Olech 179488095e7bSTony Olech static int examine_cyclic_buffer(struct vub300_mmc_host *vub300, 179588095e7bSTony Olech struct mmc_command *cmd, u8 Function) 179688095e7bSTony Olech { 179788095e7bSTony Olech /* cmd_mutex is held by vub300_mmc_request */ 179888095e7bSTony Olech u8 cmd0 = 0xFF & (cmd->arg >> 24); 179988095e7bSTony Olech u8 cmd1 = 0xFF & (cmd->arg >> 16); 180088095e7bSTony Olech u8 cmd2 = 0xFF & (cmd->arg >> 8); 180188095e7bSTony Olech u8 cmd3 = 0xFF & (cmd->arg >> 0); 180288095e7bSTony Olech int first = MAXREGMASK & vub300->fn[Function].offload_point; 180388095e7bSTony Olech struct offload_registers_access *rf = &vub300->fn[Function].reg[first]; 180488095e7bSTony Olech if (cmd0 == rf->command_byte[0] && 180588095e7bSTony Olech cmd1 == rf->command_byte[1] && 180688095e7bSTony Olech cmd2 == rf->command_byte[2] && 180788095e7bSTony Olech cmd3 == rf->command_byte[3]) { 180888095e7bSTony Olech u8 checksum = 0x00; 180988095e7bSTony Olech cmd->resp[1] = checksum << 24; 181088095e7bSTony Olech cmd->resp[0] = (rf->Respond_Byte[0] << 24) 181188095e7bSTony Olech | (rf->Respond_Byte[1] << 16) 181288095e7bSTony Olech | (rf->Respond_Byte[2] << 8) 181388095e7bSTony Olech | (rf->Respond_Byte[3] << 0); 181488095e7bSTony Olech vub300->fn[Function].offload_point += 1; 181588095e7bSTony Olech vub300->fn[Function].offload_count -= 1; 181688095e7bSTony Olech vub300->total_offload_count -= 1; 181788095e7bSTony Olech return 1; 181888095e7bSTony Olech } else { 181988095e7bSTony Olech int delta = 1; /* because it does not match the first one */ 182088095e7bSTony Olech u8 register_count = vub300->fn[Function].offload_count - 1; 182188095e7bSTony Olech u32 register_point = vub300->fn[Function].offload_point + 1; 182288095e7bSTony Olech while (0 < register_count) { 182388095e7bSTony Olech int point = MAXREGMASK & register_point; 182488095e7bSTony Olech struct offload_registers_access *r = 182588095e7bSTony Olech &vub300->fn[Function].reg[point]; 182688095e7bSTony Olech if (cmd0 == r->command_byte[0] && 182788095e7bSTony Olech cmd1 == r->command_byte[1] && 182888095e7bSTony Olech cmd2 == r->command_byte[2] && 182988095e7bSTony Olech cmd3 == r->command_byte[3]) { 183088095e7bSTony Olech u8 checksum = 0x00; 183188095e7bSTony Olech cmd->resp[1] = checksum << 24; 183288095e7bSTony Olech cmd->resp[0] = (r->Respond_Byte[0] << 24) 183388095e7bSTony Olech | (r->Respond_Byte[1] << 16) 183488095e7bSTony Olech | (r->Respond_Byte[2] << 8) 183588095e7bSTony Olech | (r->Respond_Byte[3] << 0); 183688095e7bSTony Olech vub300->fn[Function].offload_point += delta; 183788095e7bSTony Olech vub300->fn[Function].offload_count -= delta; 183888095e7bSTony Olech vub300->total_offload_count -= delta; 183988095e7bSTony Olech return 1; 184088095e7bSTony Olech } else { 184188095e7bSTony Olech register_point += 1; 184288095e7bSTony Olech register_count -= 1; 184388095e7bSTony Olech delta += 1; 184488095e7bSTony Olech continue; 184588095e7bSTony Olech } 184688095e7bSTony Olech } 184788095e7bSTony Olech return 0; 184888095e7bSTony Olech } 184988095e7bSTony Olech } 185088095e7bSTony Olech 185188095e7bSTony Olech static int satisfy_request_from_offloaded_data(struct vub300_mmc_host *vub300, 185288095e7bSTony Olech struct mmc_command *cmd) 185388095e7bSTony Olech { 185488095e7bSTony Olech /* cmd_mutex is held by vub300_mmc_request */ 185588095e7bSTony Olech u8 regs = vub300->dynamic_register_count; 185688095e7bSTony Olech u8 i = 0; 185788095e7bSTony Olech u8 func = FUN(cmd); 185888095e7bSTony Olech u32 reg = REG(cmd); 185988095e7bSTony Olech while (0 < regs--) { 186088095e7bSTony Olech if ((vub300->sdio_register[i].func_num == func) && 186188095e7bSTony Olech (vub300->sdio_register[i].sdio_reg == reg)) { 186288095e7bSTony Olech if (!vub300->sdio_register[i].prepared) { 186388095e7bSTony Olech return 0; 186488095e7bSTony Olech } else if ((0x80000000 & cmd->arg) == 0x80000000) { 186588095e7bSTony Olech /* 186688095e7bSTony Olech * a write to a dynamic register 186788095e7bSTony Olech * nullifies our offloaded value 186888095e7bSTony Olech */ 186988095e7bSTony Olech vub300->sdio_register[i].prepared = 0; 187088095e7bSTony Olech return 0; 187188095e7bSTony Olech } else { 187288095e7bSTony Olech u8 checksum = 0x00; 187388095e7bSTony Olech u8 rsp0 = 0x00; 187488095e7bSTony Olech u8 rsp1 = 0x00; 187588095e7bSTony Olech u8 rsp2 = vub300->sdio_register[i].response; 187688095e7bSTony Olech u8 rsp3 = vub300->sdio_register[i].regvalue; 187788095e7bSTony Olech vub300->sdio_register[i].prepared = 0; 187888095e7bSTony Olech cmd->resp[1] = checksum << 24; 187988095e7bSTony Olech cmd->resp[0] = (rsp0 << 24) 188088095e7bSTony Olech | (rsp1 << 16) 188188095e7bSTony Olech | (rsp2 << 8) 188288095e7bSTony Olech | (rsp3 << 0); 188388095e7bSTony Olech return 1; 188488095e7bSTony Olech } 188588095e7bSTony Olech } else { 188688095e7bSTony Olech i += 1; 188788095e7bSTony Olech continue; 188888095e7bSTony Olech } 18897eece8d0SJavier Martinez Canillas } 189088095e7bSTony Olech if (vub300->total_offload_count == 0) 189188095e7bSTony Olech return 0; 189288095e7bSTony Olech else if (vub300->fn[func].offload_count == 0) 189388095e7bSTony Olech return 0; 189488095e7bSTony Olech else 189588095e7bSTony Olech return examine_cyclic_buffer(vub300, cmd, func); 189688095e7bSTony Olech } 189788095e7bSTony Olech 189888095e7bSTony Olech static void vub300_mmc_request(struct mmc_host *mmc, struct mmc_request *req) 189988095e7bSTony Olech { /* NOT irq */ 190088095e7bSTony Olech struct mmc_command *cmd = req->cmd; 190188095e7bSTony Olech struct vub300_mmc_host *vub300 = mmc_priv(mmc); 190288095e7bSTony Olech if (!vub300->interface) { 190388095e7bSTony Olech cmd->error = -ESHUTDOWN; 190488095e7bSTony Olech mmc_request_done(mmc, req); 190588095e7bSTony Olech return; 190688095e7bSTony Olech } else { 190788095e7bSTony Olech struct mmc_data *data = req->data; 190888095e7bSTony Olech if (!vub300->card_powered) { 190988095e7bSTony Olech cmd->error = -ENOMEDIUM; 191088095e7bSTony Olech mmc_request_done(mmc, req); 191188095e7bSTony Olech return; 191288095e7bSTony Olech } 191388095e7bSTony Olech if (!vub300->card_present) { 191488095e7bSTony Olech cmd->error = -ENOMEDIUM; 191588095e7bSTony Olech mmc_request_done(mmc, req); 191688095e7bSTony Olech return; 191788095e7bSTony Olech } 191888095e7bSTony Olech if (vub300->usb_transport_fail) { 191988095e7bSTony Olech cmd->error = vub300->usb_transport_fail; 192088095e7bSTony Olech mmc_request_done(mmc, req); 192188095e7bSTony Olech return; 192288095e7bSTony Olech } 192388095e7bSTony Olech if (!vub300->interface) { 192488095e7bSTony Olech cmd->error = -ENODEV; 192588095e7bSTony Olech mmc_request_done(mmc, req); 192688095e7bSTony Olech return; 192788095e7bSTony Olech } 192888095e7bSTony Olech kref_get(&vub300->kref); 192988095e7bSTony Olech mutex_lock(&vub300->cmd_mutex); 193088095e7bSTony Olech mod_timer(&vub300->inactivity_timer, jiffies + HZ); 193188095e7bSTony Olech /* 193288095e7bSTony Olech * for performance we have to return immediately 193388095e7bSTony Olech * if the requested data has been offloaded 193488095e7bSTony Olech */ 193588095e7bSTony Olech if (cmd->opcode == 52 && 193688095e7bSTony Olech satisfy_request_from_offloaded_data(vub300, cmd)) { 193788095e7bSTony Olech cmd->error = 0; 193888095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 193988095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 194088095e7bSTony Olech mmc_request_done(mmc, req); 194188095e7bSTony Olech return; 194288095e7bSTony Olech } else { 194388095e7bSTony Olech vub300->cmd = cmd; 194488095e7bSTony Olech vub300->req = req; 194588095e7bSTony Olech vub300->data = data; 194688095e7bSTony Olech if (data) 194788095e7bSTony Olech vub300->datasize = data->blksz * data->blocks; 194888095e7bSTony Olech else 194988095e7bSTony Olech vub300->datasize = 0; 195088095e7bSTony Olech vub300_queue_cmnd_work(vub300); 195188095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 195288095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 195388095e7bSTony Olech /* 195488095e7bSTony Olech * the kernel lock diagnostics complain 195588095e7bSTony Olech * if the cmd_mutex * is "passed on" 195688095e7bSTony Olech * to the cmndwork thread, 195788095e7bSTony Olech * so we must release it now 195888095e7bSTony Olech * and re-acquire it in the cmndwork thread 195988095e7bSTony Olech */ 196088095e7bSTony Olech } 196188095e7bSTony Olech } 196288095e7bSTony Olech } 196388095e7bSTony Olech 196488095e7bSTony Olech static void __set_clock_speed(struct vub300_mmc_host *vub300, u8 buf[8], 196588095e7bSTony Olech struct mmc_ios *ios) 196688095e7bSTony Olech { 196788095e7bSTony Olech int buf_array_size = 8; /* ARRAY_SIZE(buf) does not work !!! */ 196888095e7bSTony Olech int retval; 196988095e7bSTony Olech u32 kHzClock; 197088095e7bSTony Olech if (ios->clock >= 48000000) 197188095e7bSTony Olech kHzClock = 48000; 197288095e7bSTony Olech else if (ios->clock >= 24000000) 197388095e7bSTony Olech kHzClock = 24000; 197488095e7bSTony Olech else if (ios->clock >= 20000000) 197588095e7bSTony Olech kHzClock = 20000; 197688095e7bSTony Olech else if (ios->clock >= 15000000) 197788095e7bSTony Olech kHzClock = 15000; 197888095e7bSTony Olech else if (ios->clock >= 200000) 197988095e7bSTony Olech kHzClock = 200; 198088095e7bSTony Olech else 198188095e7bSTony Olech kHzClock = 0; 198288095e7bSTony Olech { 198388095e7bSTony Olech int i; 198488095e7bSTony Olech u64 c = kHzClock; 198588095e7bSTony Olech for (i = 0; i < buf_array_size; i++) { 198688095e7bSTony Olech buf[i] = c; 198788095e7bSTony Olech c >>= 8; 198888095e7bSTony Olech } 198988095e7bSTony Olech } 199088095e7bSTony Olech retval = 199188095e7bSTony Olech usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), 199288095e7bSTony Olech SET_CLOCK_SPEED, 199388095e7bSTony Olech USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 199488095e7bSTony Olech 0x00, 0x00, buf, buf_array_size, HZ); 199588095e7bSTony Olech if (retval != 8) { 199688095e7bSTony Olech dev_err(&vub300->udev->dev, "SET_CLOCK_SPEED" 199788095e7bSTony Olech " %dkHz failed with retval=%d\n", kHzClock, retval); 199888095e7bSTony Olech } else { 199988095e7bSTony Olech dev_dbg(&vub300->udev->dev, "SET_CLOCK_SPEED" 200088095e7bSTony Olech " %dkHz\n", kHzClock); 200188095e7bSTony Olech } 200288095e7bSTony Olech } 200388095e7bSTony Olech 200488095e7bSTony Olech static void vub300_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 200588095e7bSTony Olech { /* NOT irq */ 200688095e7bSTony Olech struct vub300_mmc_host *vub300 = mmc_priv(mmc); 200788095e7bSTony Olech if (!vub300->interface) 200888095e7bSTony Olech return; 200988095e7bSTony Olech kref_get(&vub300->kref); 201088095e7bSTony Olech mutex_lock(&vub300->cmd_mutex); 201188095e7bSTony Olech if ((ios->power_mode == MMC_POWER_OFF) && vub300->card_powered) { 201288095e7bSTony Olech vub300->card_powered = 0; 201388095e7bSTony Olech usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), 201488095e7bSTony Olech SET_SD_POWER, 201588095e7bSTony Olech USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 201688095e7bSTony Olech 0x0000, 0x0000, NULL, 0, HZ); 201788095e7bSTony Olech /* must wait for the VUB300 u-proc to boot up */ 201888095e7bSTony Olech msleep(600); 201988095e7bSTony Olech } else if ((ios->power_mode == MMC_POWER_UP) && !vub300->card_powered) { 202088095e7bSTony Olech usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), 202188095e7bSTony Olech SET_SD_POWER, 202288095e7bSTony Olech USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 202388095e7bSTony Olech 0x0001, 0x0000, NULL, 0, HZ); 202488095e7bSTony Olech msleep(600); 202588095e7bSTony Olech vub300->card_powered = 1; 202688095e7bSTony Olech } else if (ios->power_mode == MMC_POWER_ON) { 202788095e7bSTony Olech u8 *buf = kmalloc(8, GFP_KERNEL); 202888095e7bSTony Olech if (buf) { 202988095e7bSTony Olech __set_clock_speed(vub300, buf, ios); 203088095e7bSTony Olech kfree(buf); 203188095e7bSTony Olech } 203288095e7bSTony Olech } else { 203388095e7bSTony Olech /* this should mean no change of state */ 203488095e7bSTony Olech } 203588095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 203688095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 203788095e7bSTony Olech } 203888095e7bSTony Olech 203988095e7bSTony Olech static int vub300_mmc_get_ro(struct mmc_host *mmc) 204088095e7bSTony Olech { 204188095e7bSTony Olech struct vub300_mmc_host *vub300 = mmc_priv(mmc); 204288095e7bSTony Olech return vub300->read_only; 204388095e7bSTony Olech } 204488095e7bSTony Olech 204588095e7bSTony Olech static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable) 204688095e7bSTony Olech { /* NOT irq */ 204788095e7bSTony Olech struct vub300_mmc_host *vub300 = mmc_priv(mmc); 204888095e7bSTony Olech if (!vub300->interface) 204988095e7bSTony Olech return; 205088095e7bSTony Olech kref_get(&vub300->kref); 205188095e7bSTony Olech if (enable) { 205288095e7bSTony Olech mutex_lock(&vub300->irq_mutex); 205388095e7bSTony Olech if (vub300->irqs_queued) { 205488095e7bSTony Olech vub300->irqs_queued -= 1; 205588095e7bSTony Olech mmc_signal_sdio_irq(vub300->mmc); 205688095e7bSTony Olech } else if (vub300->irq_disabled) { 205788095e7bSTony Olech vub300->irq_disabled = 0; 205888095e7bSTony Olech vub300->irq_enabled = 1; 205988095e7bSTony Olech vub300_queue_poll_work(vub300, 0); 206088095e7bSTony Olech } else if (vub300->irq_enabled) { 206188095e7bSTony Olech /* this should not happen, so we will just ignore it */ 206288095e7bSTony Olech } else { 206388095e7bSTony Olech vub300->irq_enabled = 1; 206488095e7bSTony Olech vub300_queue_poll_work(vub300, 0); 206588095e7bSTony Olech } 206688095e7bSTony Olech mutex_unlock(&vub300->irq_mutex); 206788095e7bSTony Olech } else { 206888095e7bSTony Olech vub300->irq_enabled = 0; 206988095e7bSTony Olech } 207088095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 207188095e7bSTony Olech } 207288095e7bSTony Olech 2073e6fa577bSJulia Lawall static const struct mmc_host_ops vub300_mmc_ops = { 207488095e7bSTony Olech .request = vub300_mmc_request, 207588095e7bSTony Olech .set_ios = vub300_mmc_set_ios, 207688095e7bSTony Olech .get_ro = vub300_mmc_get_ro, 207788095e7bSTony Olech .enable_sdio_irq = vub300_enable_sdio_irq, 207888095e7bSTony Olech }; 207988095e7bSTony Olech 208088095e7bSTony Olech static int vub300_probe(struct usb_interface *interface, 208188095e7bSTony Olech const struct usb_device_id *id) 208288095e7bSTony Olech { /* NOT irq */ 2083c44048deSChris Ball struct vub300_mmc_host *vub300; 208488095e7bSTony Olech struct usb_host_interface *iface_desc; 208588095e7bSTony Olech struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface)); 208688095e7bSTony Olech int i; 208788095e7bSTony Olech int retval = -ENOMEM; 208888095e7bSTony Olech struct urb *command_out_urb; 208988095e7bSTony Olech struct urb *command_res_urb; 209088095e7bSTony Olech struct mmc_host *mmc; 209188095e7bSTony Olech char manufacturer[48]; 209288095e7bSTony Olech char product[32]; 209388095e7bSTony Olech char serial_number[32]; 209488095e7bSTony Olech usb_string(udev, udev->descriptor.iManufacturer, manufacturer, 209588095e7bSTony Olech sizeof(manufacturer)); 209688095e7bSTony Olech usb_string(udev, udev->descriptor.iProduct, product, sizeof(product)); 209788095e7bSTony Olech usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 209888095e7bSTony Olech sizeof(serial_number)); 209988095e7bSTony Olech dev_info(&udev->dev, "probing VID:PID(%04X:%04X) %s %s %s\n", 2100dada0194SJohan Hovold le16_to_cpu(udev->descriptor.idVendor), 2101dada0194SJohan Hovold le16_to_cpu(udev->descriptor.idProduct), 210288095e7bSTony Olech manufacturer, product, serial_number); 210388095e7bSTony Olech command_out_urb = usb_alloc_urb(0, GFP_KERNEL); 210488095e7bSTony Olech if (!command_out_urb) { 210588095e7bSTony Olech retval = -ENOMEM; 210688095e7bSTony Olech goto error0; 210788095e7bSTony Olech } 210888095e7bSTony Olech command_res_urb = usb_alloc_urb(0, GFP_KERNEL); 210988095e7bSTony Olech if (!command_res_urb) { 211088095e7bSTony Olech retval = -ENOMEM; 211188095e7bSTony Olech goto error1; 211288095e7bSTony Olech } 211388095e7bSTony Olech /* this also allocates memory for our VUB300 mmc host device */ 211488095e7bSTony Olech mmc = mmc_alloc_host(sizeof(struct vub300_mmc_host), &udev->dev); 211588095e7bSTony Olech if (!mmc) { 211688095e7bSTony Olech retval = -ENOMEM; 2117c44048deSChris Ball dev_err(&udev->dev, "not enough memory for the mmc_host\n"); 211888095e7bSTony Olech goto error4; 211988095e7bSTony Olech } 212088095e7bSTony Olech /* MMC core transfer sizes tunable parameters */ 212188095e7bSTony Olech mmc->caps = 0; 212288095e7bSTony Olech if (!force_1_bit_data_xfers) 212388095e7bSTony Olech mmc->caps |= MMC_CAP_4_BIT_DATA; 212488095e7bSTony Olech if (!force_polling_for_irqs) 212588095e7bSTony Olech mmc->caps |= MMC_CAP_SDIO_IRQ; 212688095e7bSTony Olech mmc->caps &= ~MMC_CAP_NEEDS_POLL; 212788095e7bSTony Olech /* 212888095e7bSTony Olech * MMC_CAP_NEEDS_POLL causes core.c:mmc_rescan() to poll 212988095e7bSTony Olech * for devices which results in spurious CMD7's being 213088095e7bSTony Olech * issued which stops some SDIO cards from working 213188095e7bSTony Olech */ 213288095e7bSTony Olech if (limit_speed_to_24_MHz) { 213388095e7bSTony Olech mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 213488095e7bSTony Olech mmc->caps |= MMC_CAP_SD_HIGHSPEED; 213588095e7bSTony Olech mmc->f_max = 24000000; 213688095e7bSTony Olech dev_info(&udev->dev, "limiting SDIO speed to 24_MHz\n"); 213788095e7bSTony Olech } else { 213888095e7bSTony Olech mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 213988095e7bSTony Olech mmc->caps |= MMC_CAP_SD_HIGHSPEED; 214088095e7bSTony Olech mmc->f_max = 48000000; 214188095e7bSTony Olech } 214288095e7bSTony Olech mmc->f_min = 200000; 214388095e7bSTony Olech mmc->max_blk_count = 511; 214488095e7bSTony Olech mmc->max_blk_size = 512; 214588095e7bSTony Olech mmc->max_segs = 128; 214688095e7bSTony Olech if (force_max_req_size) 214788095e7bSTony Olech mmc->max_req_size = force_max_req_size * 1024; 214888095e7bSTony Olech else 214988095e7bSTony Olech mmc->max_req_size = 64 * 1024; 215088095e7bSTony Olech mmc->max_seg_size = mmc->max_req_size; 215188095e7bSTony Olech mmc->ocr_avail = 0; 215288095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_165_195; 215388095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_20_21; 215488095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_21_22; 215588095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_22_23; 215688095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_23_24; 215788095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_24_25; 215888095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_25_26; 215988095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_26_27; 216088095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_27_28; 216188095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_28_29; 216288095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_29_30; 216388095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_30_31; 216488095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_31_32; 216588095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_32_33; 216688095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_33_34; 216788095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_34_35; 216888095e7bSTony Olech mmc->ocr_avail |= MMC_VDD_35_36; 216988095e7bSTony Olech mmc->ops = &vub300_mmc_ops; 217088095e7bSTony Olech vub300 = mmc_priv(mmc); 217188095e7bSTony Olech vub300->mmc = mmc; 217288095e7bSTony Olech vub300->card_powered = 0; 217388095e7bSTony Olech vub300->bus_width = 0; 217488095e7bSTony Olech vub300->cmnd.head.block_size[0] = 0x00; 217588095e7bSTony Olech vub300->cmnd.head.block_size[1] = 0x00; 217688095e7bSTony Olech vub300->app_spec = 0; 217788095e7bSTony Olech mutex_init(&vub300->cmd_mutex); 217888095e7bSTony Olech mutex_init(&vub300->irq_mutex); 217988095e7bSTony Olech vub300->command_out_urb = command_out_urb; 218088095e7bSTony Olech vub300->command_res_urb = command_res_urb; 218188095e7bSTony Olech vub300->usb_timed_out = 0; 218288095e7bSTony Olech vub300->dynamic_register_count = 0; 218388095e7bSTony Olech 218488095e7bSTony Olech for (i = 0; i < ARRAY_SIZE(vub300->fn); i++) { 218588095e7bSTony Olech vub300->fn[i].offload_point = 0; 218688095e7bSTony Olech vub300->fn[i].offload_count = 0; 218788095e7bSTony Olech } 218888095e7bSTony Olech 218988095e7bSTony Olech vub300->total_offload_count = 0; 219088095e7bSTony Olech vub300->irq_enabled = 0; 219188095e7bSTony Olech vub300->irq_disabled = 0; 219288095e7bSTony Olech vub300->irqs_queued = 0; 219388095e7bSTony Olech 219488095e7bSTony Olech for (i = 0; i < ARRAY_SIZE(vub300->sdio_register); i++) 219588095e7bSTony Olech vub300->sdio_register[i++].activate = 0; 219688095e7bSTony Olech 219788095e7bSTony Olech vub300->udev = udev; 219888095e7bSTony Olech vub300->interface = interface; 219988095e7bSTony Olech vub300->cmnd_res_ep = 0; 220088095e7bSTony Olech vub300->cmnd_out_ep = 0; 220188095e7bSTony Olech vub300->data_inp_ep = 0; 220288095e7bSTony Olech vub300->data_out_ep = 0; 220388095e7bSTony Olech 220488095e7bSTony Olech for (i = 0; i < ARRAY_SIZE(vub300->fbs); i++) 220588095e7bSTony Olech vub300->fbs[i] = 512; 220688095e7bSTony Olech 220788095e7bSTony Olech /* 220888095e7bSTony Olech * set up the endpoint information 220988095e7bSTony Olech * 221088095e7bSTony Olech * use the first pair of bulk-in and bulk-out 221188095e7bSTony Olech * endpoints for Command/Response+Interrupt 221288095e7bSTony Olech * 221388095e7bSTony Olech * use the second pair of bulk-in and bulk-out 221488095e7bSTony Olech * endpoints for Data In/Out 221588095e7bSTony Olech */ 221688095e7bSTony Olech vub300->large_usb_packets = 0; 221788095e7bSTony Olech iface_desc = interface->cur_altsetting; 221888095e7bSTony Olech for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 221988095e7bSTony Olech struct usb_endpoint_descriptor *endpoint = 222088095e7bSTony Olech &iface_desc->endpoint[i].desc; 222188095e7bSTony Olech dev_info(&vub300->udev->dev, 222288095e7bSTony Olech "vub300 testing %s EndPoint(%d) %02X\n", 222388095e7bSTony Olech usb_endpoint_is_bulk_in(endpoint) ? "BULK IN" : 222488095e7bSTony Olech usb_endpoint_is_bulk_out(endpoint) ? "BULK OUT" : 222588095e7bSTony Olech "UNKNOWN", i, endpoint->bEndpointAddress); 222688095e7bSTony Olech if (endpoint->wMaxPacketSize > 64) 222788095e7bSTony Olech vub300->large_usb_packets = 1; 222888095e7bSTony Olech if (usb_endpoint_is_bulk_in(endpoint)) { 222988095e7bSTony Olech if (!vub300->cmnd_res_ep) { 223088095e7bSTony Olech vub300->cmnd_res_ep = 223188095e7bSTony Olech endpoint->bEndpointAddress; 223288095e7bSTony Olech } else if (!vub300->data_inp_ep) { 223388095e7bSTony Olech vub300->data_inp_ep = 223488095e7bSTony Olech endpoint->bEndpointAddress; 223588095e7bSTony Olech } else { 223688095e7bSTony Olech dev_warn(&vub300->udev->dev, 223788095e7bSTony Olech "ignoring" 223888095e7bSTony Olech " unexpected bulk_in endpoint"); 223988095e7bSTony Olech } 224088095e7bSTony Olech } else if (usb_endpoint_is_bulk_out(endpoint)) { 224188095e7bSTony Olech if (!vub300->cmnd_out_ep) { 224288095e7bSTony Olech vub300->cmnd_out_ep = 224388095e7bSTony Olech endpoint->bEndpointAddress; 224488095e7bSTony Olech } else if (!vub300->data_out_ep) { 224588095e7bSTony Olech vub300->data_out_ep = 224688095e7bSTony Olech endpoint->bEndpointAddress; 224788095e7bSTony Olech } else { 224888095e7bSTony Olech dev_warn(&vub300->udev->dev, 224988095e7bSTony Olech "ignoring" 225088095e7bSTony Olech " unexpected bulk_out endpoint"); 225188095e7bSTony Olech } 225288095e7bSTony Olech } else { 225388095e7bSTony Olech dev_warn(&vub300->udev->dev, 225488095e7bSTony Olech "vub300 ignoring EndPoint(%d) %02X", i, 225588095e7bSTony Olech endpoint->bEndpointAddress); 225688095e7bSTony Olech } 225788095e7bSTony Olech } 225888095e7bSTony Olech if (vub300->cmnd_res_ep && vub300->cmnd_out_ep && 225988095e7bSTony Olech vub300->data_inp_ep && vub300->data_out_ep) { 226088095e7bSTony Olech dev_info(&vub300->udev->dev, 226188095e7bSTony Olech "vub300 %s packets" 226288095e7bSTony Olech " using EndPoints %02X %02X %02X %02X\n", 226388095e7bSTony Olech vub300->large_usb_packets ? "LARGE" : "SMALL", 226488095e7bSTony Olech vub300->cmnd_out_ep, vub300->cmnd_res_ep, 226588095e7bSTony Olech vub300->data_out_ep, vub300->data_inp_ep); 226688095e7bSTony Olech /* we have the expected EndPoints */ 226788095e7bSTony Olech } else { 226888095e7bSTony Olech dev_err(&vub300->udev->dev, 226988095e7bSTony Olech "Could not find two sets of bulk-in/out endpoint pairs\n"); 227088095e7bSTony Olech retval = -EINVAL; 227188095e7bSTony Olech goto error5; 227288095e7bSTony Olech } 227388095e7bSTony Olech retval = 227488095e7bSTony Olech usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), 227588095e7bSTony Olech GET_HC_INF0, 227688095e7bSTony Olech USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 227788095e7bSTony Olech 0x0000, 0x0000, &vub300->hc_info, 227888095e7bSTony Olech sizeof(vub300->hc_info), HZ); 227988095e7bSTony Olech if (retval < 0) 228088095e7bSTony Olech goto error5; 228188095e7bSTony Olech retval = 2282*3c0bb310SJohan Hovold usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), 228388095e7bSTony Olech SET_ROM_WAIT_STATES, 228488095e7bSTony Olech USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 228588095e7bSTony Olech firmware_rom_wait_states, 0x0000, NULL, 0, HZ); 228688095e7bSTony Olech if (retval < 0) 228788095e7bSTony Olech goto error5; 228888095e7bSTony Olech dev_info(&vub300->udev->dev, 228988095e7bSTony Olech "operating_mode = %s %s %d MHz %s %d byte USB packets\n", 229088095e7bSTony Olech (mmc->caps & MMC_CAP_SDIO_IRQ) ? "IRQs" : "POLL", 229188095e7bSTony Olech (mmc->caps & MMC_CAP_4_BIT_DATA) ? "4-bit" : "1-bit", 229288095e7bSTony Olech mmc->f_max / 1000000, 229388095e7bSTony Olech pad_input_to_usb_pkt ? "padding input data to" : "with", 229488095e7bSTony Olech vub300->large_usb_packets ? 512 : 64); 229588095e7bSTony Olech retval = 229688095e7bSTony Olech usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), 229788095e7bSTony Olech GET_SYSTEM_PORT_STATUS, 229888095e7bSTony Olech USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 229988095e7bSTony Olech 0x0000, 0x0000, &vub300->system_port_status, 230088095e7bSTony Olech sizeof(vub300->system_port_status), HZ); 230188095e7bSTony Olech if (retval < 0) { 230288095e7bSTony Olech goto error4; 230388095e7bSTony Olech } else if (sizeof(vub300->system_port_status) == retval) { 230488095e7bSTony Olech vub300->card_present = 230588095e7bSTony Olech (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0; 230688095e7bSTony Olech vub300->read_only = 230788095e7bSTony Olech (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0; 230888095e7bSTony Olech } else { 230988095e7bSTony Olech goto error4; 231088095e7bSTony Olech } 231188095e7bSTony Olech usb_set_intfdata(interface, vub300); 231288095e7bSTony Olech INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread); 231388095e7bSTony Olech INIT_WORK(&vub300->cmndwork, vub300_cmndwork_thread); 231488095e7bSTony Olech INIT_WORK(&vub300->deadwork, vub300_deadwork_thread); 231588095e7bSTony Olech kref_init(&vub300->kref); 23162ee4f620SKees Cook timer_setup(&vub300->sg_transfer_timer, vub300_sg_timed_out, 0); 231788095e7bSTony Olech kref_get(&vub300->kref); 23182ee4f620SKees Cook timer_setup(&vub300->inactivity_timer, 23192ee4f620SKees Cook vub300_inactivity_timer_expired, 0); 232088095e7bSTony Olech vub300->inactivity_timer.expires = jiffies + HZ; 232188095e7bSTony Olech add_timer(&vub300->inactivity_timer); 232288095e7bSTony Olech if (vub300->card_present) 232388095e7bSTony Olech dev_info(&vub300->udev->dev, 232488095e7bSTony Olech "USB vub300 remote SDIO host controller[%d]" 232588095e7bSTony Olech "connected with SD/SDIO card inserted\n", 232688095e7bSTony Olech interface_to_InterfaceNumber(interface)); 232788095e7bSTony Olech else 232888095e7bSTony Olech dev_info(&vub300->udev->dev, 232988095e7bSTony Olech "USB vub300 remote SDIO host controller[%d]" 233088095e7bSTony Olech "connected with no SD/SDIO card inserted\n", 233188095e7bSTony Olech interface_to_InterfaceNumber(interface)); 233288095e7bSTony Olech mmc_add_host(mmc); 233388095e7bSTony Olech return 0; 233488095e7bSTony Olech error5: 233588095e7bSTony Olech mmc_free_host(mmc); 233688095e7bSTony Olech /* 233788095e7bSTony Olech * and hence also frees vub300 233888095e7bSTony Olech * which is contained at the end of struct mmc 233988095e7bSTony Olech */ 234088095e7bSTony Olech error4: 234188095e7bSTony Olech usb_free_urb(command_res_urb); 23425fdb4505SJulia Lawall error1: 23435fdb4505SJulia Lawall usb_free_urb(command_out_urb); 234488095e7bSTony Olech error0: 2345063f96c2SMarina Makienko usb_put_dev(udev); 234688095e7bSTony Olech return retval; 234788095e7bSTony Olech } 234888095e7bSTony Olech 234988095e7bSTony Olech static void vub300_disconnect(struct usb_interface *interface) 235088095e7bSTony Olech { /* NOT irq */ 235188095e7bSTony Olech struct vub300_mmc_host *vub300 = usb_get_intfdata(interface); 235288095e7bSTony Olech if (!vub300 || !vub300->mmc) { 235388095e7bSTony Olech return; 235488095e7bSTony Olech } else { 235588095e7bSTony Olech struct mmc_host *mmc = vub300->mmc; 235688095e7bSTony Olech if (!vub300->mmc) { 235788095e7bSTony Olech return; 235888095e7bSTony Olech } else { 235988095e7bSTony Olech int ifnum = interface_to_InterfaceNumber(interface); 236088095e7bSTony Olech usb_set_intfdata(interface, NULL); 236188095e7bSTony Olech /* prevent more I/O from starting */ 236288095e7bSTony Olech vub300->interface = NULL; 236388095e7bSTony Olech kref_put(&vub300->kref, vub300_delete); 236488095e7bSTony Olech mmc_remove_host(mmc); 236588095e7bSTony Olech pr_info("USB vub300 remote SDIO host controller[%d]" 236688095e7bSTony Olech " now disconnected", ifnum); 236788095e7bSTony Olech return; 236888095e7bSTony Olech } 236988095e7bSTony Olech } 237088095e7bSTony Olech } 237188095e7bSTony Olech 237288095e7bSTony Olech #ifdef CONFIG_PM 237388095e7bSTony Olech static int vub300_suspend(struct usb_interface *intf, pm_message_t message) 237488095e7bSTony Olech { 237588095e7bSTony Olech return 0; 237688095e7bSTony Olech } 237788095e7bSTony Olech 237888095e7bSTony Olech static int vub300_resume(struct usb_interface *intf) 237988095e7bSTony Olech { 238088095e7bSTony Olech return 0; 238188095e7bSTony Olech } 238288095e7bSTony Olech #else 238388095e7bSTony Olech #define vub300_suspend NULL 238488095e7bSTony Olech #define vub300_resume NULL 238588095e7bSTony Olech #endif 238688095e7bSTony Olech static int vub300_pre_reset(struct usb_interface *intf) 238788095e7bSTony Olech { /* NOT irq */ 238888095e7bSTony Olech struct vub300_mmc_host *vub300 = usb_get_intfdata(intf); 238988095e7bSTony Olech mutex_lock(&vub300->cmd_mutex); 239088095e7bSTony Olech return 0; 239188095e7bSTony Olech } 239288095e7bSTony Olech 239388095e7bSTony Olech static int vub300_post_reset(struct usb_interface *intf) 239488095e7bSTony Olech { /* NOT irq */ 239588095e7bSTony Olech struct vub300_mmc_host *vub300 = usb_get_intfdata(intf); 239688095e7bSTony Olech /* we are sure no URBs are active - no locking needed */ 239788095e7bSTony Olech vub300->errors = -EPIPE; 239888095e7bSTony Olech mutex_unlock(&vub300->cmd_mutex); 239988095e7bSTony Olech return 0; 240088095e7bSTony Olech } 240188095e7bSTony Olech 240288095e7bSTony Olech static struct usb_driver vub300_driver = { 240388095e7bSTony Olech .name = "vub300", 240488095e7bSTony Olech .probe = vub300_probe, 240588095e7bSTony Olech .disconnect = vub300_disconnect, 240688095e7bSTony Olech .suspend = vub300_suspend, 240788095e7bSTony Olech .resume = vub300_resume, 240888095e7bSTony Olech .pre_reset = vub300_pre_reset, 240988095e7bSTony Olech .post_reset = vub300_post_reset, 241088095e7bSTony Olech .id_table = vub300_table, 241188095e7bSTony Olech .supports_autosuspend = 1, 241288095e7bSTony Olech }; 241388095e7bSTony Olech 241488095e7bSTony Olech static int __init vub300_init(void) 241588095e7bSTony Olech { /* NOT irq */ 241688095e7bSTony Olech int result; 241788095e7bSTony Olech 241888095e7bSTony Olech pr_info("VUB300 Driver rom wait states = %02X irqpoll timeout = %04X", 241988095e7bSTony Olech firmware_rom_wait_states, 0x0FFFF & firmware_irqpoll_timeout); 242088095e7bSTony Olech cmndworkqueue = create_singlethread_workqueue("kvub300c"); 242188095e7bSTony Olech if (!cmndworkqueue) { 242288095e7bSTony Olech pr_err("not enough memory for the REQUEST workqueue"); 242388095e7bSTony Olech result = -ENOMEM; 242488095e7bSTony Olech goto out1; 242588095e7bSTony Olech } 242688095e7bSTony Olech pollworkqueue = create_singlethread_workqueue("kvub300p"); 242788095e7bSTony Olech if (!pollworkqueue) { 242888095e7bSTony Olech pr_err("not enough memory for the IRQPOLL workqueue"); 242988095e7bSTony Olech result = -ENOMEM; 243088095e7bSTony Olech goto out2; 243188095e7bSTony Olech } 243288095e7bSTony Olech deadworkqueue = create_singlethread_workqueue("kvub300d"); 243388095e7bSTony Olech if (!deadworkqueue) { 243488095e7bSTony Olech pr_err("not enough memory for the EXPIRED workqueue"); 243588095e7bSTony Olech result = -ENOMEM; 243688095e7bSTony Olech goto out3; 243788095e7bSTony Olech } 243888095e7bSTony Olech result = usb_register(&vub300_driver); 243988095e7bSTony Olech if (result) { 244088095e7bSTony Olech pr_err("usb_register failed. Error number %d", result); 244188095e7bSTony Olech goto out4; 244288095e7bSTony Olech } 244388095e7bSTony Olech return 0; 244488095e7bSTony Olech out4: 244588095e7bSTony Olech destroy_workqueue(deadworkqueue); 244688095e7bSTony Olech out3: 244788095e7bSTony Olech destroy_workqueue(pollworkqueue); 244888095e7bSTony Olech out2: 244988095e7bSTony Olech destroy_workqueue(cmndworkqueue); 245088095e7bSTony Olech out1: 245188095e7bSTony Olech return result; 245288095e7bSTony Olech } 245388095e7bSTony Olech 245488095e7bSTony Olech static void __exit vub300_exit(void) 245588095e7bSTony Olech { 245688095e7bSTony Olech usb_deregister(&vub300_driver); 245788095e7bSTony Olech flush_workqueue(cmndworkqueue); 245888095e7bSTony Olech flush_workqueue(pollworkqueue); 245988095e7bSTony Olech flush_workqueue(deadworkqueue); 246088095e7bSTony Olech destroy_workqueue(cmndworkqueue); 246188095e7bSTony Olech destroy_workqueue(pollworkqueue); 246288095e7bSTony Olech destroy_workqueue(deadworkqueue); 246388095e7bSTony Olech } 246488095e7bSTony Olech 246588095e7bSTony Olech module_init(vub300_init); 246688095e7bSTony Olech module_exit(vub300_exit); 246788095e7bSTony Olech 246888095e7bSTony Olech MODULE_AUTHOR("Tony Olech <tony.olech@elandigitalsystems.com>"); 246988095e7bSTony Olech MODULE_DESCRIPTION("VUB300 USB to SD/MMC/SDIO adapter driver"); 247088095e7bSTony Olech MODULE_LICENSE("GPL"); 2471