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