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 -EWOULDBLOCK;
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 #define SG_SEND 0
296 #define SG_REC 1
297
298 static int sg_write(struct inode *inode,struct file *filp,const char *buf,int count)
299 {
300 int bsize,size,amt,i;
301 unsigned char cmnd[MAX_COMMAND_SIZE];
302 kdev_t devt = inode->i_rdev;
303 int dev = MINOR(devt);
304 struct scsi_generic * device=&scsi_generics[dev];
305 int direction;
306 unsigned char opcode;
307 Scsi_Cmnd * SCpnt;
308
309 if ((i=verify_area(VERIFY_READ,buf,count)))
310 return i;
311
312
313
314
315 if (count<(sizeof(struct sg_header) + 6))
316 return -EIO;
317
318
319
320
321
322
323 while(device->pending)
324 {
325 if (filp->f_flags & O_NONBLOCK)
326 return -EWOULDBLOCK;
327 #ifdef DEBUG
328 printk("sg_write: sleeping on pending request\n");
329 #endif
330 interruptible_sleep_on(&device->write_wait);
331 if (current->signal & ~current->blocked)
332 return -ERESTARTSYS;
333 }
334
335
336
337
338 device->pending=1;
339 device->complete=0;
340 memcpy_fromfs(&device->header,buf,sizeof(struct sg_header));
341
342
343
344
345 device->header.pack_len=count;
346 buf+=sizeof(struct sg_header);
347 if( device->header.pack_len > device->header.reply_len )
348 {
349 bsize = device->header.pack_len;
350 direction = SG_SEND;
351 } else {
352 bsize = device->header.reply_len;
353 direction = SG_REC;
354 }
355
356
357
358
359 bsize-=sizeof(struct sg_header);
360
361
362
363
364
365
366 amt=bsize;
367 if (!bsize)
368 bsize++;
369 bsize=(bsize+511) & ~511;
370
371
372
373
374 if ((bsize<0) || !(device->buff=sg_malloc(device->buff_len=bsize)))
375 {
376 device->pending=0;
377 wake_up(&device->write_wait);
378 return -ENOMEM;
379 }
380
381 #ifdef DEBUG
382 printk("allocating device\n");
383 #endif
384
385
386
387
388
389 if (!(SCpnt=allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
390 {
391 device->pending=0;
392 wake_up(&device->write_wait);
393 sg_free(device->buff,device->buff_len);
394 device->buff = NULL;
395 return -EWOULDBLOCK;
396 }
397 #ifdef DEBUG
398 printk("device allocated\n");
399 #endif
400
401
402
403
404 SCpnt->request.rq_dev = devt;
405 SCpnt->request.rq_status = RQ_ACTIVE;
406 SCpnt->sense_buffer[0]=0;
407 opcode = get_user(buf);
408 size=COMMAND_SIZE(opcode);
409 if (opcode >= 0xc0 && device->header.twelve_byte) size = 12;
410 SCpnt->cmd_len = size;
411
412
413
414
415
416
417 if( direction == SG_SEND )
418 amt -= size;
419
420
421
422
423 if( count < (sizeof(struct sg_header) + size) )
424 {
425 device->pending=0;
426 wake_up( &device->write_wait );
427 sg_free( device->buff, device->buff_len );
428 device->buff = NULL;
429 return -EIO;
430 }
431
432
433
434
435 memcpy_fromfs(cmnd,buf,size);
436 buf+=size;
437
438
439
440
441
442
443 if( direction == SG_SEND ) memcpy_fromfs(device->buff,buf, amt);
444
445
446
447
448 cmnd[1]= (cmnd[1] & 0x1f) | (device->device->lun<<5);
449
450 #ifdef DEBUG
451 printk("do cmd\n");
452 #endif
453
454
455
456
457
458
459 scsi_do_cmd (SCpnt,(void *) cmnd,
460 (void *) device->buff,amt,
461 sg_command_done,device->timeout,SG_DEFAULT_RETRIES);
462
463 #ifdef DEBUG
464 printk("done cmd\n");
465 #endif
466
467 return count;
468 }
469
470 static int sg_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
471 {
472 int dev=MINOR(inode->i_rdev);
473 int r = 0;
474 struct scsi_generic *device=&scsi_generics[dev];
475
476 if (sel_type == SEL_IN) {
477 if(device->pending && device->complete)
478 {
479 r = 1;
480 } else {
481 select_wait(&scsi_generics[dev].read_wait, wait);
482 }
483 }
484 if (sel_type == SEL_OUT) {
485 if(!device->pending){
486 r = 1;
487 }
488 else
489 {
490 select_wait(&scsi_generics[dev].write_wait, wait);
491 }
492 }
493
494 return(r);
495 }
496
497 static struct file_operations sg_fops = {
498 NULL,
499 sg_read,
500 sg_write,
501 NULL,
502 sg_select,
503 sg_ioctl,
504 NULL,
505 sg_open,
506 sg_close,
507 NULL
508 };
509
510
511 static int sg_detect(Scsi_Device * SDp){
512 ++sg_template.dev_noticed;
513 return 1;
514 }
515
516
517 static int sg_init()
518 {
519 static int sg_registered = 0;
520
521 if (sg_template.dev_noticed == 0) return 0;
522
523 if(!sg_registered) {
524 if (register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
525 {
526 printk("Unable to get major %d for generic SCSI device\n",
527 SCSI_GENERIC_MAJOR);
528 return 1;
529 }
530 sg_registered++;
531 }
532
533
534 if(scsi_generics) return 0;
535
536 #ifdef DEBUG
537 printk("sg: Init generic device.\n");
538 #endif
539
540 #ifdef SG_BIG_BUFF
541 big_buff= (char *) scsi_init_malloc(SG_BIG_BUFF, GFP_ATOMIC | GFP_DMA);
542 #endif
543
544 scsi_generics = (struct scsi_generic *)
545 scsi_init_malloc((sg_template.dev_noticed + SG_EXTRA_DEVS)
546 * sizeof(struct scsi_generic), GFP_ATOMIC);
547 memset(scsi_generics, 0, (sg_template.dev_noticed + SG_EXTRA_DEVS)
548 * sizeof(struct scsi_generic));
549
550 sg_template.dev_max = sg_template.dev_noticed + SG_EXTRA_DEVS;
551 return 0;
552 }
553
554 static int sg_attach(Scsi_Device * SDp)
555 {
556 struct scsi_generic * gpnt;
557 int i;
558
559 if(sg_template.nr_dev >= sg_template.dev_max)
560 {
561 SDp->attached--;
562 return 1;
563 }
564
565 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
566 if(!gpnt->device) break;
567
568 if(i >= sg_template.dev_max) panic ("scsi_devices corrupt (sg)");
569
570 scsi_generics[i].device=SDp;
571 scsi_generics[i].users=0;
572 scsi_generics[i].generic_wait=NULL;
573 scsi_generics[i].read_wait=NULL;
574 scsi_generics[i].write_wait=NULL;
575 scsi_generics[i].buff=NULL;
576 scsi_generics[i].exclude=0;
577 scsi_generics[i].pending=0;
578 scsi_generics[i].timeout=SG_DEFAULT_TIMEOUT;
579 sg_template.nr_dev++;
580 return 0;
581 };
582
583
584
585 static void sg_detach(Scsi_Device * SDp)
586 {
587 struct scsi_generic * gpnt;
588 int i;
589
590 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
591 if(gpnt->device == SDp) {
592 gpnt->device = NULL;
593 SDp->attached--;
594 sg_template.nr_dev--;
595 return;
596 }
597 return;
598 }
599
600 #ifdef MODULE
601
602 int init_module(void) {
603 sg_template.usage_count = &mod_use_count_;
604 return scsi_register_module(MODULE_SCSI_DEV, &sg_template);
605 }
606
607 void cleanup_module( void)
608 {
609 scsi_unregister_module(MODULE_SCSI_DEV, &sg_template);
610 unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
611
612 if(scsi_generics != NULL) {
613 scsi_init_free((char *) scsi_generics,
614 (sg_template.dev_noticed + SG_EXTRA_DEVS)
615 * sizeof(struct scsi_generic));
616 }
617 sg_template.dev_max = 0;
618 #ifdef SG_BIG_BUFF
619 if(big_buff != NULL)
620 scsi_init_free(big_buff, SG_BIG_BUFF);
621 #endif
622 }
623 #endif
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642