1dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm/* Driver for Rio Karma 2dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * 3dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * (c) 2006 Bob Copeland <me@bobcopeland.com> 4dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * (c) 2006 Keith Bennett <keith@mcs.st-and.ac.uk> 5dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * 6dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * This program is free software; you can redistribute it and/or modify it 7dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * under the terms of the GNU General Public License as published by the 8dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * Free Software Foundation; either version 2, or (at your option) any 9dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * later version. 10dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * 11dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * This program is distributed in the hope that it will be useful, but 12dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * WITHOUT ANY WARRANTY; without even the implied warranty of 13dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * General Public License for more details. 15dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * 16dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * You should have received a copy of the GNU General Public License along 17dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * with this program; if not, write to the Free Software Foundation, Inc., 18dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * 675 Mass Ave, Cambridge, MA 02139, USA. 19dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm */ 20dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 21c10337846c93bd914dd3003ffb001adc583b313eAlan Stern#include <linux/module.h> 225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 23c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 24dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#include <scsi/scsi.h> 25dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#include <scsi/scsi_cmnd.h> 26dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#include <scsi/scsi_device.h> 27dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 28dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#include "usb.h" 29dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#include "transport.h" 30dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#include "debug.h" 31dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 324246b06a33ebdd6593dccaab3aa01eb0c9f8c1c8Maciej GrelaMODULE_DESCRIPTION("Driver for Rio Karma"); 334246b06a33ebdd6593dccaab3aa01eb0c9f8c1c8Maciej GrelaMODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>"); 344246b06a33ebdd6593dccaab3aa01eb0c9f8c1c8Maciej GrelaMODULE_LICENSE("GPL"); 354246b06a33ebdd6593dccaab3aa01eb0c9f8c1c8Maciej Grela 36dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#define RIO_PREFIX "RIOP\x00" 37dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#define RIO_PREFIX_LEN 5 38dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#define RIO_SEND_LEN 40 39dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#define RIO_RECV_LEN 0x200 40dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 41dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#define RIO_ENTER_STORAGE 0x1 42dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#define RIO_LEAVE_STORAGE 0x2 43dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm#define RIO_RESET 0xC 44dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 45dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharmstruct karma_data { 46dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm int in_storage; 47dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm char *recv; 48dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm}; 49dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 50c10337846c93bd914dd3003ffb001adc583b313eAlan Sternstatic int rio_karma_init(struct us_data *us); 51c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 52c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 53c10337846c93bd914dd3003ffb001adc583b313eAlan Stern/* 54c10337846c93bd914dd3003ffb001adc583b313eAlan Stern * The table of devices 55c10337846c93bd914dd3003ffb001adc583b313eAlan Stern */ 56c10337846c93bd914dd3003ffb001adc583b313eAlan Stern#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ 57c10337846c93bd914dd3003ffb001adc583b313eAlan Stern vendorName, productName, useProtocol, useTransport, \ 58c10337846c93bd914dd3003ffb001adc583b313eAlan Stern initFunction, flags) \ 59c10337846c93bd914dd3003ffb001adc583b313eAlan Stern{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ 60c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } 61c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 62f35e0d5614b9dbf76ec7b5cbd464914a77c01c88Felipe Balbistatic struct usb_device_id karma_usb_ids[] = { 63c10337846c93bd914dd3003ffb001adc583b313eAlan Stern# include "unusual_karma.h" 64c10337846c93bd914dd3003ffb001adc583b313eAlan Stern { } /* Terminating entry */ 65c10337846c93bd914dd3003ffb001adc583b313eAlan Stern}; 66c10337846c93bd914dd3003ffb001adc583b313eAlan SternMODULE_DEVICE_TABLE(usb, karma_usb_ids); 67c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 68c10337846c93bd914dd3003ffb001adc583b313eAlan Stern#undef UNUSUAL_DEV 69c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 70c10337846c93bd914dd3003ffb001adc583b313eAlan Stern/* 71c10337846c93bd914dd3003ffb001adc583b313eAlan Stern * The flags table 72c10337846c93bd914dd3003ffb001adc583b313eAlan Stern */ 73c10337846c93bd914dd3003ffb001adc583b313eAlan Stern#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ 74c10337846c93bd914dd3003ffb001adc583b313eAlan Stern vendor_name, product_name, use_protocol, use_transport, \ 75c10337846c93bd914dd3003ffb001adc583b313eAlan Stern init_function, Flags) \ 76c10337846c93bd914dd3003ffb001adc583b313eAlan Stern{ \ 77c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .vendorName = vendor_name, \ 78c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .productName = product_name, \ 79c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .useProtocol = use_protocol, \ 80c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .useTransport = use_transport, \ 81c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .initFunction = init_function, \ 82c10337846c93bd914dd3003ffb001adc583b313eAlan Stern} 83c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 84c10337846c93bd914dd3003ffb001adc583b313eAlan Sternstatic struct us_unusual_dev karma_unusual_dev_list[] = { 85c10337846c93bd914dd3003ffb001adc583b313eAlan Stern# include "unusual_karma.h" 86c10337846c93bd914dd3003ffb001adc583b313eAlan Stern { } /* Terminating entry */ 87c10337846c93bd914dd3003ffb001adc583b313eAlan Stern}; 88c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 89c10337846c93bd914dd3003ffb001adc583b313eAlan Stern#undef UNUSUAL_DEV 90c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 91c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 92dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm/* 93dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * Send commands to Rio Karma. 94dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * 95dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * For each command we send 40 bytes starting 'RIOP\0' followed by 96dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * the command number and a sequence number, which the device will ack 97dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * with a 512-byte packet with the high four bits set and everything 98dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * else null. Then we send 'RIOP\x80' followed by a zero and the 99dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * sequence number, until byte 5 in the response repeats the sequence 100dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * number. 101dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm */ 102dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharmstatic int rio_karma_send_command(char cmd, struct us_data *us) 103dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm{ 104dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm int result, partial; 105dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm unsigned long timeout; 106dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm static unsigned char seq = 1; 107dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm struct karma_data *data = (struct karma_data *) us->extra; 108dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 109dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm US_DEBUGP("karma: sending command %04x\n", cmd); 110dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm memset(us->iobuf, 0, RIO_SEND_LEN); 111dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm memcpy(us->iobuf, RIO_PREFIX, RIO_PREFIX_LEN); 112dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm us->iobuf[5] = cmd; 113dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm us->iobuf[6] = seq; 114dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 115dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm timeout = jiffies + msecs_to_jiffies(6000); 116dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm for (;;) { 117dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, 118dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm us->iobuf, RIO_SEND_LEN, &partial); 119dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (result != USB_STOR_XFER_GOOD) 120dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm goto err; 121dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 122dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, 123dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm data->recv, RIO_RECV_LEN, &partial); 124dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (result != USB_STOR_XFER_GOOD) 125dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm goto err; 126dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 127dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (data->recv[5] == seq) 128dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm break; 129dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 130dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (time_after(jiffies, timeout)) 131dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm goto err; 132dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 133dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm us->iobuf[4] = 0x80; 134dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm us->iobuf[5] = 0; 135dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm msleep(50); 136dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm } 137dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 138dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm seq++; 139dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (seq == 0) 140dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm seq = 1; 141dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 142dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm US_DEBUGP("karma: sent command %04x\n", cmd); 143dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return 0; 144dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharmerr: 145dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm US_DEBUGP("karma: command %04x failed\n", cmd); 146dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return USB_STOR_TRANSPORT_FAILED; 147dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm} 148dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 149dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm/* 150dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * Trap START_STOP and READ_10 to leave/re-enter storage mode. 151dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm * Everything else is propagated to the normal bulk layer. 152dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm */ 153c10337846c93bd914dd3003ffb001adc583b313eAlan Sternstatic int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us) 154dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm{ 155dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm int ret; 156dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm struct karma_data *data = (struct karma_data *) us->extra; 157dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 158dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (srb->cmnd[0] == READ_10 && !data->in_storage) { 159dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm ret = rio_karma_send_command(RIO_ENTER_STORAGE, us); 160dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (ret) 161dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return ret; 162dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 163dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm data->in_storage = 1; 164dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return usb_stor_Bulk_transport(srb, us); 165dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm } else if (srb->cmnd[0] == START_STOP) { 166dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm ret = rio_karma_send_command(RIO_LEAVE_STORAGE, us); 167dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (ret) 168dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return ret; 169dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 170dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm data->in_storage = 0; 171dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return rio_karma_send_command(RIO_RESET, us); 172dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm } 173dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return usb_stor_Bulk_transport(srb, us); 174dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm} 175dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 176dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharmstatic void rio_karma_destructor(void *extra) 177dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm{ 178dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm struct karma_data *data = (struct karma_data *) extra; 179dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm kfree(data->recv); 180dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm} 181dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 182c10337846c93bd914dd3003ffb001adc583b313eAlan Sternstatic int rio_karma_init(struct us_data *us) 183dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm{ 184dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm int ret = 0; 185dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); 186dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (!data) 187dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm goto out; 188dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 189dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm data->recv = kmalloc(RIO_RECV_LEN, GFP_NOIO); 190dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm if (!data->recv) { 191dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm kfree(data); 192dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm goto out; 193dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm } 194dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm 195dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm us->extra = data; 196dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm us->extra_destructor = rio_karma_destructor; 197dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm ret = rio_karma_send_command(RIO_ENTER_STORAGE, us); 198dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm data->in_storage = (ret == 0); 199dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharmout: 200dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm return ret; 201dfe0d3ba20e860d0b9a16c4c6524180b8f93be05Matthew Dharm} 202c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 203c10337846c93bd914dd3003ffb001adc583b313eAlan Sternstatic int karma_probe(struct usb_interface *intf, 204c10337846c93bd914dd3003ffb001adc583b313eAlan Stern const struct usb_device_id *id) 205c10337846c93bd914dd3003ffb001adc583b313eAlan Stern{ 206c10337846c93bd914dd3003ffb001adc583b313eAlan Stern struct us_data *us; 207c10337846c93bd914dd3003ffb001adc583b313eAlan Stern int result; 208c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 209c10337846c93bd914dd3003ffb001adc583b313eAlan Stern result = usb_stor_probe1(&us, intf, id, 210c10337846c93bd914dd3003ffb001adc583b313eAlan Stern (id - karma_usb_ids) + karma_unusual_dev_list); 211c10337846c93bd914dd3003ffb001adc583b313eAlan Stern if (result) 212c10337846c93bd914dd3003ffb001adc583b313eAlan Stern return result; 213c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 214c10337846c93bd914dd3003ffb001adc583b313eAlan Stern us->transport_name = "Rio Karma/Bulk"; 215c10337846c93bd914dd3003ffb001adc583b313eAlan Stern us->transport = rio_karma_transport; 216c10337846c93bd914dd3003ffb001adc583b313eAlan Stern us->transport_reset = usb_stor_Bulk_reset; 217c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 218c10337846c93bd914dd3003ffb001adc583b313eAlan Stern result = usb_stor_probe2(us); 219c10337846c93bd914dd3003ffb001adc583b313eAlan Stern return result; 220c10337846c93bd914dd3003ffb001adc583b313eAlan Stern} 221c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 222c10337846c93bd914dd3003ffb001adc583b313eAlan Sternstatic struct usb_driver karma_driver = { 223c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .name = "ums-karma", 224c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .probe = karma_probe, 225c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .disconnect = usb_stor_disconnect, 226c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .suspend = usb_stor_suspend, 227c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .resume = usb_stor_resume, 228c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .reset_resume = usb_stor_reset_resume, 229c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .pre_reset = usb_stor_pre_reset, 230c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .post_reset = usb_stor_post_reset, 231c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .id_table = karma_usb_ids, 232c10337846c93bd914dd3003ffb001adc583b313eAlan Stern .soft_unbind = 1, 233e73b2db6c9bc5bd9a3c080f286964e594351991aHuajun Li .no_dynamic_id = 1, 234c10337846c93bd914dd3003ffb001adc583b313eAlan Stern}; 235c10337846c93bd914dd3003ffb001adc583b313eAlan Stern 23665db43054065790a75291b0834657445fea2cf56Greg Kroah-Hartmanmodule_usb_driver(karma_driver); 237