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