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
1
2
3
4
5
6
7
8
9
10 #include <linux/fs.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/string.h>
14 #include <linux/mm.h>
15 #include <linux/errno.h>
16 #include <linux/mtio.h>
17 #include <linux/ioctl.h>
18 #include <linux/fcntl.h>
19 #include <asm/io.h>
20 #include <asm/segment.h>
21 #include <asm/system.h>
22
23 #include "../block/blk.h"
24 #include "scsi.h"
25 #include "hosts.h"
26 #include "scsi_ioctl.h"
27 #include "sg.h"
28
29 static void sg_init(void);
30 static int sg_attach(Scsi_Device *);
31 static int sg_detect(Scsi_Device *);
32 static void sg_detach(Scsi_Device *);
33
34
35 struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", 0xff,
36 SCSI_GENERIC_MAJOR, 0, 0, 0, 0,
37 sg_detect, sg_init,
38 NULL, sg_attach, sg_detach};
39
40 #ifdef SG_BIG_BUFF
41 static char *big_buff;
42 static struct wait_queue *big_wait;
43 static int big_inuse=0;
44 #endif
45
46 struct scsi_generic
47 {
48 Scsi_Device *device;
49 int users;
50 struct wait_queue *generic_wait;
51 struct wait_queue *read_wait;
52 struct wait_queue *write_wait;
53 int timeout;
54 int buff_len;
55 char *buff;
56 struct sg_header header;
57 char exclude;
58 char pending;
59 char complete;
60 };
61
62 static struct scsi_generic *scsi_generics=NULL;
63 static void sg_free(char *buff,int size);
64
65 static int sg_ioctl(struct inode * inode,struct file * file,
66 unsigned int cmd_in, unsigned long arg)
67 {
68 int dev = MINOR(inode->i_rdev);
69 if ((dev<0) || (dev>=sg_template.dev_max))
70 return -ENXIO;
71 switch(cmd_in)
72 {
73 case SG_SET_TIMEOUT:
74 scsi_generics[dev].timeout=get_fs_long((int *) arg);
75 return 0;
76 case SG_GET_TIMEOUT:
77 return scsi_generics[dev].timeout;
78 default:
79 return scsi_ioctl(scsi_generics[dev].device, cmd_in, (void *) arg);
80 }
81 }
82
83 static int sg_open(struct inode * inode, struct file * filp)
84 {
85 int dev=MINOR(inode->i_rdev);
86 int flags=filp->f_flags;
87 if (dev>=sg_template.dev_max || !scsi_generics[dev].device)
88 return -ENXIO;
89 if (O_RDWR!=(flags & O_ACCMODE))
90 return -EACCES;
91 if (flags & O_EXCL)
92 {
93 while(scsi_generics[dev].users)
94 {
95 if (flags & O_NONBLOCK)
96 return -EBUSY;
97 interruptible_sleep_on(&scsi_generics[dev].generic_wait);
98 if (current->signal & ~current->blocked)
99 return -ERESTARTSYS;
100 }
101 scsi_generics[dev].exclude=1;
102 }
103 else
104 while(scsi_generics[dev].exclude)
105 {
106 if (flags & O_NONBLOCK)
107 return -EBUSY;
108 interruptible_sleep_on(&scsi_generics[dev].generic_wait);
109 if (current->signal & ~current->blocked)
110 return -ERESTARTSYS;
111 }
112 if (!scsi_generics[dev].users && scsi_generics[dev].pending && scsi_generics[dev].complete)
113 {
114 if (scsi_generics[dev].buff != NULL)
115 sg_free(scsi_generics[dev].buff,scsi_generics[dev].buff_len);
116 scsi_generics[dev].buff=NULL;
117 scsi_generics[dev].pending=0;
118 }
119 if (!scsi_generics[dev].users)
120 scsi_generics[dev].timeout=SG_DEFAULT_TIMEOUT;
121 if (scsi_generics[dev].device->host->hostt->usage_count)
122 (*scsi_generics[dev].device->host->hostt->usage_count)++;
123 scsi_generics[dev].users++;
124 return 0;
125 }
126
127 static void sg_close(struct inode * inode, struct file * filp)
128 {
129 int dev=MINOR(inode->i_rdev);
130 scsi_generics[dev].users--;
131 if (scsi_generics[dev].device->host->hostt->usage_count)
132 (*scsi_generics[dev].device->host->hostt->usage_count)--;
133 scsi_generics[dev].exclude=0;
134 wake_up(&scsi_generics[dev].generic_wait);
135 }
136
137 static char *sg_malloc(int size)
138 {
139 if (size<=4096)
140 return (char *) scsi_malloc(size);
141 #ifdef SG_BIG_BUFF
142 if (size<SG_BIG_BUFF)
143 {
144 while(big_inuse)
145 {
146 interruptible_sleep_on(&big_wait);
147 if (current->signal & ~current->blocked)
148 return NULL;
149 }
150 big_inuse=1;
151 return big_buff;
152 }
153 #endif
154 return NULL;
155 }
156
157 static void sg_free(char *buff,int size)
158 {
159 #ifdef SG_BIG_BUFF
160 if (buff==big_buff)
161 {
162 big_inuse=0;
163 wake_up(&big_wait);
164 return;
165 }
166 #endif
167 scsi_free(buff,size);
168 }
169
170 static int sg_read(struct inode *inode,struct file *filp,char *buf,int count)
171 {
172 int dev=MINOR(inode->i_rdev);
173 int i;
174 struct scsi_generic *device=&scsi_generics[dev];
175 if ((i=verify_area(VERIFY_WRITE,buf,count)))
176 return i;
177 while(!device->pending || !device->complete)
178 {
179 if (filp->f_flags & O_NONBLOCK)
180 return -EWOULDBLOCK;
181 interruptible_sleep_on(&device->read_wait);
182 if (current->signal & ~current->blocked)
183 return -ERESTARTSYS;
184 }
185 device->header.pack_len=device->header.reply_len;
186 device->header.result=0;
187 if (count>=sizeof(struct sg_header))
188 {
189 memcpy_tofs(buf,&device->header,sizeof(struct sg_header));
190 buf+=sizeof(struct sg_header);
191 if (count>device->header.pack_len)
192 count=device->header.pack_len;
193 if (count > sizeof(struct sg_header)) {
194 memcpy_tofs(buf,device->buff,count-sizeof(struct sg_header));
195 }
196 }
197 else
198 count=0;
199 sg_free(device->buff,device->buff_len);
200 device->buff = NULL;
201 device->pending=0;
202 wake_up(&device->write_wait);
203 return count;
204 }
205
206 static void sg_command_done(Scsi_Cmnd * SCpnt)
207 {
208 int dev=SCpnt->request.dev;
209 struct scsi_generic *device=&scsi_generics[dev];
210 if (!device->pending)
211 {
212 printk("unexpected done for sg %d\n",dev);
213 SCpnt->request.dev=-1;
214 return;
215 }
216 memcpy(device->header.sense_buffer, SCpnt->sense_buffer, sizeof(SCpnt->sense_buffer));
217 if (SCpnt->sense_buffer[0])
218 {
219 device->header.result=EIO;
220 }
221 else
222 device->header.result=SCpnt->result;
223 device->complete=1;
224 SCpnt->request.dev=-1;
225 wake_up(&scsi_generics[dev].read_wait);
226 }
227
228 static int sg_write(struct inode *inode,struct file *filp,char *buf,int count)
229 {
230 int dev=MINOR(inode->i_rdev);
231 Scsi_Cmnd *SCpnt;
232 int bsize,size,amt,i;
233 unsigned char opcode;
234 unsigned char cmnd[MAX_COMMAND_SIZE];
235 struct scsi_generic *device=&scsi_generics[dev];
236
237 if ((i=verify_area(VERIFY_READ,buf,count)))
238 return i;
239
240
241
242
243 if (count<(sizeof(struct sg_header) + 6))
244 return -EIO;
245
246 while(device->pending)
247 {
248 if (filp->f_flags & O_NONBLOCK)
249 return -EWOULDBLOCK;
250 #ifdef DEBUG
251 printk("sg_write: sleeping on pending request\n");
252 #endif
253 interruptible_sleep_on(&device->write_wait);
254 if (current->signal & ~current->blocked)
255 return -ERESTARTSYS;
256 }
257 device->pending=1;
258 device->complete=0;
259 memcpy_fromfs(&device->header,buf,sizeof(struct sg_header));
260
261 device->header.pack_len=count;
262 buf+=sizeof(struct sg_header);
263 bsize=(device->header.pack_len>device->header.reply_len) ? device->header.pack_len : device->header.reply_len;
264 bsize-=sizeof(struct sg_header);
265 amt=bsize;
266 if (!bsize)
267 bsize++;
268 bsize=(bsize+511) & ~511;
269 if ((bsize<0) || !(device->buff=sg_malloc(device->buff_len=bsize)))
270 {
271 device->pending=0;
272 wake_up(&device->write_wait);
273 return -ENOMEM;
274 }
275 #ifdef DEBUG
276 printk("allocating device\n");
277 #endif
278 if (!(SCpnt=allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
279 {
280 device->pending=0;
281 wake_up(&device->write_wait);
282 sg_free(device->buff,device->buff_len);
283 device->buff = NULL;
284 return -EWOULDBLOCK;
285 }
286 #ifdef DEBUG
287 printk("device allocated\n");
288 #endif
289
290 SCpnt->request.dev=dev;
291 SCpnt->sense_buffer[0]=0;
292 opcode = get_fs_byte(buf);
293 size=COMMAND_SIZE(opcode);
294 if (opcode >= 0xc0 && device->header.twelve_byte) size = 12;
295 SCpnt->cmd_len = size;
296
297
298
299 if (count<(sizeof(struct sg_header) + size))
300 {
301 device->pending=0;
302 wake_up(&device->write_wait);
303 sg_free(device->buff,device->buff_len);
304 device->buff = NULL;
305 return -EIO;
306 }
307
308 memcpy_fromfs(cmnd,buf,size);
309 buf+=size;
310 memcpy_fromfs(device->buff,buf,device->header.pack_len-size-sizeof(struct sg_header));
311 cmnd[1]=(cmnd[1] & 0x1f) | (device->device->lun<<5);
312 #ifdef DEBUG
313 printk("do cmd\n");
314 #endif
315 scsi_do_cmd (SCpnt,(void *) cmnd,
316 (void *) device->buff,amt,
317 sg_command_done,device->timeout,SG_DEFAULT_RETRIES);
318 #ifdef DEBUG
319 printk("done cmd\n");
320 #endif
321 return count;
322 }
323
324 static struct file_operations sg_fops = {
325 NULL,
326 sg_read,
327 sg_write,
328 NULL,
329 NULL,
330 sg_ioctl,
331 NULL,
332 sg_open,
333 sg_close,
334 NULL
335 };
336
337
338 static int sg_detect(Scsi_Device * SDp){
339 ++sg_template.dev_noticed;
340 return 1;
341 }
342
343
344 static void sg_init()
345 {
346 static int sg_registered = 0;
347
348 if (sg_template.dev_noticed == 0) return;
349
350 if(!sg_registered) {
351 if (register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
352 {
353 printk("Unable to get major %d for generic SCSI device\n",
354 SCSI_GENERIC_MAJOR);
355 return;
356 }
357 sg_registered++;
358 }
359
360
361 if(scsi_generics) return;
362
363 #ifdef DEBUG
364 printk("sg: Init generic device.\n");
365 #endif
366
367 #ifdef SG_BIG_BUFF
368 big_buff= (char *) scsi_init_malloc(SG_BIG_BUFF, GFP_ATOMIC | GFP_DMA);
369 #endif
370
371 scsi_generics = (struct scsi_generic *)
372 scsi_init_malloc((sg_template.dev_noticed + SG_EXTRA_DEVS)
373 * sizeof(struct scsi_generic), GFP_ATOMIC);
374 memset(scsi_generics, 0, (sg_template.dev_noticed + SG_EXTRA_DEVS)
375 * sizeof(struct scsi_generic));
376
377 sg_template.dev_max = sg_template.dev_noticed + SG_EXTRA_DEVS;
378 }
379
380 static int sg_attach(Scsi_Device * SDp)
381 {
382 struct scsi_generic * gpnt;
383 int i;
384
385 if(sg_template.nr_dev >= sg_template.dev_max)
386 {
387 SDp->attached--;
388 return 1;
389 }
390
391 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
392 if(!gpnt->device) break;
393
394 if(i >= sg_template.dev_max) panic ("scsi_devices corrupt (sg)");
395
396 scsi_generics[i].device=SDp;
397 scsi_generics[i].users=0;
398 scsi_generics[i].generic_wait=NULL;
399 scsi_generics[i].read_wait=NULL;
400 scsi_generics[i].write_wait=NULL;
401 scsi_generics[i].buff=NULL;
402 scsi_generics[i].exclude=0;
403 scsi_generics[i].pending=0;
404 scsi_generics[i].timeout=SG_DEFAULT_TIMEOUT;
405 sg_template.nr_dev++;
406 return 0;
407 };
408
409
410
411 static void sg_detach(Scsi_Device * SDp)
412 {
413 struct scsi_generic * gpnt;
414 int i;
415
416 for(gpnt = scsi_generics, i=0; i<sg_template.dev_max; i++, gpnt++)
417 if(gpnt->device == SDp) {
418 gpnt->device = NULL;
419 SDp->attached--;
420 sg_template.nr_dev--;
421 return;
422 }
423 return;
424 }
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441