This source file includes following definitions.
- sg_ioctl
- sg_open
- sg_close
- sg_malloc
- sg_free
- sg_read
- sg_command_done
- sg_write
- 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 void 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 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 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 if (flags & O_EXCL)
97 {
98 while(scsi_generics[dev].users)
99 {
100 if (flags & O_NONBLOCK)
101 return -EBUSY;
102 interruptible_sleep_on(&scsi_generics[dev].generic_wait);
103 if (current->signal & ~current->blocked)
104 return -ERESTARTSYS;
105 }
106 scsi_generics[dev].exclude=1;
107 }
108 else
109 while(scsi_generics[dev].exclude)
110 {
111 if (flags & O_NONBLOCK)
112 return -EBUSY;
113 interruptible_sleep_on(&scsi_generics[dev].generic_wait);
114 if (current->signal & ~current->blocked)
115 return -ERESTARTSYS;
116 }
117 if (!scsi_generics[dev].users && scsi_generics[dev].pending && scsi_generics[dev].complete)
118 {
119 if (scsi_generics[dev].buff != NULL)
120 sg_free(scsi_generics[dev].buff,scsi_generics[dev].buff_len);
121 scsi_generics[dev].buff=NULL;
122 scsi_generics[dev].pending=0;
123 }
124 if (!scsi_generics[dev].users)
125 scsi_generics[dev].timeout=SG_DEFAULT_TIMEOUT;
126 if (scsi_generics[dev].device->host->hostt->usage_count)
127 (*scsi_generics[dev].device->host->hostt->usage_count)++;
128 if(sg_template.usage_count) (*sg_template.usage_count)++;
129 scsi_generics[dev].users++;
130 return 0;
131 }
132
133 static void sg_close(struct inode * inode, struct file * filp)
134 {
135 int dev=MINOR(inode->i_rdev);
136 scsi_generics[dev].users--;
137 if (scsi_generics[dev].device->host->hostt->usage_count)
138 (*scsi_generics[dev].device->host->hostt->usage_count)--;
139 if(sg_template.usage_count) (*sg_template.usage_count)--;
140 scsi_generics[dev].exclude=0;
141 wake_up(&scsi_generics[dev].generic_wait);
142 }
143
144 static char *sg_malloc(int size)
145 {
146 if (size<=4096)
147 return (char *) scsi_malloc(size);
148 #ifdef SG_BIG_BUFF
149 if (size<SG_BIG_BUFF)
150 {
151 while(big_inuse)
152 {
153 interruptible_sleep_on(&big_wait);
154 if (current->signal & ~current->blocked)
155 return NULL;
156 }
157 big_inuse=1;
158 return big_buff;
159 }
160 #endif
161 return NULL;
162 }
163
164 static void sg_free(char *buff,int size)
165 {
166 #ifdef SG_BIG_BUFF
167 if (buff==big_buff)
168 {
169 big_inuse=0;
170 wake_up(&big_wait);
171 return;
172 }
173 #endif
174 scsi_free(buff,size);
175 }
176
177 static int sg_read(struct inode *inode,struct file *filp,char *buf,int count)
178 {
179 int dev=MINOR(inode->i_rdev);
180 int i;
181 struct scsi_generic *device=&scsi_generics[dev];
182 if ((i=verify_area(VERIFY_WRITE,buf,count)))
183 return i;
184 while(!device->pending || !device->complete)
185 {
186 if (filp->f_flags & O_NONBLOCK)
187 return -EWOULDBLOCK;
188 interruptible_sleep_on(&device->read_wait);
189 if (current->signal & ~current->blocked)
190 return -ERESTARTSYS;
191 }
192 device->header.pack_len=device->header.reply_len;
193 device->header.result=0;
194 if (count>=sizeof(struct sg_header))
195 {
196 memcpy_tofs(buf,&device->header,sizeof(struct sg_header));
197 buf+=sizeof(struct sg_header);
198 if (count>device->header.pack_len)
199 count=device->header.pack_len;
200 if (count > sizeof(struct sg_header)) {
201 memcpy_tofs(buf,device->buff,count-sizeof(struct sg_header));
202 }
203 }
204 else
205 count=0;
206 sg_free(device->buff,device->buff_len);
207 device->buff = NULL;
208 device->pending=0;
209 wake_up(&device->write_wait);
210 return count;
211 }
212
213 static void sg_command_done(Scsi_Cmnd * SCpnt)
214 {
215 int dev=SCpnt->request.dev;
216 struct scsi_generic *device=&scsi_generics[dev];
217 if (!device->pending)
218 {
219 printk("unexpected done for sg %d\n",dev);
220 SCpnt->request.dev=-1;
221 return;
222 }
223 memcpy(device->header.sense_buffer, SCpnt->sense_buffer, sizeof(SCpnt->sense_buffer));
224 if (SCpnt->sense_buffer[0])
225 {
226 device->header.result=EIO;
227 }
228 else
229 device->header.result=SCpnt->result;
230 device->complete=1;
231 SCpnt->request.dev=-1;
232 wake_up(&scsi_generics[dev].read_wait);
233 }
234
235 static int sg_write(struct inode *inode,struct file *filp,char *buf,int count)
236 {
237 int dev=MINOR(inode->i_rdev);
238 Scsi_Cmnd *SCpnt;
239 int bsize,size,amt,i;
240 unsigned char opcode;
241 unsigned char cmnd[MAX_COMMAND_SIZE];
242 struct scsi_generic *device=&scsi_generics[dev];
243
244 if ((i=verify_area(VERIFY_READ,buf,count)))
245 return i;
246
247
248
249
250 if (count<(sizeof(struct sg_header) + 6))
251 return -EIO;
252
253 while(device->pending)
254 {
255 if (filp->f_flags & O_NONBLOCK)
256 return -EWOULDBLOCK;
257 #ifdef DEBUG
258 printk("sg_write: sleeping on pending request\n");
259 #endif
260 interruptible_sleep_on(&device->write_wait);
261 if (current->signal & ~current->blocked)
262 return -ERESTARTSYS;
263 }
264 device->pending=1;
265 device->complete=0;
266 memcpy_fromfs(&device->header,buf,sizeof(struct sg_header));
267
268 device->header.pack_len=count;
269 buf+=sizeof(struct sg_header);
270 bsize=(device->header.pack_len>device->header.reply_len) ? device->header.pack_len : device->header.reply_len;
271 bsize-=sizeof(struct sg_header);
272 amt=bsize;
273 if (!bsize)
274 bsize++;
275 bsize=(bsize+511) & ~511;
276 if ((bsize<0) || !(device->buff=sg_malloc(device->buff_len=bsize)))
277 {
278 device->pending=0;
279 wake_up(&device->write_wait);
280 return -ENOMEM;
281 }
282 #ifdef DEBUG
283 printk("allocating device\n");
284 #endif
285 if (!(SCpnt=allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
286 {
287 device->pending=0;
288 wake_up(&device->write_wait);
289 sg_free(device->buff,device->buff_len);
290 device->buff = NULL;
291 return -EWOULDBLOCK;
292 }
293 #ifdef DEBUG
294 printk("device allocated\n");
295 #endif
296
297 SCpnt->request.dev=dev;
298 SCpnt->sense_buffer[0]=0;
299 opcode = get_user(buf);
300 size=COMMAND_SIZE(opcode);
301 if (opcode >= 0xc0 && device->header.twelve_byte) size = 12;
302 SCpnt->cmd_len = size;
303 amt-=device->header.pack_len>device->header.reply_len ? size : 0;
304
305
306
307 if (count<(sizeof(struct sg_header) + size))
308 {
309 device->pending=0;
310 wake_up(&device->write_wait);
311 sg_free(device->buff,device->buff_len);
312 device->buff = NULL;
313 return -EIO;
314 }
315
316 memcpy_fromfs(cmnd,buf,size);
317 buf+=size;
318 memcpy_fromfs(device->buff,buf,device->header.pack_len-size-sizeof(struct sg_header));
319 cmnd[1]=(cmnd[1] & 0x1f) | (device->device->lun<<5);
320 #ifdef DEBUG
321 printk("do cmd\n");
322 #endif
323 scsi_do_cmd (SCpnt,(void *) cmnd,
324 (void *) device->buff,amt,
325 sg_command_done,device->timeout,SG_DEFAULT_RETRIES);
326 #ifdef DEBUG
327 printk("done cmd\n");
328 #endif
329 return count;
330 }
331
332 static struct file_operations sg_fops = {
333 NULL,
334 sg_read,
335 sg_write,
336 NULL,
337 NULL,
338 sg_ioctl,
339 NULL,
340 sg_open,
341 sg_close,
342 NULL
343 };
344
345
346 static int sg_detect(Scsi_Device * SDp){
347 ++sg_template.dev_noticed;
348 return 1;
349 }
350
351
352 static void sg_init()
353 {
354 static int sg_registered = 0;
355
356 if (sg_template.dev_noticed == 0) return;
357
358 if(!sg_registered) {
359 if (register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
360 {
361 printk("Unable to get major %d for generic SCSI device\n",
362 SCSI_GENERIC_MAJOR);
363 return;
364 }
365 sg_registered++;
366 }
367
368
369 if(scsi_generics) return;
370
371 #ifdef DEBUG
372 printk("sg: Init generic device.\n");
373 #endif
374
375 #ifdef SG_BIG_BUFF
376 big_buff= (char *) scsi_init_malloc(SG_BIG_BUFF, GFP_ATOMIC | GFP_DMA);
377 #endif
378
379 scsi_generics = (struct scsi_generic *)
380 scsi_init_malloc((sg_template.dev_noticed + SG_EXTRA_DEVS)
381 * sizeof(struct scsi_generic), GFP_ATOMIC);
382 memset(scsi_generics, 0, (sg_template.dev_noticed + SG_EXTRA_DEVS)
383 * sizeof(struct scsi_generic));
384
385 sg_template.dev_max = sg_template.dev_noticed + SG_EXTRA_DEVS;
386 }
387
388 static int sg_attach(Scsi_Device * SDp)
389 {
390 struct scsi_generic * gpnt;
391 int i;
392
393 if(sg_template.nr_dev >= sg_template.dev_max)
394 {
395 SDp->attached--;
396 return 1;
397 }
398
399 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
400 if(!gpnt->device) break;
401
402 if(i >= sg_template.dev_max) panic ("scsi_devices corrupt (sg)");
403
404 scsi_generics[i].device=SDp;
405 scsi_generics[i].users=0;
406 scsi_generics[i].generic_wait=NULL;
407 scsi_generics[i].read_wait=NULL;
408 scsi_generics[i].write_wait=NULL;
409 scsi_generics[i].buff=NULL;
410 scsi_generics[i].exclude=0;
411 scsi_generics[i].pending=0;
412 scsi_generics[i].timeout=SG_DEFAULT_TIMEOUT;
413 sg_template.nr_dev++;
414 return 0;
415 };
416
417
418
419 static void sg_detach(Scsi_Device * SDp)
420 {
421 struct scsi_generic * gpnt;
422 int i;
423
424 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
425 if(gpnt->device == SDp) {
426 gpnt->device = NULL;
427 SDp->attached--;
428 sg_template.nr_dev--;
429 return;
430 }
431 return;
432 }
433
434 #ifdef MODULE
435 char kernel_version[] = UTS_RELEASE;
436
437 int init_module(void) {
438 sg_template.usage_count = &mod_use_count_;
439 return scsi_register_module(MODULE_SCSI_DEV, &sg_template);
440 }
441
442 void cleanup_module( void)
443 {
444 if (MOD_IN_USE) {
445 printk(KERN_INFO __FILE__ ": module is in use, remove rejected\n");
446 return;
447 }
448 scsi_unregister_module(MODULE_SCSI_DEV, &sg_template);
449 unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
450
451 if(scsi_generics != NULL) {
452 scsi_init_free((char *) scsi_generics,
453 (sg_template.dev_noticed + SG_EXTRA_DEVS)
454 * sizeof(struct scsi_generic));
455 }
456 sg_template.dev_max = 0;
457 #ifdef SG_BIG_BUFF
458 if(big_buff != NULL)
459 scsi_init_free(big_buff, SG_BIG_BUFF);
460 #endif
461 }
462 #endif
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481