This source file includes following definitions.
- sg_ioctl
- sg_open
- sg_close
- sg_malloc
- sg_free
- sg_read
- sg_command_done
- sg_write
- sg_select
- sg_detect
- sg_init
- sg_attach
- sg_detach
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9 #include <linux/module.h>
10
11 #include <linux/fs.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/string.h>
15 #include <linux/mm.h>
16 #include <linux/errno.h>
17 #include <linux/mtio.h>
18 #include <linux/ioctl.h>
19 #include <linux/fcntl.h>
20 #include <asm/io.h>
21 #include <asm/segment.h>
22 #include <asm/system.h>
23
24 #include <linux/blk.h>
25 #include "scsi.h"
26 #include "hosts.h"
27 #include "scsi_ioctl.h"
28 #include "sg.h"
29
30 static int sg_init(void);
31 static int sg_attach(Scsi_Device *);
32 static int sg_detect(Scsi_Device *);
33 static void sg_detach(Scsi_Device *);
34
35
36 struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", NULL, 0xff,
37 SCSI_GENERIC_MAJOR, 0, 0, 0, 0,
38 sg_detect, sg_init,
39 NULL, sg_attach, sg_detach};
40
41 #ifdef SG_BIG_BUFF
42 static char *big_buff = NULL;
43 static struct wait_queue *big_wait;
44 static int big_inuse=0;
45 #endif
46
47 struct scsi_generic
48 {
49 Scsi_Device *device;
50 int users;
51 struct wait_queue *generic_wait;
52 struct wait_queue *read_wait;
53 struct wait_queue *write_wait;
54 int timeout;
55 int buff_len;
56 char *buff;
57 struct sg_header header;
58 char exclude;
59 char pending;
60 char complete;
61 };
62
63 static struct scsi_generic *scsi_generics=NULL;
64 static void sg_free(char *buff,int size);
65
66 static int sg_ioctl(struct inode * inode,struct file * file,
67 unsigned int cmd_in, unsigned long arg)
68 {
69 int result;
70 int dev = MINOR(inode->i_rdev);
71 if ((dev<0) || (dev>=sg_template.dev_max))
72 return -ENXIO;
73 switch(cmd_in)
74 {
75 case SG_SET_TIMEOUT:
76 result = verify_area(VERIFY_READ, (const void *)arg, sizeof(long));
77 if (result) return result;
78
79 scsi_generics[dev].timeout=get_user((int *) arg);
80 return 0;
81 case SG_GET_TIMEOUT:
82 return scsi_generics[dev].timeout;
83 default:
84 return scsi_ioctl(scsi_generics[dev].device, cmd_in, (void *) arg);
85 }
86 }
87
88 static int sg_open(struct inode * inode, struct file * filp)
89 {
90 int dev=MINOR(inode->i_rdev);
91 int flags=filp->f_flags;
92 if (dev>=sg_template.dev_max || !scsi_generics[dev].device)
93 return -ENXIO;
94 if (O_RDWR!=(flags & O_ACCMODE))
95 return -EACCES;
96
97
98
99
100
101 if (flags & O_EXCL)
102 {
103 while(scsi_generics[dev].users)
104 {
105 if (flags & O_NONBLOCK)
106 return -EBUSY;
107 interruptible_sleep_on(&scsi_generics[dev].generic_wait);
108 if (current->signal & ~current->blocked)
109 return -ERESTARTSYS;
110 }
111 scsi_generics[dev].exclude=1;
112 }
113 else
114
115
116
117
118 while(scsi_generics[dev].exclude)
119 {
120 if (flags & O_NONBLOCK)
121 return -EBUSY;
122 interruptible_sleep_on(&scsi_generics[dev].generic_wait);
123 if (current->signal & ~current->blocked)
124 return -ERESTARTSYS;
125 }
126
127
128
129
130
131
132 if (!scsi_generics[dev].users
133 && scsi_generics[dev].pending
134 && scsi_generics[dev].complete)
135 {
136 if (scsi_generics[dev].buff != NULL)
137 sg_free(scsi_generics[dev].buff,scsi_generics[dev].buff_len);
138 scsi_generics[dev].buff=NULL;
139 scsi_generics[dev].pending=0;
140 }
141 if (!scsi_generics[dev].users)
142 scsi_generics[dev].timeout=SG_DEFAULT_TIMEOUT;
143 if (scsi_generics[dev].device->host->hostt->usage_count)
144 (*scsi_generics[dev].device->host->hostt->usage_count)++;
145 if(sg_template.usage_count) (*sg_template.usage_count)++;
146 scsi_generics[dev].users++;
147 return 0;
148 }
149
150 static void sg_close(struct inode * inode, struct file * filp)
151 {
152 int dev=MINOR(inode->i_rdev);
153 scsi_generics[dev].users--;
154 if (scsi_generics[dev].device->host->hostt->usage_count)
155 (*scsi_generics[dev].device->host->hostt->usage_count)--;
156 if(sg_template.usage_count) (*sg_template.usage_count)--;
157 scsi_generics[dev].exclude=0;
158 wake_up(&scsi_generics[dev].generic_wait);
159 }
160
161 static char *sg_malloc(int size)
162 {
163 if (size<=4096)
164 return (char *) scsi_malloc(size);
165 #ifdef SG_BIG_BUFF
166 if (size<=SG_BIG_BUFF)
167 {
168 while(big_inuse)
169 {
170 interruptible_sleep_on(&big_wait);
171 if (current->signal & ~current->blocked)
172 return NULL;
173 }
174 big_inuse=1;
175 return big_buff;
176 }
177 #endif
178 return NULL;
179 }
180
181 static void sg_free(char *buff,int size)
182 {
183 #ifdef SG_BIG_BUFF
184 if (buff==big_buff)
185 {
186 big_inuse=0;
187 wake_up(&big_wait);
188 return;
189 }
190 #endif
191 scsi_free(buff,size);
192 }
193
194
195
196
197
198
199 static int sg_read(struct inode *inode,struct file *filp,char *buf,int count)
200 {
201 int dev=MINOR(inode->i_rdev);
202 int i;
203 unsigned long flags;
204 struct scsi_generic *device=&scsi_generics[dev];
205 if ((i=verify_area(VERIFY_WRITE,buf,count)))
206 return i;
207
208
209
210
211 save_flags(flags);
212 cli();
213 while(!device->pending || !device->complete)
214 {
215 if (filp->f_flags & O_NONBLOCK)
216 {
217 restore_flags(flags);
218 return -EAGAIN;
219 }
220 interruptible_sleep_on(&device->read_wait);
221 if (current->signal & ~current->blocked)
222 {
223 restore_flags(flags);
224 return -ERESTARTSYS;
225 }
226 }
227 restore_flags(flags);
228
229
230
231
232 device->header.pack_len=device->header.reply_len;
233 device->header.result=0;
234 if (count>=sizeof(struct sg_header))
235 {
236 memcpy_tofs(buf,&device->header,sizeof(struct sg_header));
237 buf+=sizeof(struct sg_header);
238 if (count>device->header.pack_len)
239 count=device->header.pack_len;
240 if (count > sizeof(struct sg_header)) {
241 memcpy_tofs(buf,device->buff,count-sizeof(struct sg_header));
242 }
243 }
244 else
245 count=0;
246
247
248
249
250
251 sg_free(device->buff,device->buff_len);
252 device->buff = NULL;
253 device->pending=0;
254 wake_up(&device->write_wait);
255 return count;
256 }
257
258
259
260
261
262
263 static void sg_command_done(Scsi_Cmnd * SCpnt)
264 {
265 int dev = MINOR(SCpnt->request.rq_dev);
266 struct scsi_generic *device = &scsi_generics[dev];
267 if (!device->pending)
268 {
269 printk("unexpected done for sg %d\n",dev);
270 SCpnt->request.rq_status = RQ_INACTIVE;
271 return;
272 }
273
274
275
276
277
278 memcpy(device->header.sense_buffer, SCpnt->sense_buffer, sizeof(SCpnt->sense_buffer));
279 if (SCpnt->sense_buffer[0])
280 {
281 device->header.result=EIO;
282 }
283 else
284 device->header.result=SCpnt->result;
285
286
287
288
289
290 device->complete=1;
291 SCpnt->request.rq_status = RQ_INACTIVE;
292 wake_up(&scsi_generics[dev].read_wait);
293 }
294
295 static int sg_write(struct inode *inode,struct file *filp,const char *buf,int count)
296 {
297 int bsize,size,amt,i;
298 unsigned char cmnd[MAX_COMMAND_SIZE];
299 kdev_t devt = inode->i_rdev;
300 int dev = MINOR(devt);
301 struct scsi_generic * device=&scsi_generics[dev];
302 int input_size;
303 unsigned char opcode;
304 Scsi_Cmnd * SCpnt;
305
306 if ((i=verify_area(VERIFY_READ,buf,count)))
307 return i;
308
309
310
311
312 if (count<(sizeof(struct sg_header) + 6))
313 return -EIO;
314
315
316
317
318
319
320 while(device->pending)
321 {
322 if (filp->f_flags & O_NONBLOCK)
323 return -EAGAIN;
324 #ifdef DEBUG
325 printk("sg_write: sleeping on pending request\n");
326 #endif
327 interruptible_sleep_on(&device->write_wait);
328 if (current->signal & ~current->blocked)
329 return -ERESTARTSYS;
330 }
331
332
333
334
335 device->pending=1;
336 device->complete=0;
337 memcpy_fromfs(&device->header,buf,sizeof(struct sg_header));
338
339 device->header.pack_len=count;
340 buf+=sizeof(struct sg_header);
341
342
343
344
345 opcode = get_user(buf);
346 size=COMMAND_SIZE(opcode);
347 if (opcode >= 0xc0 && device->header.twelve_byte) size = 12;
348
349
350
351
352 input_size = device->header.pack_len - size;
353 if( input_size > device->header.reply_len)
354 {
355 bsize = input_size;
356 } else {
357 bsize = device->header.reply_len;
358 }
359
360
361
362
363 bsize-=sizeof(struct sg_header);
364 input_size-=sizeof(struct sg_header);
365
366
367
368
369 if( input_size < 0 )
370 {
371 device->pending=0;
372 wake_up( &device->write_wait );
373 return -EIO;
374 }
375
376
377
378
379
380
381 amt=bsize;
382 if (!bsize)
383 bsize++;
384 bsize=(bsize+511) & ~511;
385
386
387
388
389 if ((bsize<0) || !(device->buff=sg_malloc(device->buff_len=bsize)))
390 {
391 device->pending=0;
392 wake_up(&device->write_wait);
393 return -ENOMEM;
394 }
395
396 #ifdef DEBUG
397 printk("allocating device\n");
398 #endif
399
400
401
402
403
404 if (!(SCpnt=allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
405 {
406 device->pending=0;
407 wake_up(&device->write_wait);
408 sg_free(device->buff,device->buff_len);
409 device->buff = NULL;
410 return -EAGAIN;
411 }
412 #ifdef DEBUG
413 printk("device allocated\n");
414 #endif
415
416 SCpnt->request.rq_dev = devt;
417 SCpnt->request.rq_status = RQ_ACTIVE;
418 SCpnt->sense_buffer[0]=0;
419 SCpnt->cmd_len = size;
420
421
422
423
424 memcpy_fromfs(cmnd,buf,size);
425 buf+=size;
426
427
428
429
430
431
432 if (input_size > 0) memcpy_fromfs(device->buff, buf, input_size);
433
434
435
436
437 cmnd[1]= (cmnd[1] & 0x1f) | (device->device->lun<<5);
438
439 #ifdef DEBUG
440 printk("do cmd\n");
441 #endif
442
443
444
445
446
447
448 scsi_do_cmd (SCpnt,(void *) cmnd,
449 (void *) device->buff,amt,
450 sg_command_done,device->timeout,SG_DEFAULT_RETRIES);
451
452 #ifdef DEBUG
453 printk("done cmd\n");
454 #endif
455
456 return count;
457 }
458
459 static int sg_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
460 {
461 int dev=MINOR(inode->i_rdev);
462 int r = 0;
463 struct scsi_generic *device=&scsi_generics[dev];
464
465 if (sel_type == SEL_IN) {
466 if(device->pending && device->complete)
467 {
468 r = 1;
469 } else {
470 select_wait(&scsi_generics[dev].read_wait, wait);
471 }
472 }
473 if (sel_type == SEL_OUT) {
474 if(!device->pending){
475 r = 1;
476 }
477 else
478 {
479 select_wait(&scsi_generics[dev].write_wait, wait);
480 }
481 }
482
483 return(r);
484 }
485
486 static struct file_operations sg_fops = {
487 NULL,
488 sg_read,
489 sg_write,
490 NULL,
491 sg_select,
492 sg_ioctl,
493 NULL,
494 sg_open,
495 sg_close,
496 NULL
497 };
498
499
500 static int sg_detect(Scsi_Device * SDp){
501
502 switch (SDp->type) {
503 case TYPE_DISK:
504 case TYPE_MOD:
505 case TYPE_ROM:
506 case TYPE_WORM:
507 case TYPE_TAPE: break;
508 default:
509 printk("Detected scsi generic sg%c at scsi%d, channel %d, id %d, lun %d\n",
510 'a'+sg_template.dev_noticed,
511 SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
512 }
513 sg_template.dev_noticed++;
514 return 1;
515 }
516
517
518 static int sg_init()
519 {
520 static int sg_registered = 0;
521
522 if (sg_template.dev_noticed == 0) return 0;
523
524 if(!sg_registered) {
525 if (register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
526 {
527 printk("Unable to get major %d for generic SCSI device\n",
528 SCSI_GENERIC_MAJOR);
529 return 1;
530 }
531 sg_registered++;
532 }
533
534
535 if(scsi_generics) return 0;
536
537 #ifdef DEBUG
538 printk("sg: Init generic device.\n");
539 #endif
540
541 #ifdef SG_BIG_BUFF
542 big_buff= (char *) scsi_init_malloc(SG_BIG_BUFF, GFP_ATOMIC | GFP_DMA);
543 #endif
544
545 scsi_generics = (struct scsi_generic *)
546 scsi_init_malloc((sg_template.dev_noticed + SG_EXTRA_DEVS)
547 * sizeof(struct scsi_generic), GFP_ATOMIC);
548 memset(scsi_generics, 0, (sg_template.dev_noticed + SG_EXTRA_DEVS)
549 * sizeof(struct scsi_generic));
550
551 sg_template.dev_max = sg_template.dev_noticed + SG_EXTRA_DEVS;
552 return 0;
553 }
554
555 static int sg_attach(Scsi_Device * SDp)
556 {
557 struct scsi_generic * gpnt;
558 int i;
559
560 if(sg_template.nr_dev >= sg_template.dev_max)
561 {
562 SDp->attached--;
563 return 1;
564 }
565
566 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
567 if(!gpnt->device) break;
568
569 if(i >= sg_template.dev_max) panic ("scsi_devices corrupt (sg)");
570
571 scsi_generics[i].device=SDp;
572 scsi_generics[i].users=0;
573 scsi_generics[i].generic_wait=NULL;
574 scsi_generics[i].read_wait=NULL;
575 scsi_generics[i].write_wait=NULL;
576 scsi_generics[i].buff=NULL;
577 scsi_generics[i].exclude=0;
578 scsi_generics[i].pending=0;
579 scsi_generics[i].timeout=SG_DEFAULT_TIMEOUT;
580 sg_template.nr_dev++;
581 return 0;
582 };
583
584
585
586 static void sg_detach(Scsi_Device * SDp)
587 {
588 struct scsi_generic * gpnt;
589 int i;
590
591 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
592 if(gpnt->device == SDp) {
593 gpnt->device = NULL;
594 SDp->attached--;
595 sg_template.nr_dev--;
596 return;
597 }
598 return;
599 }
600
601 #ifdef MODULE
602
603 int init_module(void) {
604 sg_template.usage_count = &mod_use_count_;
605 return scsi_register_module(MODULE_SCSI_DEV, &sg_template);
606 }
607
608 void cleanup_module( void)
609 {
610 scsi_unregister_module(MODULE_SCSI_DEV, &sg_template);
611 unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
612
613 if(scsi_generics != NULL) {
614 scsi_init_free((char *) scsi_generics,
615 (sg_template.dev_noticed + SG_EXTRA_DEVS)
616 * sizeof(struct scsi_generic));
617 }
618 sg_template.dev_max = 0;
619 #ifdef SG_BIG_BUFF
620 if(big_buff != NULL)
621 scsi_init_free(big_buff, SG_BIG_BUFF);
622 #endif
623 }
624 #endif
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643