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