VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / usb / image / hpusbscsi.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/sched.h>
4 #include <linux/signal.h>
5 #include <linux/errno.h>
6 #include <linux/init.h>
7 #include <linux/slab.h>
8 #include <linux/spinlock.h>
9 #include <linux/smp_lock.h>
10 #include <linux/usb.h>
11 #include <asm/atomic.h>
12 #include <linux/blkdev.h>
13 #include "../../scsi/scsi.h"
14 #include <scsi/scsi_host.h>
15
16 #include "hpusbscsi.h"
17
18 #define DEBUG(x...) \
19         printk( KERN_DEBUG x )
20
21 static char *states[]={"FREE", "BEGINNING", "WORKING", "ERROR", "WAIT", "PREMATURE"};
22
23 #define TRACE_STATE printk(KERN_DEBUG"hpusbscsi->state = %s at line %d\n", states[hpusbscsi->state], __LINE__)
24
25 static Scsi_Host_Template hpusbscsi_scsi_host_template = {
26         .module                 = THIS_MODULE,
27         .name                   = "hpusbscsi",
28         .proc_name              = "hpusbscsi",
29         .queuecommand           = hpusbscsi_scsi_queuecommand,
30         .eh_abort_handler       = hpusbscsi_scsi_abort,
31         .eh_host_reset_handler  = hpusbscsi_scsi_host_reset,
32         .sg_tablesize           = SG_ALL,
33         .can_queue              = 1,
34         .this_id                = -1,
35         .cmd_per_lun            = 1,
36         .use_clustering         = 1,
37         .emulated               = 1,
38 };
39
40 static int
41 hpusbscsi_usb_probe(struct usb_interface *intf,
42                     const struct usb_device_id *id)
43 {
44         struct usb_device *dev = interface_to_usbdev(intf);
45         struct usb_host_interface *altsetting = intf->cur_altsetting;
46         struct hpusbscsi *new;
47         int error = -ENOMEM;
48         int i;
49
50         if (altsetting->desc.bNumEndpoints != 3) {
51                 printk (KERN_ERR "Wrong number of endpoints\n");
52                 return -ENODEV;
53         }
54
55         new = kmalloc(sizeof(struct hpusbscsi), GFP_KERNEL);
56         if (!new)
57                 return -ENOMEM;
58         memset(new, 0, sizeof(struct hpusbscsi));
59         new->dataurb = usb_alloc_urb(0, GFP_KERNEL);
60         if (!new->dataurb)
61                 goto out_kfree;
62         new->controlurb = usb_alloc_urb(0, GFP_KERNEL);
63         if (!new->controlurb)
64                 goto out_free_dataurb;
65
66         new->dev = dev;
67         init_waitqueue_head(&new->pending);
68         init_waitqueue_head(&new->deathrow);
69
70         error = -ENODEV;
71         for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
72                 if ((altsetting->endpoint[i].desc.
73                      bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
74                                 USB_ENDPOINT_XFER_BULK) {
75                         if (altsetting->endpoint[i].desc.
76                             bEndpointAddress & USB_DIR_IN) {
77                                 new->ep_in =
78                                         altsetting->endpoint[i].desc.
79                                         bEndpointAddress &
80                                         USB_ENDPOINT_NUMBER_MASK;
81                         } else {
82                                 new->ep_out =
83                                         altsetting->endpoint[i].desc.
84                                         bEndpointAddress &
85                                         USB_ENDPOINT_NUMBER_MASK;
86                         }
87                 } else {
88                         new->ep_int =
89                                 altsetting->endpoint[i].desc.
90                                 bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
91                         new->interrupt_interval= altsetting->endpoint[i].desc.
92                                 bInterval;
93                 }
94         }
95
96         /* build and submit an interrupt URB for status byte handling */
97         usb_fill_int_urb(new->controlurb, new->dev,
98                         usb_rcvintpipe(new->dev, new->ep_int),
99                         &new->scsi_state_byte, 1,
100                         control_interrupt_callback,new,
101                         new->interrupt_interval);
102
103         if (usb_submit_urb(new->controlurb, GFP_KERNEL) < 0)
104                 goto out_free_controlurb;
105
106         /* In host->hostdata we store a pointer to desc */
107         new->host = scsi_host_alloc(&hpusbscsi_scsi_host_template, sizeof(new));
108         if (!new->host)
109                 goto out_unlink_controlurb;
110
111         new->host->hostdata[0] = (unsigned long)new;
112         scsi_add_host(new->host, &intf->dev); /* XXX handle failure */
113         scsi_scan_host(new->host);
114
115         new->sense_command[0] = REQUEST_SENSE;
116         new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH;
117
118         usb_set_intfdata(intf, new);
119         return 0;
120
121  out_unlink_controlurb:
122         usb_unlink_urb(new->controlurb);
123  out_free_controlurb:
124         usb_free_urb(new->controlurb);
125  out_free_dataurb:
126         usb_free_urb(new->dataurb);
127  out_kfree:
128         kfree(new);
129         return error;
130 }
131
132 static void
133 hpusbscsi_usb_disconnect(struct usb_interface *intf)
134 {
135         struct hpusbscsi *desc = usb_get_intfdata(intf);
136
137         usb_set_intfdata(intf, NULL);
138
139         scsi_remove_host(desc->host);
140         usb_unlink_urb(desc->controlurb);
141         scsi_host_put(desc->host);
142
143         usb_free_urb(desc->controlurb);
144         usb_free_urb(desc->dataurb);
145         kfree(desc);
146 }
147
148 static struct usb_device_id hpusbscsi_usb_ids[] = {
149         {USB_DEVICE (0x03f0, 0x0701)},  /* HP 53xx */
150         {USB_DEVICE (0x03f0, 0x0801)},  /* HP 7400 */
151         {USB_DEVICE (0x0638, 0x0268)},  /*iVina 1200U */
152         {USB_DEVICE (0x0638, 0x026a)},  /*Scan Dual II */
153         {USB_DEVICE (0x0638, 0x0A13)},  /*Avision AV600U */
154         {USB_DEVICE (0x0638, 0x0A16)},  /*Avision DS610CU Scancopier */
155         {USB_DEVICE (0x0638, 0x0A18)},  /*Avision AV600U Plus */
156         {USB_DEVICE (0x0638, 0x0A23)},  /*Avision AV220 */
157         {USB_DEVICE (0x0638, 0x0A24)},  /*Avision AV210 */
158         {USB_DEVICE (0x0686, 0x4004)},  /*Minolta Elite II */
159         {}                      /* Terminating entry */
160 };
161
162 MODULE_DEVICE_TABLE (usb, hpusbscsi_usb_ids);
163 MODULE_LICENSE("GPL");
164
165
166 static struct usb_driver hpusbscsi_usb_driver = {
167         .owner = THIS_MODULE,
168         .name ="hpusbscsi",
169         .probe =hpusbscsi_usb_probe,
170         .disconnect =hpusbscsi_usb_disconnect,
171         .id_table =hpusbscsi_usb_ids,
172 };
173
174 /* module initialisation */
175
176 static int __init
177 hpusbscsi_init (void)
178 {
179         return usb_register(&hpusbscsi_usb_driver);
180 }
181
182 static void __exit
183 hpusbscsi_exit (void)
184 {
185         usb_deregister(&hpusbscsi_usb_driver);
186 }
187
188 module_init (hpusbscsi_init);
189 module_exit (hpusbscsi_exit);
190
191 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
192 {
193         struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
194         usb_complete_t usb_callback;
195         int res;
196
197         /* we don't answer for anything but our single device on any faked host controller */
198         if ( srb->device->lun || srb->device->id || srb->device->channel ) {
199                 if (callback) {
200                         srb->result = DID_BAD_TARGET;
201                         callback(srb);
202                 }
203                         goto out;
204         }
205
206         /* Now we need to decide which callback to give to the urb we send the command with */
207
208         if (!srb->bufflen) {
209                 if (srb->cmnd[0] == REQUEST_SENSE){
210                         hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
211                         usb_callback = request_sense_callback;
212                 } else {
213                         usb_callback = simple_command_callback;
214                 }
215         } else {
216                 if (likely(srb->use_sg)) {
217                         usb_callback = scatter_gather_callback;
218                         hpusbscsi->fragment = 0;
219                 } else {
220                         usb_callback = simple_payload_callback;
221                 }
222                 /* Now we find out which direction data is to be transferred in */
223                 hpusbscsi->current_data_pipe = DIRECTION_IS_IN(srb->cmnd[0]) ?
224                         usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in)
225                 :
226                         usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out)
227                 ;
228         }
229
230
231         TRACE_STATE;
232
233         /* We zero the sense buffer to avoid confusing user space */
234         memset(srb->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
235
236         hpusbscsi->state = HP_STATE_BEGINNING;
237         TRACE_STATE;
238
239         /* We prepare the urb for writing out the scsi command */
240         usb_fill_bulk_urb(
241                 hpusbscsi->dataurb,
242                 hpusbscsi->dev,
243                 usb_sndbulkpipe(hpusbscsi->dev,hpusbscsi->ep_out),
244                 srb->cmnd,
245                 srb->cmd_len,
246                 usb_callback,
247                 hpusbscsi
248         );
249         hpusbscsi->scallback = callback;
250         hpusbscsi->srb = srb;
251
252         res = usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC);
253         if (unlikely(res)) {
254                 hpusbscsi->state = HP_STATE_FREE;
255                 TRACE_STATE;
256                 if (likely(callback != NULL)) {
257                         srb->result = DID_ERROR;
258                         callback(srb);
259                 }
260         }
261
262 out:
263         return 0;
264 }
265
266 static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb)
267 {
268         struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
269
270         printk(KERN_DEBUG"SCSI reset requested.\n");
271         //usb_reset_device(hpusbscsi->dev);
272         //printk(KERN_DEBUG"SCSI reset completed.\n");
273         hpusbscsi->state = HP_STATE_FREE;
274
275         return 0;
276 }
277
278 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
279 {
280         struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
281         printk(KERN_DEBUG"Requested is canceled.\n");
282
283         usb_unlink_urb(hpusbscsi->dataurb);
284         usb_unlink_urb(hpusbscsi->controlurb);
285         hpusbscsi->state = HP_STATE_FREE;
286
287         return SCSI_ABORT_PENDING;
288 }
289
290 /* usb interrupt handlers - they are all running IN INTERRUPT ! */
291
292 static void handle_usb_error (struct hpusbscsi *hpusbscsi)
293 {
294         if (likely(hpusbscsi->scallback != NULL)) {
295                 hpusbscsi->srb->result = DID_ERROR;
296                 hpusbscsi->scallback(hpusbscsi->srb);
297         }
298         hpusbscsi->state = HP_STATE_FREE;
299 }
300
301 static void  control_interrupt_callback (struct urb *u, struct pt_regs *regs)
302 {
303         struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
304         u8 scsi_state;
305
306 DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte);
307         if(unlikely(u->status < 0)) {
308                 if (likely(hpusbscsi->state != HP_STATE_FREE))
309                         handle_usb_error(hpusbscsi);
310                 if (u->status == -ECONNRESET || u->status == -ENOENT || u->status == -ESHUTDOWN)
311                         return;
312                 else
313                         goto resub;
314         }
315
316         scsi_state = hpusbscsi->scsi_state_byte;
317         if (hpusbscsi->state != HP_STATE_ERROR) {
318                 hpusbscsi->srb->result &= SCSI_ERR_MASK;
319                 hpusbscsi->srb->result |= scsi_state;
320         }
321
322         if (scsi_state == CHECK_CONDITION << 1) {
323                 if (hpusbscsi->state == HP_STATE_WAIT) {
324                         issue_request_sense(hpusbscsi);
325                 } else {
326                         /* we request sense after an eventual data transfer */
327                         hpusbscsi->state = HP_STATE_ERROR;
328                 }
329         }
330
331         if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT && scsi_state != CHECK_CONDITION <<1 )
332                 /* we do a callback to the scsi layer if and only if all data has been transferred */
333                 hpusbscsi->scallback(hpusbscsi->srb);
334
335         TRACE_STATE;
336         switch (hpusbscsi->state) {
337         case HP_STATE_WAIT:
338                 hpusbscsi->state = HP_STATE_FREE;
339         TRACE_STATE;
340                 break;
341         case HP_STATE_WORKING:
342         case HP_STATE_BEGINNING:
343                 hpusbscsi->state = HP_STATE_PREMATURE;
344         TRACE_STATE;
345                 break;
346         case HP_STATE_ERROR:
347                 break;
348         default:
349                 printk(KERN_ERR"hpusbscsi: Unexpected status report.\n");
350         TRACE_STATE;
351                 hpusbscsi->state = HP_STATE_FREE;
352         TRACE_STATE;
353                 break;
354         }
355 resub:
356         usb_submit_urb(u, GFP_ATOMIC);
357 }
358
359 static void simple_command_callback(struct urb *u, struct pt_regs *regs)
360 {
361         struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
362         if (unlikely(u->status<0)) {
363                 handle_usb_error(hpusbscsi);
364                 return;
365         }
366         TRACE_STATE;
367         if (hpusbscsi->state != HP_STATE_PREMATURE) {
368                 TRACE_STATE;
369                 hpusbscsi->state = HP_STATE_WAIT;
370         } else {
371                 if (likely(hpusbscsi->scallback != NULL))
372                         hpusbscsi->scallback(hpusbscsi->srb);
373                 hpusbscsi->state = HP_STATE_FREE;
374         TRACE_STATE;
375         }
376 }
377
378 static void scatter_gather_callback(struct urb *u, struct pt_regs *regs)
379 {
380         struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
381         struct scatterlist *sg = hpusbscsi->srb->buffer;
382         usb_complete_t callback;
383         int res;
384
385         DEBUG("Going through scatter/gather\n");
386         if (unlikely(u->status < 0)) {
387                 handle_usb_error(hpusbscsi);
388                 return;
389         }
390
391         if (hpusbscsi->fragment + 1 != hpusbscsi->srb->use_sg)
392                 callback = scatter_gather_callback;
393         else
394                 callback = simple_done;
395
396         TRACE_STATE;
397         if (hpusbscsi->state != HP_STATE_PREMATURE)
398                 hpusbscsi->state = HP_STATE_WORKING;
399         TRACE_STATE;
400
401         usb_fill_bulk_urb(
402                 u,
403                 hpusbscsi->dev,
404                 hpusbscsi->current_data_pipe,
405                 page_address(sg[hpusbscsi->fragment].page) +
406                 sg[hpusbscsi->fragment].offset,
407                 sg[hpusbscsi->fragment++].length,
408                 callback,
409                 hpusbscsi
410         );
411
412         res = usb_submit_urb(u, GFP_ATOMIC);
413         if (unlikely(res))
414                 handle_usb_error(hpusbscsi);
415         TRACE_STATE;
416 }
417
418 static void simple_done (struct urb *u, struct pt_regs *regs)
419 {
420         struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
421
422         if (unlikely(u->status < 0)) {
423                 handle_usb_error(hpusbscsi);
424                 return;
425         }
426         DEBUG("Data transfer done\n");
427         TRACE_STATE;
428         if (hpusbscsi->state != HP_STATE_PREMATURE) {
429                 if (unlikely(u->status < 0)) {
430                         handle_usb_error(hpusbscsi);
431                 } else {
432                         if (hpusbscsi->state != HP_STATE_ERROR) {
433                                 hpusbscsi->state = HP_STATE_WAIT;
434                         } else {
435                                 issue_request_sense(hpusbscsi);
436                         }
437                 }
438         } else {
439                 if (likely(hpusbscsi->scallback != NULL))
440                         hpusbscsi->scallback(hpusbscsi->srb);
441                 hpusbscsi->state = HP_STATE_FREE;
442         }
443 }
444
445 static void simple_payload_callback (struct urb *u, struct pt_regs *regs)
446 {
447         struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
448         int res;
449
450         if (unlikely(u->status<0)) {
451                 handle_usb_error(hpusbscsi);
452                 return;
453         }
454
455         usb_fill_bulk_urb(
456                 u,
457                 hpusbscsi->dev,
458                 hpusbscsi->current_data_pipe,
459                 hpusbscsi->srb->buffer,
460                 hpusbscsi->srb->bufflen,
461                 simple_done,
462                 hpusbscsi
463         );
464
465         res = usb_submit_urb(u, GFP_ATOMIC);
466         if (unlikely(res)) {
467                 handle_usb_error(hpusbscsi);
468                 return;
469         }
470         TRACE_STATE;
471         if (hpusbscsi->state != HP_STATE_PREMATURE) {
472                 hpusbscsi->state = HP_STATE_WORKING;
473         TRACE_STATE;
474         } 
475 }
476
477 static void request_sense_callback (struct urb *u, struct pt_regs *regs)
478 {
479         struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
480
481         if (u->status<0) {
482                 handle_usb_error(hpusbscsi);
483                 return;
484         }
485
486         usb_fill_bulk_urb(
487                 u,
488                 hpusbscsi->dev,
489                 hpusbscsi->current_data_pipe,
490                 hpusbscsi->srb->sense_buffer,
491                 SCSI_SENSE_BUFFERSIZE,
492                 simple_done,
493                 hpusbscsi
494         );
495
496         if (0 > usb_submit_urb(u, GFP_ATOMIC)) {
497                 handle_usb_error(hpusbscsi);
498                 return;
499         }
500         if (hpusbscsi->state != HP_STATE_PREMATURE && hpusbscsi->state != HP_STATE_ERROR)
501                 hpusbscsi->state = HP_STATE_WORKING;
502 }
503
504 static void issue_request_sense (struct hpusbscsi *hpusbscsi)
505 {
506         usb_fill_bulk_urb(
507                 hpusbscsi->dataurb,
508                 hpusbscsi->dev,
509                 usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out),
510                 &hpusbscsi->sense_command,
511                 SENSE_COMMAND_SIZE,
512                 request_sense_callback,
513                 hpusbscsi
514         );
515
516         hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in);
517
518         if (0 > usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC)) {
519                 handle_usb_error(hpusbscsi);
520         }
521 }
522
523