File: | obj-scan-build/../linux/src/drivers/scsi/sr.c |
Location: | line 748, column 3 |
Description: | Value stored to 'tries' is never read |
1 | /* |
2 | * sr.c Copyright (C) 1992 David Giller |
3 | * Copyright (C) 1993, 1994, 1995 Eric Youngdale |
4 | * |
5 | * adapted from: |
6 | * sd.c Copyright (C) 1992 Drew Eckhardt |
7 | * Linux scsi disk driver by |
8 | * Drew Eckhardt <drew@colorado.edu> |
9 | * |
10 | * Modified by Eric Youngdale ericy@cais.com to |
11 | * add scatter-gather, multiple outstanding request, and other |
12 | * enhancements. |
13 | * |
14 | * Modified by Eric Youngdale eric@aib.com to support loadable |
15 | * low-level scsi drivers. |
16 | * |
17 | * Modified by Thomas Quinot thomas@melchior.cuivre.fdn.fr to |
18 | * provide auto-eject. |
19 | * |
20 | */ |
21 | |
22 | #include <linux/module.h> |
23 | |
24 | #include <linux/fs.h> |
25 | #include <linux/kernel.h> |
26 | #include <linux/sched.h> |
27 | #include <linux/mm.h> |
28 | #include <linux/string.h> |
29 | #include <linux/errno.h> |
30 | #include <linux/cdrom.h> |
31 | #include <linux/interrupt.h> |
32 | #include <asm/system.h> |
33 | |
34 | #define MAJOR_NR11 SCSI_CDROM_MAJOR11 |
35 | #include <linux/blk.h> |
36 | #include "scsi.h" |
37 | #include "hosts.h" |
38 | #include "sr.h" |
39 | #include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */ |
40 | #include "constants.h" |
41 | |
42 | #define MAX_RETRIES3 3 |
43 | #define SR_TIMEOUT(30 * 100) (30 * HZ100) |
44 | |
45 | static int sr_init(void); |
46 | static void sr_finish(void); |
47 | static int sr_attach(Scsi_Device *); |
48 | static int sr_detect(Scsi_Device *); |
49 | static void sr_detach(Scsi_Device *); |
50 | |
51 | struct Scsi_Device_Template sr_template = {NULL((void *) 0), "cdrom", "sr", NULL((void *) 0), TYPE_ROM0x05, |
52 | SCSI_CDROM_MAJOR11, 0, 0, 0, 1, |
53 | sr_detect, sr_init, |
54 | sr_finish, sr_attach, sr_detach}; |
55 | |
56 | Scsi_CD * scsi_CDs = NULL((void *) 0); |
57 | static int * sr_sizes; |
58 | |
59 | static int * sr_blocksizes; |
60 | |
61 | static int sr_open(struct inode *, struct file *); |
62 | void get_sectorsize(int); |
63 | void sr_photocd(struct inode *); |
64 | |
65 | extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
66 | |
67 | void requeue_sr_request (Scsi_Cmnd * SCpnt); |
68 | static int check_cdrom_media_change(kdev_t); |
69 | |
70 | static void sr_release(struct inode * inode, struct file * file) |
71 | { |
72 | sync_dev(inode->i_rdev); |
73 | if(! --scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->access_count) |
74 | { |
75 | sr_ioctl(inode, NULL((void *) 0), SCSI_IOCTL_DOORUNLOCK0x5381, 0); |
76 | if (scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].auto_eject) |
77 | sr_ioctl(inode, NULL((void *) 0), CDROMEJECT0x5309, 0); |
78 | } |
79 | if (scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->host->hostt->usage_count) |
80 | (*scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->host->hostt->usage_count)--; |
81 | if(sr_template.usage_count) (*sr_template.usage_count)--; |
82 | } |
83 | |
84 | static struct file_operations sr_fops = |
85 | { |
86 | NULL((void *) 0), /* lseek - default */ |
87 | block_read, /* read - general block-dev read */ |
88 | block_write, /* write - general block-dev write */ |
89 | NULL((void *) 0), /* readdir - bad */ |
90 | NULL((void *) 0), /* select */ |
91 | sr_ioctl, /* ioctl */ |
92 | NULL((void *) 0), /* mmap */ |
93 | sr_open, /* special open code */ |
94 | sr_release, /* release */ |
95 | NULL((void *) 0), /* fsync */ |
96 | NULL((void *) 0), /* fasync */ |
97 | check_cdrom_media_change, /* Disk change */ |
98 | NULL((void *) 0) /* revalidate */ |
99 | }; |
100 | |
101 | /* |
102 | * This function checks to see if the media has been changed in the |
103 | * CDROM drive. It is possible that we have already sensed a change, |
104 | * or the drive may have sensed one and not yet reported it. We must |
105 | * be ready for either case. This function always reports the current |
106 | * value of the changed bit. If flag is 0, then the changed bit is reset. |
107 | * This function could be done as an ioctl, but we would need to have |
108 | * an inode for that to work, and we do not always have one. |
109 | */ |
110 | |
111 | int check_cdrom_media_change(kdev_t full_dev){ |
112 | int retval, target; |
113 | struct inode inode; |
114 | int flag = 0; |
115 | |
116 | target = MINOR(full_dev)((full_dev) & ((1<<8) - 1)); |
117 | |
118 | if (target >= sr_template.nr_dev) { |
119 | printk("CD-ROM request error: invalid device.\n"); |
120 | return 0; |
121 | }; |
122 | |
123 | inode.i_rdev = full_dev; /* This is all we really need here */ |
124 | retval = sr_ioctl(&inode, NULL((void *) 0), SCSI_IOCTL_TEST_UNIT_READY2, 0); |
125 | |
126 | if(retval){ /* Unable to test, unit probably not ready. This usually |
127 | * means there is no disc in the drive. Mark as changed, |
128 | * and we will figure it out later once the drive is |
129 | * available again. */ |
130 | |
131 | scsi_CDs[target].device->changed = 1; |
132 | return 1; /* This will force a flush, if called from |
133 | * check_disk_change */ |
134 | }; |
135 | |
136 | retval = scsi_CDs[target].device->changed; |
137 | if(!flag) { |
138 | scsi_CDs[target].device->changed = 0; |
139 | /* If the disk changed, the capacity will now be different, |
140 | * so we force a re-read of this information */ |
141 | if (retval) scsi_CDs[target].needs_sector_size = 1; |
142 | }; |
143 | return retval; |
144 | } |
145 | |
146 | /* |
147 | * rw_intr is the interrupt routine for the device driver. It will be notified on the |
148 | * end of a SCSI read / write, and will take on of several actions based on success or failure. |
149 | */ |
150 | |
151 | static void rw_intr (Scsi_Cmnd * SCpnt) |
152 | { |
153 | int result = SCpnt->result; |
154 | int this_count = SCpnt->this_count; |
155 | int good_sectors = (result == 0 ? this_count : 0); |
156 | int block_sectors = 0; |
157 | |
158 | #ifdef DEBUG |
159 | printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data); |
160 | #endif |
161 | /* |
162 | Handle MEDIUM ERRORs or VOLUME OVERFLOWs that indicate partial success. |
163 | Since this is a relatively rare error condition, no care is taken to |
164 | avoid unnecessary additional work such as memcpy's that could be avoided. |
165 | */ |
166 | |
167 | if (driver_byte(result)(((result) >> 24) & 0xff) != 0 && /* An error occurred */ |
168 | SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */ |
169 | (SCpnt->sense_buffer[2] == MEDIUM_ERROR0x03 || |
170 | SCpnt->sense_buffer[2] == VOLUME_OVERFLOW0x0d || |
171 | SCpnt->sense_buffer[2] == ILLEGAL_REQUEST0x05)) |
172 | { |
173 | long error_sector = (SCpnt->sense_buffer[3] << 24) | |
174 | (SCpnt->sense_buffer[4] << 16) | |
175 | (SCpnt->sense_buffer[5] << 8) | |
176 | SCpnt->sense_buffer[6]; |
177 | int device_nr = DEVICE_NR(SCpnt->request.rq_dev)(((SCpnt->request.rq_dev) & ((1<<8) - 1))); |
178 | if (SCpnt->request.bh != NULL((void *) 0)) |
179 | block_sectors = SCpnt->request.bh->b_size >> 9; |
180 | if (block_sectors < 4) block_sectors = 4; |
181 | if (scsi_CDs[device_nr].sector_size == 2048) |
182 | error_sector <<= 2; |
183 | error_sector &= ~ (block_sectors - 1); |
184 | good_sectors = error_sector - SCpnt->request.sector; |
185 | if (good_sectors < 0 || good_sectors >= this_count) |
186 | good_sectors = 0; |
187 | /* |
188 | The SCSI specification allows for the value returned by READ |
189 | CAPACITY to be up to 75 2K sectors past the last readable |
190 | block. Therefore, if we hit a medium error within the last |
191 | 75 2K sectors, we decrease the saved size value. |
192 | */ |
193 | if ((error_sector >> 1) < sr_sizes[device_nr] && |
194 | scsi_CDs[device_nr].capacity - error_sector < 4*75) |
195 | sr_sizes[device_nr] = error_sector >> 1; |
196 | } |
197 | |
198 | if (good_sectors > 0) |
199 | { /* Some sectors were read successfully. */ |
200 | if (SCpnt->use_sg == 0) { |
201 | if (SCpnt->buffer != SCpnt->request.buffer) |
202 | { |
203 | int offset; |
204 | offset = (SCpnt->request.sector % 4) << 9; |
205 | memcpy((char *)SCpnt->request.buffer,(__builtin_constant_p(good_sectors << 9) ? __constant_memcpy (((char *)SCpnt->request.buffer),((char *)SCpnt->buffer + offset),(good_sectors << 9)) : __memcpy(((char *)SCpnt ->request.buffer),((char *)SCpnt->buffer + offset),(good_sectors << 9))) |
206 | (char *)SCpnt->buffer + offset,(__builtin_constant_p(good_sectors << 9) ? __constant_memcpy (((char *)SCpnt->request.buffer),((char *)SCpnt->buffer + offset),(good_sectors << 9)) : __memcpy(((char *)SCpnt ->request.buffer),((char *)SCpnt->buffer + offset),(good_sectors << 9))) |
207 | good_sectors << 9)(__builtin_constant_p(good_sectors << 9) ? __constant_memcpy (((char *)SCpnt->request.buffer),((char *)SCpnt->buffer + offset),(good_sectors << 9)) : __memcpy(((char *)SCpnt ->request.buffer),((char *)SCpnt->buffer + offset),(good_sectors << 9))); |
208 | /* Even though we are not using scatter-gather, we look |
209 | * ahead and see if there is a linked request for the |
210 | * other half of this buffer. If there is, then satisfy |
211 | * it. */ |
212 | if((offset == 0) && good_sectors == 2 && |
213 | SCpnt->request.nr_sectors > good_sectors && |
214 | SCpnt->request.bh && |
215 | SCpnt->request.bh->b_reqnext && |
216 | SCpnt->request.bh->b_reqnext->b_size == 1024) { |
217 | memcpy((char *)SCpnt->request.bh->b_reqnext->b_data,(__builtin_constant_p(1024) ? __constant_memcpy(((char *)SCpnt ->request.bh->b_reqnext->b_data),((char *)SCpnt-> buffer + 1024),(1024)) : __memcpy(((char *)SCpnt->request. bh->b_reqnext->b_data),((char *)SCpnt->buffer + 1024 ),(1024))) |
218 | (char *)SCpnt->buffer + 1024,(__builtin_constant_p(1024) ? __constant_memcpy(((char *)SCpnt ->request.bh->b_reqnext->b_data),((char *)SCpnt-> buffer + 1024),(1024)) : __memcpy(((char *)SCpnt->request. bh->b_reqnext->b_data),((char *)SCpnt->buffer + 1024 ),(1024))) |
219 | 1024)(__builtin_constant_p(1024) ? __constant_memcpy(((char *)SCpnt ->request.bh->b_reqnext->b_data),((char *)SCpnt-> buffer + 1024),(1024)) : __memcpy(((char *)SCpnt->request. bh->b_reqnext->b_data),((char *)SCpnt->buffer + 1024 ),(1024))); |
220 | good_sectors += 2; |
221 | }; |
222 | |
223 | scsi_free(SCpnt->buffer, 2048); |
224 | } |
225 | } else { |
226 | struct scatterlist * sgpnt; |
227 | int i; |
228 | sgpnt = (struct scatterlist *) SCpnt->buffer; |
229 | for(i=0; i<SCpnt->use_sg; i++) { |
230 | if (sgpnt[i].alt_address) { |
231 | if (sgpnt[i].alt_address != sgpnt[i].address) { |
232 | memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length)(__builtin_constant_p(sgpnt[i].length) ? __constant_memcpy((sgpnt [i].alt_address),(sgpnt[i].address),(sgpnt[i].length)) : __memcpy ((sgpnt[i].alt_address),(sgpnt[i].address),(sgpnt[i].length)) ); |
233 | }; |
234 | scsi_free(sgpnt[i].address, sgpnt[i].length); |
235 | }; |
236 | }; |
237 | scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */ |
238 | if(SCpnt->request.sector % 4) good_sectors -= 2; |
239 | /* See if there is a padding record at the end that needs to be removed */ |
240 | if(good_sectors > SCpnt->request.nr_sectors) |
241 | good_sectors -= 2; |
242 | }; |
243 | |
244 | #ifdef DEBUG |
245 | printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors, |
246 | good_sectors); |
247 | #endif |
248 | if (SCpnt->request.nr_sectors > this_count) |
249 | { |
250 | SCpnt->request.errors = 0; |
251 | if (!SCpnt->request.bh) |
252 | panic("sr.c: linked page request (%lx %x)", |
253 | SCpnt->request.sector, this_count); |
254 | } |
255 | |
256 | SCpnt = end_scsi_request(SCpnt, 1, good_sectors); /* All done */ |
257 | if (result == 0) |
258 | { |
259 | requeue_sr_request(SCpnt); |
260 | return; |
261 | } |
262 | } |
263 | |
264 | if (good_sectors == 0) { |
265 | /* We only come through here if no sectors were read successfully. */ |
266 | |
267 | /* Free up any indirection buffers we allocated for DMA purposes. */ |
268 | if (SCpnt->use_sg) { |
269 | struct scatterlist * sgpnt; |
270 | int i; |
271 | sgpnt = (struct scatterlist *) SCpnt->buffer; |
272 | for(i=0; i<SCpnt->use_sg; i++) { |
273 | if (sgpnt[i].alt_address) { |
274 | scsi_free(sgpnt[i].address, sgpnt[i].length); |
275 | } |
276 | } |
277 | scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */ |
278 | } else { |
279 | if (SCpnt->buffer != SCpnt->request.buffer) |
280 | scsi_free(SCpnt->buffer, SCpnt->bufflen); |
281 | } |
282 | |
283 | } |
284 | |
285 | if (driver_byte(result)(((result) >> 24) & 0xff) != 0) { |
286 | if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) { |
287 | if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION0x06) { |
288 | /* detected disc change. set a bit and quietly refuse |
289 | * further access. */ |
290 | |
291 | scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)(((SCpnt->request.rq_dev) & ((1<<8) - 1)))].device->changed = 1; |
292 | SCpnt = end_scsi_request(SCpnt, 0, this_count); |
293 | requeue_sr_request(SCpnt); |
294 | return; |
295 | } |
296 | } |
297 | |
298 | if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST0x05) { |
299 | printk("CD-ROM error: "); |
300 | print_sense("sr", SCpnt); |
301 | printk("command was: "); |
302 | print_command(SCpnt->cmnd); |
303 | if (scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)(((SCpnt->request.rq_dev) & ((1<<8) - 1)))].ten) { |
304 | scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)(((SCpnt->request.rq_dev) & ((1<<8) - 1)))].ten = 0; |
305 | requeue_sr_request(SCpnt); |
306 | result = 0; |
307 | return; |
308 | } else { |
309 | SCpnt = end_scsi_request(SCpnt, 0, this_count); |
310 | requeue_sr_request(SCpnt); /* Do next request */ |
311 | return; |
312 | } |
313 | |
314 | } |
315 | |
316 | if (SCpnt->sense_buffer[2] == NOT_READY0x02) { |
317 | printk("CD-ROM not ready. Make sure you have a disc in the drive.\n"); |
318 | SCpnt = end_scsi_request(SCpnt, 0, this_count); |
319 | requeue_sr_request(SCpnt); /* Do next request */ |
320 | return; |
321 | } |
322 | |
323 | if (SCpnt->sense_buffer[2] == MEDIUM_ERROR0x03) { |
324 | printk("scsi%d: MEDIUM ERROR on " |
325 | "channel %d, id %d, lun %d, CDB: ", |
326 | SCpnt->host->host_no, (int) SCpnt->channel, |
327 | (int) SCpnt->target, (int) SCpnt->lun); |
328 | print_command(SCpnt->cmnd); |
329 | print_sense("sr", SCpnt); |
330 | SCpnt = end_scsi_request(SCpnt, 0, block_sectors); |
331 | requeue_sr_request(SCpnt); |
332 | return; |
333 | } |
334 | |
335 | if (SCpnt->sense_buffer[2] == VOLUME_OVERFLOW0x0d) { |
336 | printk("scsi%d: VOLUME OVERFLOW on " |
337 | "channel %d, id %d, lun %d, CDB: ", |
338 | SCpnt->host->host_no, (int) SCpnt->channel, |
339 | (int) SCpnt->target, (int) SCpnt->lun); |
340 | print_command(SCpnt->cmnd); |
341 | print_sense("sr", SCpnt); |
342 | SCpnt = end_scsi_request(SCpnt, 0, block_sectors); |
343 | requeue_sr_request(SCpnt); |
344 | return; |
345 | } |
346 | } |
347 | |
348 | /* We only get this far if we have an error we have not recognized */ |
349 | if(result) { |
350 | printk("SCSI CD error : host %d id %d lun %d return code = %03x\n", |
351 | scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)(((SCpnt->request.rq_dev) & ((1<<8) - 1)))].device->host->host_no, |
352 | scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)(((SCpnt->request.rq_dev) & ((1<<8) - 1)))].device->id, |
353 | scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)(((SCpnt->request.rq_dev) & ((1<<8) - 1)))].device->lun, |
354 | result); |
355 | |
356 | if (status_byte(result)(((result) >> 1) & 0x1f) == CHECK_CONDITION0x01) |
357 | print_sense("sr", SCpnt); |
358 | |
359 | SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors); |
360 | requeue_sr_request(SCpnt); |
361 | } |
362 | } |
363 | |
364 | /* |
365 | * Here I tried to implement support for multisession-CD's |
366 | * |
367 | * Much of this has do be done with vendor-specific SCSI-commands, because |
368 | * multisession is newer than the SCSI-II standard. |
369 | * So I have to complete it step by step. Useful information is welcome. |
370 | * |
371 | * Actually works: |
372 | * - NEC: Detection and support of multisession CD's. Special handling |
373 | * for XA-disks is not necessary. |
374 | * |
375 | * - TOSHIBA: setting density is done here now, mounting PhotoCD's should |
376 | * work now without running the program "set_density" |
377 | * Multisession CD's are supported too. |
378 | * |
379 | * Gerd Knorr <kraxel@cs.tu-berlin.de> |
380 | */ |
381 | /* |
382 | * 19950704 operator@melchior.cuivre.fdn.fr (Thomas Quinot) |
383 | * |
384 | * - SONY: Same as Nec. |
385 | * |
386 | * - PIONEER: works with SONY code (may be others too ?) |
387 | */ |
388 | |
389 | void sr_photocd(struct inode *inode) |
390 | { |
391 | unsigned long sector,min,sec,frame; |
392 | unsigned char buf[40]; /* the buffer for the ioctl */ |
393 | unsigned char *cmd; /* the scsi-command */ |
394 | unsigned char *send; /* the data we send to the drive ... */ |
395 | unsigned char *rec; /* ... and get back */ |
396 | int rc,is_xa,no_multi; |
397 | |
398 | if (scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].xa_flags & 0x02) { |
399 | #ifdef DEBUG |
400 | printk(KERN_DEBUG"<7>" "sr_photocd: CDROM and/or driver do not support multisession CD's"); |
401 | #endif |
402 | return; |
403 | } |
404 | |
405 | if (!suser()) { |
406 | /* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND isn't allowed |
407 | * for me. That's why mpcd_sector will be initialized with zero, |
408 | * because I'm not able to get the right value. Necessary only if |
409 | * access_count is 1, else no disk change happened since the last |
410 | * call of this function and we can keep the old value. |
411 | */ |
412 | if (1 == scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->access_count) { |
413 | scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].mpcd_sector = 0; |
414 | scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].xa_flags &= ~0x01; |
415 | } |
416 | return; |
417 | } |
418 | |
419 | sector = 0; |
420 | is_xa = 0; |
421 | no_multi = 0; |
422 | cmd = rec = &buf[8]; |
423 | |
424 | switch(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->manufacturer) { |
425 | |
426 | case SCSI_MAN_NEC1: |
427 | #ifdef DEBUG |
428 | printk(KERN_DEBUG"<7>" "sr_photocd: use NEC code\n"); |
429 | #endif |
430 | memset(buf,0,40)(__builtin_constant_p(0) ? (__builtin_constant_p((40)) ? __constant_c_and_count_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40))) : __constant_c_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40)))) : (__builtin_constant_p ((40)) ? __memset_generic((((buf))),(((0))),(((40)))) : __memset_generic (((buf)),((0)),((40))))); |
431 | *((unsigned int*)buf) = 0x0; /* we send nothing... */ |
432 | *((unsigned int*)buf+1) = 0x16; /* and receive 0x16 bytes */ |
433 | cmd[0] = 0xde; |
434 | cmd[1] = 0x03; |
435 | cmd[2] = 0xb0; |
436 | rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device, |
437 | SCSI_IOCTL_SEND_COMMAND1, buf); |
438 | if (rc != 0) { |
439 | if (rc != 0x28000002) /* drop "not ready" */ |
440 | printk(KERN_WARNING"<4>""sr_photocd: ioctl error (NEC): 0x%x\n",rc); |
441 | break; |
442 | } |
443 | if (rec[14] != 0 && rec[14] != 0xb0) { |
444 | printk(KERN_INFO"<6>""sr_photocd: (NEC) Hmm, seems the CDROM doesn't support multisession CD's\n"); |
445 | no_multi = 1; |
446 | break; |
447 | } |
448 | min = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16; |
449 | sec = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16; |
450 | frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16; |
451 | sector = min*CD_SECS60*CD_FRAMES75 + sec*CD_FRAMES75 + frame; |
452 | is_xa = (rec[14] == 0xb0); |
453 | #ifdef DEBUG |
454 | if (sector) { |
455 | printk(KERN_DEBUG"<7>" "sr_photocd: multisession CD detected. start: %lu\n",sector); |
456 | } |
457 | #endif |
458 | break; |
459 | |
460 | case SCSI_MAN_TOSHIBA2: |
461 | #ifdef DEBUG |
462 | printk(KERN_DEBUG"<7>" "sr_photocd: use TOSHIBA code\n"); |
463 | #endif |
464 | |
465 | /* we request some disc information (is it a XA-CD ?, |
466 | * where starts the last session ?) */ |
467 | memset(buf,0,40)(__builtin_constant_p(0) ? (__builtin_constant_p((40)) ? __constant_c_and_count_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40))) : __constant_c_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40)))) : (__builtin_constant_p ((40)) ? __memset_generic((((buf))),(((0))),(((40)))) : __memset_generic (((buf)),((0)),((40))))); |
468 | *((unsigned int*)buf) = (unsigned int) 0; |
469 | *((unsigned int*)buf+1) = (unsigned int) 4; /* receive 4 bytes */ |
470 | cmd[0] = (unsigned char) 0x00c7; |
471 | cmd[1] = (unsigned char) 3; |
472 | rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device, |
473 | SCSI_IOCTL_SEND_COMMAND1, buf); |
474 | if (rc != 0) { |
475 | if (rc == 0x28000002) { |
476 | /* Got a "not ready" - error. No chance to find out if this is |
477 | * because there is no CD in the drive or because the drive |
478 | * don't knows multisession CD's. So I need to do an extra |
479 | * check... */ |
480 | if (!kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device, |
481 | SCSI_IOCTL_TEST_UNIT_READY2, NULL((void *) 0))) { |
482 | printk(KERN_INFO"<6>" "sr_photocd: (TOSHIBA) Hmm, seems the CDROM doesn't support multisession CD's\n"); |
483 | no_multi = 1; |
484 | } |
485 | } else |
486 | printk(KERN_INFO"<6>""sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc); |
487 | break; /* if the first ioctl fails, we don't call the second one */ |
488 | } |
489 | is_xa = (rec[0] == 0x20); |
490 | min = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16; |
491 | sec = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16; |
492 | frame = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16; |
493 | sector = min*CD_SECS60*CD_FRAMES75 + sec*CD_FRAMES75 + frame; |
494 | if (sector) { |
495 | sector -= CD_BLOCK_OFFSET150; |
496 | #ifdef DEBUG |
497 | printk(KERN_DEBUG"<7>" "sr_photocd: multisession CD detected: start: %lu\n",sector); |
498 | #endif |
499 | } |
500 | |
501 | /* now we do a get_density... */ |
502 | memset(buf,0,40)(__builtin_constant_p(0) ? (__builtin_constant_p((40)) ? __constant_c_and_count_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40))) : __constant_c_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40)))) : (__builtin_constant_p ((40)) ? __memset_generic((((buf))),(((0))),(((40)))) : __memset_generic (((buf)),((0)),((40))))); |
503 | *((unsigned int*)buf) = (unsigned int) 0; |
504 | *((unsigned int*)buf+1) = (unsigned int) 12; |
505 | cmd[0] = (unsigned char) MODE_SENSE0x1a; |
506 | cmd[2] = (unsigned char) 1; |
507 | cmd[4] = (unsigned char) 12; |
508 | rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device, |
509 | SCSI_IOCTL_SEND_COMMAND1, buf); |
510 | if (rc != 0) { |
511 | printk(KERN_WARNING"<4>" "sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc); |
512 | break; |
513 | } |
514 | #ifdef DEBUG |
515 | printk(KERN_DEBUG"<7>" "sr_photocd: get_density: 0x%x\n",rec[4]); |
516 | #endif |
517 | |
518 | /* ...and only if necessary a set_density */ |
519 | if ((rec[4] != 0x81 && is_xa) || (rec[4] != 0 && !is_xa)) { |
520 | #ifdef DEBUG |
521 | printk(KERN_DEBUG"<7>" "sr_photocd: doing set_density\n"); |
522 | #endif |
523 | memset(buf,0,40)(__builtin_constant_p(0) ? (__builtin_constant_p((40)) ? __constant_c_and_count_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40))) : __constant_c_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40)))) : (__builtin_constant_p ((40)) ? __memset_generic((((buf))),(((0))),(((40)))) : __memset_generic (((buf)),((0)),((40))))); |
524 | *((unsigned int*)buf) = (unsigned int) 12; /* send 12 bytes */ |
525 | *((unsigned int*)buf+1) = (unsigned int) 0; |
526 | cmd[0] = (unsigned char) MODE_SELECT0x15; |
527 | cmd[1] = (unsigned char) (1 << 4); |
528 | cmd[4] = (unsigned char) 12; |
529 | send = &cmd[6]; /* this is a 6-Byte command */ |
530 | send[ 3] = (unsigned char) 0x08; /* data for cmd */ |
531 | /* density 0x81 for XA, 0 else */ |
532 | send[ 4] = (is_xa) ? |
533 | (unsigned char) 0x81 : (unsigned char) 0; |
534 | send[10] = (unsigned char) 0x08; |
535 | rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device, |
536 | SCSI_IOCTL_SEND_COMMAND1, buf); |
537 | if (rc != 0) { |
538 | printk(KERN_WARNING"<4>" "sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc); |
539 | } |
540 | /* The set_density command may have changed the |
541 | * sector size or capacity. */ |
542 | scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].needs_sector_size = 1; |
543 | } |
544 | break; |
545 | |
546 | case SCSI_MAN_SONY4: /* Thomas QUINOT <thomas@melchior.cuivre.fdn.fr> */ |
547 | case SCSI_MAN_PIONEER5: |
548 | case SCSI_MAN_UNKNOWN0: |
549 | #ifdef DEBUG |
550 | printk(KERN_DEBUG"<7>" "sr_photocd: use SONY/PIONEER code\n"); |
551 | #endif |
552 | get_sectorsize(MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))); /* spinup (avoid timeout) */ |
553 | memset(buf,0,40)(__builtin_constant_p(0) ? (__builtin_constant_p((40)) ? __constant_c_and_count_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40))) : __constant_c_memset (((buf)),((0x01010101UL*(unsigned char)(0))),((40)))) : (__builtin_constant_p ((40)) ? __memset_generic((((buf))),(((0))),(((40)))) : __memset_generic (((buf)),((0)),((40))))); |
554 | *((unsigned int*)buf) = 0x0; /* we send nothing... */ |
555 | *((unsigned int*)buf+1) = 0x0c; /* and receive 0x0c bytes */ |
556 | cmd[0] = READ_TOC0x43; |
557 | cmd[8] = 0x0c; |
558 | cmd[9] = 0x40; |
559 | rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device, |
560 | SCSI_IOCTL_SEND_COMMAND1, buf); |
561 | |
562 | if (rc != 0) { |
563 | if (rc != 0x28000002) /* drop "not ready" */ |
564 | printk(KERN_WARNING"<4>" "sr_photocd: ioctl error (SONY/PIONEER): 0x%x\n",rc); |
565 | break; |
566 | } |
567 | if ((rec[0] << 8) + rec[1] < 0x0a) { |
568 | printk(KERN_INFO"<6>" "sr_photocd: (SONY/PIONEER) Hmm, seems the CDROM doesn't support multisession CD's\n"); |
569 | no_multi = 1; |
570 | break; |
571 | } |
572 | sector = rec[11] + (rec[10] << 8) + (rec[9] << 16) + (rec[8] << 24); |
573 | is_xa = !!sector; |
574 | #ifdef DEBUG |
575 | if (sector) |
576 | printk (KERN_DEBUG"<7>" "sr_photocd: multisession CD detected. start: %lu\n",sector); |
577 | #endif |
578 | break; |
579 | |
580 | case SCSI_MAN_NEC_OLDCDR3: |
581 | default: |
582 | sector = 0; |
583 | no_multi = 1; |
584 | break; } |
585 | |
586 | scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].mpcd_sector = sector; |
587 | if (is_xa) |
588 | scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].xa_flags |= 0x01; |
589 | else |
590 | scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].xa_flags &= ~0x01; |
591 | if (no_multi) |
592 | scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].xa_flags |= 0x02; |
593 | return; |
594 | } |
595 | |
596 | static int sr_open(struct inode * inode, struct file * filp) |
597 | { |
598 | if(MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1)) >= sr_template.nr_dev || |
599 | !scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device) return -ENXIO6; /* No such device */ |
600 | |
601 | if (filp->f_mode & 2) |
602 | return -EROFS30; |
603 | |
604 | if(sr_template.usage_count) (*sr_template.usage_count)++; |
605 | |
606 | sr_ioctl(inode,filp,CDROMCLOSETRAY0x5319,0); |
607 | check_disk_change(inode->i_rdev); |
608 | |
609 | if(!scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->access_count++) |
610 | sr_ioctl(inode, NULL((void *) 0), SCSI_IOCTL_DOORLOCK0x5380, 0); |
611 | if (scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->host->hostt->usage_count) |
612 | (*scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].device->host->hostt->usage_count)++; |
613 | |
614 | sr_photocd(inode); |
615 | |
616 | /* If this device did not have media in the drive at boot time, then |
617 | * we would have been unable to get the sector size. Check to see if |
618 | * this is the case, and try again. |
619 | */ |
620 | |
621 | if(scsi_CDs[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))].needs_sector_size) |
622 | get_sectorsize(MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))); |
623 | |
624 | return 0; |
625 | } |
626 | |
627 | |
628 | /* |
629 | * do_sr_request() is the request handler function for the sr driver. |
630 | * Its function in life is to take block device requests, and |
631 | * translate them to SCSI commands. |
632 | */ |
633 | |
634 | static void do_sr_request (void) |
635 | { |
636 | Scsi_Cmnd * SCpnt = NULL((void *) 0); |
637 | struct request * req = NULL((void *) 0); |
638 | Scsi_Device * SDev; |
639 | unsigned long flags; |
640 | int flag = 0; |
641 | |
642 | while (1==1){ |
643 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); |
644 | cli()__asm__ __volatile__ ("cli": : :"memory"); |
645 | if (CURRENT(blk_dev[11].current_request) != NULL((void *) 0) && CURRENT(blk_dev[11].current_request)->rq_status == RQ_INACTIVE(-1)) { |
646 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); |
647 | return; |
648 | }; |
649 | |
650 | INIT_SCSI_REQUESTif (!(blk_dev[11].current_request)) { (do_sr = (((void *) 0)) ); __asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory" ); return; } if ((((blk_dev[11].current_request)->rq_dev) >> 8) != 11) panic("CD-ROM" ": request list destroyed"); if ((blk_dev [11].current_request)->bh) { if (!buffer_locked((blk_dev[11 ].current_request)->bh)) panic("CD-ROM" ": block not locked" ); }; |
651 | |
652 | SDev = scsi_CDs[DEVICE_NR(CURRENT->rq_dev)((((blk_dev[11].current_request)->rq_dev) & ((1<< 8) - 1)))].device; |
653 | |
654 | /* |
655 | * I am not sure where the best place to do this is. We need |
656 | * to hook in a place where we are likely to come if in user |
657 | * space. |
658 | */ |
659 | if( SDev->was_reset ) |
660 | { |
661 | /* |
662 | * We need to relock the door, but we might |
663 | * be in an interrupt handler. Only do this |
664 | * from user space, since we do not want to |
665 | * sleep from an interrupt. |
666 | */ |
667 | if( SDev->removable && !intr_count ) |
668 | { |
669 | scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK0x5380, 0); |
670 | } |
671 | SDev->was_reset = 0; |
672 | } |
673 | |
674 | if (flag++ == 0) |
675 | SCpnt = allocate_device(&CURRENT(blk_dev[11].current_request), |
676 | scsi_CDs[DEVICE_NR(CURRENT->rq_dev)((((blk_dev[11].current_request)->rq_dev) & ((1<< 8) - 1)))].device, 0); |
677 | else SCpnt = NULL((void *) 0); |
678 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); |
679 | |
680 | /* This is a performance enhancement. We dig down into the request list and |
681 | * try to find a queueable request (i.e. device not busy, and host able to |
682 | * accept another command. If we find one, then we queue it. This can |
683 | * make a big difference on systems with more than one disk drive. We want |
684 | * to have the interrupts off when monkeying with the request list, because |
685 | * otherwise the kernel might try to slip in a request in between somewhere. */ |
686 | |
687 | if (!SCpnt && sr_template.nr_dev > 1){ |
688 | struct request *req1; |
689 | req1 = NULL((void *) 0); |
690 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); |
691 | cli()__asm__ __volatile__ ("cli": : :"memory"); |
692 | req = CURRENT(blk_dev[11].current_request); |
693 | while(req){ |
694 | SCpnt = request_queueable(req, |
695 | scsi_CDs[DEVICE_NR(req->rq_dev)(((req->rq_dev) & ((1<<8) - 1)))].device); |
696 | if(SCpnt) break; |
697 | req1 = req; |
698 | req = req->next; |
699 | }; |
700 | if (SCpnt && req->rq_status == RQ_INACTIVE(-1)) { |
701 | if (req == CURRENT(blk_dev[11].current_request)) |
702 | CURRENT(blk_dev[11].current_request) = CURRENT(blk_dev[11].current_request)->next; |
703 | else |
704 | req1->next = req->next; |
705 | }; |
706 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); |
707 | }; |
708 | |
709 | if (!SCpnt) |
710 | return; /* Could not find anything to do */ |
711 | |
712 | wake_up(&wait_for_request); |
713 | |
714 | /* Queue command */ |
715 | requeue_sr_request(SCpnt); |
716 | }; /* While */ |
717 | } |
718 | |
719 | void requeue_sr_request (Scsi_Cmnd * SCpnt) |
720 | { |
721 | unsigned int dev, block, realcount; |
722 | unsigned char cmd[10], *buffer, tries; |
723 | int this_count, start, end_rec; |
724 | |
725 | tries = 2; |
726 | |
727 | repeat: |
728 | if(!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE(-1)) { |
729 | do_sr_request(); |
730 | return; |
731 | } |
732 | |
733 | dev = MINOR(SCpnt->request.rq_dev)((SCpnt->request.rq_dev) & ((1<<8) - 1)); |
734 | block = SCpnt->request.sector; |
735 | buffer = NULL((void *) 0); |
736 | this_count = 0; |
737 | |
738 | if (dev >= sr_template.nr_dev) { |
739 | /* printk("CD-ROM request error: invalid device.\n"); */ |
740 | SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); |
741 | tries = 2; |
742 | goto repeat; |
743 | } |
744 | |
745 | if (!scsi_CDs[dev].use) { |
746 | /* printk("CD-ROM request error: device marked not in use.\n"); */ |
747 | SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); |
748 | tries = 2; |
Value stored to 'tries' is never read | |
749 | goto repeat; |
750 | } |
751 | |
752 | if (scsi_CDs[dev].device->changed) { |
753 | /* |
754 | * quietly refuse to do anything to a changed disc |
755 | * until the changed bit has been reset |
756 | */ |
757 | /* printk("CD-ROM has been changed. Prohibiting further I/O.\n"); */ |
758 | SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); |
759 | tries = 2; |
760 | goto repeat; |
761 | } |
762 | |
763 | switch (SCpnt->request.cmd) |
764 | { |
765 | case WRITE1: |
766 | SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors); |
767 | goto repeat; |
768 | break; |
769 | case READ0 : |
770 | cmd[0] = READ_60x08; |
771 | break; |
772 | default : |
773 | panic ("Unknown sr command %d\n", SCpnt->request.cmd); |
774 | } |
775 | |
776 | cmd[1] = (SCpnt->lun << 5) & 0xe0; |
777 | |
778 | /* |
779 | * Now do the grungy work of figuring out which sectors we need, and |
780 | * where in memory we are going to put them. |
781 | * |
782 | * The variables we need are: |
783 | * |
784 | * this_count= number of 512 byte sectors being read |
785 | * block = starting cdrom sector to read. |
786 | * realcount = # of cdrom sectors to read |
787 | * |
788 | * The major difference between a scsi disk and a scsi cdrom |
789 | * is that we will always use scatter-gather if we can, because we can |
790 | * work around the fact that the buffer cache has a block size of 1024, |
791 | * and we have 2048 byte sectors. This code should work for buffers that |
792 | * are any multiple of 512 bytes long. |
793 | */ |
794 | |
795 | SCpnt->use_sg = 0; |
796 | |
797 | if (SCpnt->host->sg_tablesize > 0 && |
798 | (!need_isa_buffer || |
799 | dma_free_sectors >= 10)) { |
800 | struct buffer_head * bh; |
801 | struct scatterlist * sgpnt; |
802 | int count, this_count_max; |
803 | bh = SCpnt->request.bh; |
804 | this_count = 0; |
805 | count = 0; |
806 | this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4; |
807 | /* Calculate how many links we can use. First see if we need |
808 | * a padding record at the start */ |
809 | this_count = SCpnt->request.sector % 4; |
810 | if(this_count) count++; |
811 | while(bh && count < SCpnt->host->sg_tablesize) { |
812 | if ((this_count + (bh->b_size >> 9)) > this_count_max) break; |
813 | this_count += (bh->b_size >> 9); |
814 | count++; |
815 | bh = bh->b_reqnext; |
816 | }; |
817 | /* Fix up in case of an odd record at the end */ |
818 | end_rec = 0; |
819 | if(this_count % 4) { |
820 | if (count < SCpnt->host->sg_tablesize) { |
821 | count++; |
822 | end_rec = (4 - (this_count % 4)) << 9; |
823 | this_count += 4 - (this_count % 4); |
824 | } else { |
825 | count--; |
826 | this_count -= (this_count % 4); |
827 | }; |
828 | }; |
829 | SCpnt->use_sg = count; /* Number of chains */ |
830 | /* scsi_malloc can only allocate in chunks of 512 bytes */ |
831 | count = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511; |
832 | |
833 | SCpnt->sglist_len = count; |
834 | sgpnt = (struct scatterlist * ) scsi_malloc(count); |
835 | if (!sgpnt) { |
836 | printk("Warning - running *really* short on DMA buffers\n"); |
837 | SCpnt->use_sg = 0; /* No memory left - bail out */ |
838 | } else { |
839 | buffer = (unsigned char *) sgpnt; |
840 | count = 0; |
841 | bh = SCpnt->request.bh; |
842 | if(SCpnt->request.sector % 4) { |
843 | sgpnt[count].length = (SCpnt->request.sector % 4) << 9; |
844 | sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length); |
845 | if(!sgpnt[count].address) panic("SCSI DMA pool exhausted."); |
846 | sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete |
847 | if needed */ |
848 | count++; |
849 | }; |
850 | for(bh = SCpnt->request.bh; count < SCpnt->use_sg; |
851 | count++, bh = bh->b_reqnext) { |
852 | if (bh) { /* Need a placeholder at the end of the record? */ |
853 | sgpnt[count].address = bh->b_data; |
854 | sgpnt[count].length = bh->b_size; |
855 | sgpnt[count].alt_address = NULL((void *) 0); |
856 | } else { |
857 | sgpnt[count].address = (char *) scsi_malloc(end_rec); |
858 | if(!sgpnt[count].address) panic("SCSI DMA pool exhausted."); |
859 | sgpnt[count].length = end_rec; |
860 | sgpnt[count].alt_address = sgpnt[count].address; |
861 | if (count+1 != SCpnt->use_sg) panic("Bad sr request list"); |
862 | break; |
863 | }; |
864 | if (((long) sgpnt[count].address) + sgpnt[count].length - 1 > |
865 | ISA_DMA_THRESHOLD(0x00ffffff) && SCpnt->host->unchecked_isa_dma) { |
866 | sgpnt[count].alt_address = sgpnt[count].address; |
867 | /* We try to avoid exhausting the DMA pool, since it is easier |
868 | * to control usage here. In other places we might have a more |
869 | * pressing need, and we would be screwed if we ran out */ |
870 | if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) { |
871 | sgpnt[count].address = NULL((void *) 0); |
872 | } else { |
873 | sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length); |
874 | }; |
875 | /* If we start running low on DMA buffers, we abort the scatter-gather |
876 | * operation, and free all of the memory we have allocated. We want to |
877 | * ensure that all scsi operations are able to do at least a non-scatter/gather |
878 | * operation */ |
879 | if(sgpnt[count].address == NULL((void *) 0)){ /* Out of dma memory */ |
880 | printk("Warning: Running low on SCSI DMA buffers"); |
881 | /* Try switching back to a non scatter-gather operation. */ |
882 | while(--count >= 0){ |
883 | if(sgpnt[count].alt_address) |
884 | scsi_free(sgpnt[count].address, sgpnt[count].length); |
885 | }; |
886 | SCpnt->use_sg = 0; |
887 | scsi_free(buffer, SCpnt->sglist_len); |
888 | break; |
889 | }; /* if address == NULL */ |
890 | }; /* if need DMA fixup */ |
891 | }; /* for loop to fill list */ |
892 | #ifdef DEBUG |
893 | printk("SR: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector, |
894 | this_count, |
895 | SCpnt->request.current_nr_sectors, |
896 | SCpnt->request.nr_sectors); |
897 | for(count=0; count<SCpnt->use_sg; count++) |
898 | printk("SGlist: %d %x %x %x\n", count, |
899 | sgpnt[count].address, |
900 | sgpnt[count].alt_address, |
901 | sgpnt[count].length); |
902 | #endif |
903 | }; /* Able to allocate scatter-gather list */ |
904 | }; |
905 | |
906 | if (SCpnt->use_sg == 0){ |
907 | /* We cannot use scatter-gather. Do this the old fashion way */ |
908 | if (!SCpnt->request.bh) |
909 | this_count = SCpnt->request.nr_sectors; |
910 | else |
911 | this_count = (SCpnt->request.bh->b_size >> 9); |
912 | |
913 | start = block % 4; |
914 | if (start) |
915 | { |
916 | this_count = ((this_count > 4 - start) ? |
917 | (4 - start) : (this_count)); |
918 | buffer = (unsigned char *) scsi_malloc(2048); |
919 | } |
920 | else if (this_count < 4) |
921 | { |
922 | buffer = (unsigned char *) scsi_malloc(2048); |
923 | } |
924 | else |
925 | { |
926 | this_count -= this_count % 4; |
927 | buffer = (unsigned char *) SCpnt->request.buffer; |
928 | if (((long) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD(0x00ffffff) && |
929 | SCpnt->host->unchecked_isa_dma) |
930 | buffer = (unsigned char *) scsi_malloc(this_count << 9); |
931 | } |
932 | }; |
933 | |
934 | if (scsi_CDs[dev].sector_size == 2048) |
935 | block = block >> 2; /* These are the sectors that the cdrom uses */ |
936 | else |
937 | block = block & 0xfffffffc; |
938 | |
939 | realcount = (this_count + 3) / 4; |
940 | |
941 | if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2; |
942 | |
943 | if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) |
944 | { |
945 | if (realcount > 0xffff) |
946 | { |
947 | realcount = 0xffff; |
948 | this_count = realcount * (scsi_CDs[dev].sector_size >> 9); |
949 | } |
950 | |
951 | cmd[0] += READ_100x28 - READ_60x08 ; |
952 | cmd[2] = (unsigned char) (block >> 24) & 0xff; |
953 | cmd[3] = (unsigned char) (block >> 16) & 0xff; |
954 | cmd[4] = (unsigned char) (block >> 8) & 0xff; |
955 | cmd[5] = (unsigned char) block & 0xff; |
956 | cmd[6] = cmd[9] = 0; |
957 | cmd[7] = (unsigned char) (realcount >> 8) & 0xff; |
958 | cmd[8] = (unsigned char) realcount & 0xff; |
959 | } |
960 | else |
961 | { |
962 | if (realcount > 0xff) |
963 | { |
964 | realcount = 0xff; |
965 | this_count = realcount * (scsi_CDs[dev].sector_size >> 9); |
966 | } |
967 | |
968 | cmd[1] |= (unsigned char) ((block >> 16) & 0x1f); |
969 | cmd[2] = (unsigned char) ((block >> 8) & 0xff); |
970 | cmd[3] = (unsigned char) block & 0xff; |
971 | cmd[4] = (unsigned char) realcount; |
972 | cmd[5] = 0; |
973 | } |
974 | |
975 | #ifdef DEBUG |
976 | { |
977 | int i; |
978 | printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count); |
979 | printk("Use sg: %d\n", SCpnt->use_sg); |
980 | printk("Dumping command: "); |
981 | for(i=0; i<12; i++) printk("%2.2x ", cmd[i]); |
982 | printk("\n"); |
983 | }; |
984 | #endif |
985 | |
986 | /* Some dumb host adapters can speed transfers by knowing the |
987 | * minimum transfersize in advance. |
988 | * |
989 | * We shouldn't disconnect in the middle of a sector, but the cdrom |
990 | * sector size can be larger than the size of a buffer and the |
991 | * transfer may be split to the size of a buffer. So it's safe to |
992 | * assume that we can at least transfer the minimum of the buffer |
993 | * size (1024) and the sector size between each connect / disconnect. |
994 | */ |
995 | |
996 | SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ? |
997 | 1024 : scsi_CDs[dev].sector_size; |
998 | |
999 | SCpnt->this_count = this_count; |
1000 | scsi_do_cmd (SCpnt, (void *) cmd, buffer, |
1001 | realcount * scsi_CDs[dev].sector_size, |
1002 | rw_intr, SR_TIMEOUT(30 * 100), MAX_RETRIES3); |
1003 | } |
1004 | |
1005 | static int sr_detect(Scsi_Device * SDp){ |
1006 | |
1007 | if(SDp->type != TYPE_ROM0x05 && SDp->type != TYPE_WORM0x04) return 0; |
1008 | |
1009 | #ifdef MACH1 |
1010 | printk("Detected scsi CD-ROM cd%d at scsi%d, channel %d, id %d, lun %d\n", |
1011 | #else |
1012 | printk("Detected scsi CD-ROM sr%d at scsi%d, channel %d, id %d, lun %d\n", |
1013 | #endif |
1014 | sr_template.dev_noticed++, |
1015 | SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); |
1016 | |
1017 | return 1; |
1018 | } |
1019 | |
1020 | static int sr_attach(Scsi_Device * SDp){ |
1021 | Scsi_CD * cpnt; |
1022 | int i; |
1023 | |
1024 | if(SDp->type != TYPE_ROM0x05 && SDp->type != TYPE_WORM0x04) return 1; |
1025 | |
1026 | if (sr_template.nr_dev >= sr_template.dev_max) |
1027 | { |
1028 | SDp->attached--; |
1029 | return 1; |
1030 | } |
1031 | |
1032 | for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) |
1033 | if(!cpnt->device) break; |
1034 | |
1035 | if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)"); |
1036 | |
1037 | SDp->scsi_request_fn = do_sr_request; |
1038 | scsi_CDs[i].device = SDp; |
1039 | sr_template.nr_dev++; |
1040 | if(sr_template.nr_dev > sr_template.dev_max) |
1041 | panic ("scsi_devices corrupt (sr)"); |
1042 | return 0; |
1043 | } |
1044 | |
1045 | |
1046 | static void sr_init_done (Scsi_Cmnd * SCpnt) |
1047 | { |
1048 | struct request * req; |
1049 | |
1050 | req = &SCpnt->request; |
1051 | req->rq_status = RQ_SCSI_DONE0xfffe; /* Busy, but indicate request done */ |
1052 | |
1053 | if (req->sem != NULL((void *) 0)) { |
1054 | up(req->sem); |
1055 | } |
1056 | } |
1057 | |
1058 | void get_sectorsize(int i){ |
1059 | unsigned char cmd[10]; |
1060 | unsigned char *buffer; |
1061 | int the_result, retries; |
1062 | Scsi_Cmnd * SCpnt; |
1063 | |
1064 | buffer = (unsigned char *) scsi_malloc(512); |
1065 | SCpnt = allocate_device(NULL((void *) 0), scsi_CDs[i].device, 1); |
1066 | |
1067 | retries = 3; |
1068 | do { |
1069 | cmd[0] = READ_CAPACITY0x25; |
1070 | cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0; |
1071 | memset ((void *) &cmd[2], 0, 8)(__builtin_constant_p(0) ? (__builtin_constant_p((8)) ? __constant_c_and_count_memset ((((void *) &cmd[2])),((0x01010101UL*(unsigned char)(0))) ,((8))) : __constant_c_memset((((void *) &cmd[2])),((0x01010101UL *(unsigned char)(0))),((8)))) : (__builtin_constant_p((8)) ? __memset_generic (((((void *) &cmd[2]))),(((0))),(((8)))) : __memset_generic ((((void *) &cmd[2])),((0)),((8))))); |
1072 | SCpnt->request.rq_status = RQ_SCSI_BUSY0xffff; /* Mark as really busy */ |
1073 | SCpnt->cmd_len = 0; |
1074 | |
1075 | memset(buffer, 0, 8)(__builtin_constant_p(0) ? (__builtin_constant_p((8)) ? __constant_c_and_count_memset (((buffer)),((0x01010101UL*(unsigned char)(0))),((8))) : __constant_c_memset (((buffer)),((0x01010101UL*(unsigned char)(0))),((8)))) : (__builtin_constant_p ((8)) ? __memset_generic((((buffer))),(((0))),(((8)))) : __memset_generic (((buffer)),((0)),((8))))); |
1076 | |
1077 | /* Do the command and wait.. */ |
1078 | { |
1079 | struct semaphore sem = MUTEX_LOCKED((struct semaphore) { 0, 0, 0, ((void *) 0) }); |
1080 | SCpnt->request.sem = &sem; |
1081 | scsi_do_cmd (SCpnt, |
1082 | (void *) cmd, (void *) buffer, |
1083 | 512, sr_init_done, SR_TIMEOUT(30 * 100), |
1084 | MAX_RETRIES3); |
1085 | down(&sem); |
1086 | } |
1087 | |
1088 | the_result = SCpnt->result; |
1089 | retries--; |
1090 | |
1091 | } while(the_result && retries); |
1092 | |
1093 | SCpnt->request.rq_status = RQ_INACTIVE(-1); /* Mark as not busy */ |
1094 | |
1095 | wake_up(&SCpnt->device->device_wait); |
1096 | |
1097 | if (the_result) { |
1098 | scsi_CDs[i].capacity = 0x1fffff; |
1099 | scsi_CDs[i].sector_size = 2048; /* A guess, just in case */ |
1100 | scsi_CDs[i].needs_sector_size = 1; |
1101 | } else { |
1102 | scsi_CDs[i].capacity = 1 + ((buffer[0] << 24) | |
1103 | (buffer[1] << 16) | |
1104 | (buffer[2] << 8) | |
1105 | buffer[3]); |
1106 | scsi_CDs[i].sector_size = (buffer[4] << 24) | |
1107 | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; |
1108 | switch (scsi_CDs[i].sector_size) { |
1109 | /* |
1110 | * HP 4020i CD-Recorder reports 2340 byte sectors |
1111 | * Philips CD-Writers report 2352 byte sectors |
1112 | * |
1113 | * Use 2k sectors for them.. |
1114 | */ |
1115 | case 0: case 2340: case 2352: |
1116 | scsi_CDs[i].sector_size = 2048; |
1117 | /* fall through */ |
1118 | case 2048: |
1119 | scsi_CDs[i].capacity *= 4; |
1120 | /* fall through */ |
1121 | case 512: |
1122 | break; |
1123 | default: |
1124 | #ifdef MACH1 |
1125 | printk ("cd%d : unsupported sector size %d.\n", |
1126 | i, scsi_CDs[i].sector_size); |
1127 | #else |
1128 | printk ("scd%d : unsupported sector size %d.\n", |
1129 | i, scsi_CDs[i].sector_size); |
1130 | #endif |
1131 | scsi_CDs[i].capacity = 0; |
1132 | scsi_CDs[i].needs_sector_size = 1; |
1133 | } |
1134 | scsi_CDs[i].needs_sector_size = 0; |
1135 | sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS10 - 9); |
1136 | }; |
1137 | scsi_free(buffer, 512); |
1138 | } |
1139 | |
1140 | static int sr_registered = 0; |
1141 | |
1142 | static int sr_init() |
1143 | { |
1144 | int i; |
1145 | |
1146 | if(sr_template.dev_noticed == 0) return 0; |
1147 | |
1148 | if(!sr_registered) { |
1149 | if (register_blkdev(MAJOR_NR11,"sr",&sr_fops)) { |
1150 | printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR11); |
1151 | return 1; |
1152 | } |
1153 | sr_registered++; |
1154 | } |
1155 | |
1156 | |
1157 | if (scsi_CDs) return 0; |
1158 | sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS2; |
1159 | scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC0x01); |
1160 | memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD))(__builtin_constant_p(0) ? (__builtin_constant_p((sr_template .dev_max * sizeof(Scsi_CD))) ? __constant_c_and_count_memset( ((scsi_CDs)),((0x01010101UL*(unsigned char)(0))),((sr_template .dev_max * sizeof(Scsi_CD)))) : __constant_c_memset(((scsi_CDs )),((0x01010101UL*(unsigned char)(0))),((sr_template.dev_max * sizeof(Scsi_CD))))) : (__builtin_constant_p((sr_template.dev_max * sizeof(Scsi_CD))) ? __memset_generic((((scsi_CDs))),(((0)) ),(((sr_template.dev_max * sizeof(Scsi_CD))))) : __memset_generic (((scsi_CDs)),((0)),((sr_template.dev_max * sizeof(Scsi_CD))) ))); |
1161 | |
1162 | sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC0x01); |
1163 | memset(sr_sizes, 0, sr_template.dev_max * sizeof(int))(__builtin_constant_p(0) ? (__builtin_constant_p((sr_template .dev_max * sizeof(int))) ? __constant_c_and_count_memset(((sr_sizes )),((0x01010101UL*(unsigned char)(0))),((sr_template.dev_max * sizeof(int)))) : __constant_c_memset(((sr_sizes)),((0x01010101UL *(unsigned char)(0))),((sr_template.dev_max * sizeof(int))))) : (__builtin_constant_p((sr_template.dev_max * sizeof(int))) ? __memset_generic((((sr_sizes))),(((0))),(((sr_template.dev_max * sizeof(int))))) : __memset_generic(((sr_sizes)),((0)),((sr_template .dev_max * sizeof(int)))))); |
1164 | |
1165 | sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max * |
1166 | sizeof(int), GFP_ATOMIC0x01); |
1167 | for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048; |
1168 | blksize_size[MAJOR_NR11] = sr_blocksizes; |
1169 | return 0; |
1170 | } |
1171 | |
1172 | void sr_finish() |
1173 | { |
1174 | int i; |
1175 | |
1176 | blk_dev[MAJOR_NR11].request_fn = DEVICE_REQUESTdo_sr_request; |
1177 | blk_size[MAJOR_NR11] = sr_sizes; |
1178 | |
1179 | for (i = 0; i < sr_template.nr_dev; ++i) |
1180 | { |
1181 | /* If we have already seen this, then skip it. Comes up |
1182 | * with loadable modules. */ |
1183 | if (scsi_CDs[i].capacity) continue; |
1184 | scsi_CDs[i].capacity = 0x1fffff; |
1185 | scsi_CDs[i].sector_size = 2048; /* A guess, just in case */ |
1186 | scsi_CDs[i].needs_sector_size = 1; |
1187 | #if 0 |
1188 | /* seems better to leave this for later */ |
1189 | get_sectorsize(i); |
1190 | printk("Scd sectorsize = %d bytes.\n", scsi_CDs[i].sector_size); |
1191 | #endif |
1192 | scsi_CDs[i].use = 1; |
1193 | scsi_CDs[i].ten = 1; |
1194 | scsi_CDs[i].remap = 1; |
1195 | scsi_CDs[i].auto_eject = 0; /* Default is not to eject upon unmount. */ |
1196 | sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS10 - 9); |
1197 | } |
1198 | |
1199 | |
1200 | /* If our host adapter is capable of scatter-gather, then we increase |
1201 | * the read-ahead to 16 blocks (32 sectors). If not, we use |
1202 | * a two block (4 sector) read ahead. */ |
1203 | if(scsi_CDs[0].device && scsi_CDs[0].device->host->sg_tablesize) |
1204 | read_ahead[MAJOR_NR11] = 32; /* 32 sector read-ahead. Always removable. */ |
1205 | else |
1206 | read_ahead[MAJOR_NR11] = 4; /* 4 sector read-ahead */ |
1207 | |
1208 | return; |
1209 | } |
1210 | |
1211 | static void sr_detach(Scsi_Device * SDp) |
1212 | { |
1213 | Scsi_CD * cpnt; |
1214 | int i; |
1215 | |
1216 | for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++) |
1217 | if(cpnt->device == SDp) { |
1218 | kdev_t devi = MKDEV(MAJOR_NR, i)(((11) << 8) | (i)); |
1219 | |
1220 | /* |
1221 | * Since the cdrom is read-only, no need to sync the device. |
1222 | * We should be kind to our buffer cache, however. |
1223 | */ |
1224 | invalidate_inodes(devi); |
1225 | invalidate_buffers(devi); |
1226 | |
1227 | /* |
1228 | * Reset things back to a sane state so that one can re-load a new |
1229 | * driver (perhaps the same one). |
1230 | */ |
1231 | cpnt->device = NULL((void *) 0); |
1232 | cpnt->capacity = 0; |
1233 | SDp->attached--; |
1234 | sr_template.nr_dev--; |
1235 | sr_template.dev_noticed--; |
1236 | sr_sizes[i] = 0; |
1237 | return; |
1238 | } |
1239 | return; |
1240 | } |
1241 | |
1242 | |
1243 | #ifdef MODULE |
1244 | |
1245 | int init_module(void) { |
1246 | sr_template.usage_count = &mod_use_count_; |
1247 | return scsi_register_module(MODULE_SCSI_DEV4, &sr_template); |
1248 | } |
1249 | |
1250 | void cleanup_module( void) |
1251 | { |
1252 | scsi_unregister_module(MODULE_SCSI_DEV4, &sr_template); |
1253 | unregister_blkdev(SCSI_CDROM_MAJOR11, "sr"); |
1254 | sr_registered--; |
1255 | if(scsi_CDs != NULL((void *) 0)) { |
1256 | scsi_init_free((char *) scsi_CDs, |
1257 | (sr_template.dev_noticed + SR_EXTRA_DEVS2) |
1258 | * sizeof(Scsi_CD)); |
1259 | |
1260 | scsi_init_free((char *) sr_sizes, sr_template.dev_max * sizeof(int)); |
1261 | scsi_init_free((char *) sr_blocksizes, sr_template.dev_max * sizeof(int)); |
1262 | } |
1263 | |
1264 | blksize_size[MAJOR_NR11] = NULL((void *) 0); |
1265 | blk_dev[MAJOR_NR11].request_fn = NULL((void *) 0); |
1266 | blk_size[MAJOR_NR11] = NULL((void *) 0); |
1267 | read_ahead[MAJOR_NR11] = 0; |
1268 | |
1269 | sr_template.dev_max = 0; |
1270 | } |
1271 | #endif /* MODULE */ |
1272 | |
1273 | /* |
1274 | * Overrides for Emacs so that we follow Linus's tabbing style. |
1275 | * Emacs will notice this stuff at the end of the file and automatically |
1276 | * adjust the settings for this buffer only. This must remain at the end |
1277 | * of the file. |
1278 | * --------------------------------------------------------------------------- |
1279 | * Local variables: |
1280 | * c-indent-level: 4 |
1281 | * c-brace-imaginary-offset: 0 |
1282 | * c-brace-offset: -4 |
1283 | * c-argdecl-indent: 4 |
1284 | * c-label-offset: -4 |
1285 | * c-continued-statement-offset: 4 |
1286 | * c-continued-brace-offset: 0 |
1287 | * indent-tabs-mode: nil |
1288 | * tab-width: 8 |
1289 | * End: |
1290 | */ |