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