]>
Commit | Line | Data |
---|---|---|
04d1e647 | 1 | --- 1.41/drivers/cdrom/cdrom.c Sat Sep 27 16:24:59 2003 |
2 | +++ edited/drivers/cdrom/cdrom.c Thu Dec 18 11:41:45 2003 | |
3 | @@ -228,10 +228,16 @@ | |
4 | 3.12 Oct 18, 2000 - Jens Axboe <axboe@suse.de> | |
5 | -- Use quiet bit on packet commands not known to work | |
6 | ||
7 | + 3.20 Dec 17, 2003 - Jens Axboe <axboe@suse.de> | |
8 | + -- Various fixes and lots of cleanups not listed :-) | |
9 | + -- Locking fixes | |
10 | + -- Mt Rainier support | |
11 | + -- DVD-RAM write open fixes | |
12 | + | |
13 | -------------------------------------------------------------------------*/ | |
14 | ||
15 | -#define REVISION "Revision: 3.12" | |
16 | -#define VERSION "Id: cdrom.c 3.12 2000/10/18" | |
17 | +#define REVISION "Revision: 3.20" | |
18 | +#define VERSION "Id: cdrom.c 3.20 2003/12/17" | |
19 | ||
20 | /* I use an error-log mask to give fine grain control over the type of | |
21 | messages dumped to the system logs. The available masks include: */ | |
22 | @@ -282,11 +288,25 @@ | |
23 | static int lockdoor = 1; | |
24 | /* will we ever get to use this... sigh. */ | |
25 | static int check_media_type; | |
26 | +/* automatically restart mrw format */ | |
27 | +static int mrw_format_restart = 1; | |
28 | MODULE_PARM(debug, "i"); | |
29 | MODULE_PARM(autoclose, "i"); | |
30 | MODULE_PARM(autoeject, "i"); | |
31 | MODULE_PARM(lockdoor, "i"); | |
32 | MODULE_PARM(check_media_type, "i"); | |
33 | +MODULE_PARM(mrw_format_restart, "i"); | |
34 | + | |
35 | +static spinlock_t cdrom_lock = SPIN_LOCK_UNLOCKED; | |
36 | + | |
37 | +static const char *mrw_format_status[] = { | |
38 | + "not mrw", | |
39 | + "bgformat inactive", | |
40 | + "bgformat active", | |
41 | + "mrw complete", | |
42 | +}; | |
43 | + | |
44 | +static const char *mrw_address_space[] = { "DMA", "GAA" }; | |
45 | ||
46 | #if (ERRLOGMASK!=CD_NOTHING) | |
47 | #define cdinfo(type, fmt, args...) \ | |
48 | @@ -325,6 +345,10 @@ | |
49 | static int cdrom_get_next_writable(struct cdrom_device_info *, long *); | |
50 | static void cdrom_count_tracks(struct cdrom_device_info *, tracktype*); | |
51 | ||
52 | +static int cdrom_mrw_exit(struct cdrom_device_info *cdi); | |
53 | + | |
54 | +static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di); | |
55 | + | |
56 | #ifdef CONFIG_SYSCTL | |
57 | static void cdrom_sysctl_register(void); | |
58 | #endif /* CONFIG_SYSCTL */ | |
59 | @@ -347,13 +371,14 @@ | |
60 | ||
61 | if (cdo->open == NULL || cdo->release == NULL) | |
62 | return -2; | |
63 | - if ( !banner_printed ) { | |
64 | + if (!banner_printed) { | |
65 | printk(KERN_INFO "Uniform CD-ROM driver " REVISION "\n"); | |
66 | banner_printed = 1; | |
67 | #ifdef CONFIG_SYSCTL | |
68 | cdrom_sysctl_register(); | |
69 | #endif /* CONFIG_SYSCTL */ | |
70 | } | |
71 | + | |
72 | ENSURE(drive_status, CDC_DRIVE_STATUS ); | |
73 | ENSURE(media_changed, CDC_MEDIA_CHANGED); | |
74 | ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY); | |
75 | @@ -378,9 +403,14 @@ | |
76 | if (check_media_type==1) | |
77 | cdi->options |= (int) CDO_CHECK_TYPE; | |
78 | ||
79 | + if (CDROM_CAN(CDC_MRW_W)) | |
80 | + cdi->exit = cdrom_mrw_exit; | |
81 | + | |
82 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); | |
83 | + spin_lock(&cdrom_lock); | |
84 | cdi->next = topCdromPtr; | |
85 | topCdromPtr = cdi; | |
86 | + spin_unlock(&cdrom_lock); | |
87 | return 0; | |
88 | } | |
89 | #undef ENSURE | |
90 | @@ -391,23 +421,311 @@ | |
91 | cdinfo(CD_OPEN, "entering unregister_cdrom\n"); | |
92 | ||
93 | prev = NULL; | |
94 | + spin_lock(&cdrom_lock); | |
95 | cdi = topCdromPtr; | |
96 | while (cdi && cdi != unreg) { | |
97 | prev = cdi; | |
98 | cdi = cdi->next; | |
99 | } | |
100 | ||
101 | - if (cdi == NULL) | |
102 | + if (cdi == NULL) { | |
103 | + spin_unlock(&cdrom_lock); | |
104 | return -2; | |
105 | + } | |
106 | if (prev) | |
107 | prev->next = cdi->next; | |
108 | else | |
109 | topCdromPtr = cdi->next; | |
110 | + | |
111 | + spin_unlock(&cdrom_lock); | |
112 | + | |
113 | + if (cdi->exit) | |
114 | + cdi->exit(cdi); | |
115 | + | |
116 | cdi->ops->n_minors--; | |
117 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); | |
118 | return 0; | |
119 | } | |
120 | ||
121 | +int cdrom_get_media_event(struct cdrom_device_info *cdi, | |
122 | + struct media_event_desc *med) | |
123 | +{ | |
124 | + struct cdrom_generic_command cgc; | |
125 | + unsigned char buffer[8]; | |
126 | + struct event_header *eh = (struct event_header *) buffer; | |
127 | + | |
128 | + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | |
129 | + cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; | |
130 | + cgc.cmd[1] = 1; /* IMMED */ | |
131 | + cgc.cmd[4] = 1 << 4; /* media event */ | |
132 | + cgc.cmd[8] = sizeof(buffer); | |
133 | + cgc.quiet = 1; | |
134 | + | |
135 | + if (cdi->ops->generic_packet(cdi, &cgc)) | |
136 | + return 1; | |
137 | + | |
138 | + if (be16_to_cpu(eh->data_len) < sizeof(*med)) | |
139 | + return 1; | |
140 | + | |
141 | + memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); | |
142 | + return 0; | |
143 | +} | |
144 | + | |
145 | +/* | |
146 | + * the first prototypes used 0x2c as the page code for the mrw mode page, | |
147 | + * subsequently this was changed to 0x03. probe the one used by this drive | |
148 | + */ | |
149 | +int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) | |
150 | +{ | |
151 | + struct cdrom_generic_command cgc; | |
152 | + char buffer[16]; | |
153 | + | |
154 | + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | |
155 | + | |
156 | + cgc.buffer = buffer; | |
157 | + cgc.buflen = sizeof(buffer); | |
158 | + cgc.timeout = HZ; | |
159 | + cgc.quiet = 1; | |
160 | + | |
161 | + if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) { | |
162 | + cdi->mrw_mode_page = MRW_MODE_PC; | |
163 | + return 0; | |
164 | + } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { | |
165 | + cdi->mrw_mode_page = MRW_MODE_PC_PRE1; | |
166 | + return 0; | |
167 | + } else { | |
168 | + printk("cdrom: %s: unknown mrw mode page\n", cdi->name); | |
169 | + return 1; | |
170 | + } | |
171 | + | |
172 | + printk("cdrom: %s: mrw mode page %x\n", cdi->name, cdi->mrw_mode_page); | |
173 | +} | |
174 | + | |
175 | +int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) | |
176 | +{ | |
177 | + struct cdrom_generic_command cgc; | |
178 | + struct mrw_feature_desc *mfd; | |
179 | + unsigned char buffer[16]; | |
180 | + int ret; | |
181 | + | |
182 | + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | |
183 | + | |
184 | + cgc.cmd[0] = GPCMD_GET_CONFIGURATION; | |
185 | + cgc.cmd[3] = CDF_MRW; | |
186 | + cgc.cmd[8] = sizeof(buffer); | |
187 | + cgc.quiet = 1; | |
188 | + | |
189 | + if ((ret = cdi->ops->generic_packet(cdi, &cgc))) | |
190 | + return ret; | |
191 | + | |
192 | + mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; | |
193 | + *write = mfd->write; | |
194 | + | |
195 | + if ((ret = cdrom_mrw_probe_pc(cdi))) | |
196 | + return ret; | |
197 | + | |
198 | + return 0; | |
199 | +} | |
200 | + | |
201 | +static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) | |
202 | +{ | |
203 | + struct cdrom_generic_command cgc; | |
204 | + unsigned char buffer[12]; | |
205 | + int ret; | |
206 | + | |
207 | + printk("cdrom: %sstarting format\n", cont ? "Re" : ""); | |
208 | + | |
209 | + /* | |
210 | + * FmtData bit set (bit 4), format type is 1 | |
211 | + */ | |
212 | + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE); | |
213 | + cgc.cmd[0] = GPCMD_FORMAT_UNIT; | |
214 | + cgc.cmd[1] = (1 << 4) | 1; | |
215 | + | |
216 | + cgc.timeout = 5 * 60 * HZ; | |
217 | + | |
218 | + /* | |
219 | + * 4 byte format list header, 8 byte format list descriptor | |
220 | + */ | |
221 | + buffer[1] = 1 << 1; | |
222 | + buffer[3] = 8; | |
223 | + | |
224 | + /* | |
225 | + * nr_blocks field | |
226 | + */ | |
227 | + buffer[4] = 0xff; | |
228 | + buffer[5] = 0xff; | |
229 | + buffer[6] = 0xff; | |
230 | + buffer[7] = 0xff; | |
231 | + | |
232 | + buffer[8] = 0x24 << 2; | |
233 | + buffer[11] = cont; | |
234 | + | |
235 | + ret = cdi->ops->generic_packet(cdi, &cgc); | |
236 | + if (ret) | |
237 | + printk("cdrom: bgformat failed\n"); | |
238 | + | |
239 | + return ret; | |
240 | +} | |
241 | + | |
242 | +static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed) | |
243 | +{ | |
244 | + struct cdrom_generic_command cgc; | |
245 | + | |
246 | + init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE); | |
247 | + cgc.cmd[0] = GPCMD_CLOSE_TRACK; | |
248 | + | |
249 | + /* | |
250 | + * Session = 1, Track = 0 | |
251 | + */ | |
252 | + cgc.cmd[1] = !!immed; | |
253 | + cgc.cmd[2] = 1 << 1; | |
254 | + | |
255 | + cgc.timeout = 300 * HZ; | |
256 | + | |
257 | + return cdi->ops->generic_packet(cdi, &cgc); | |
258 | +} | |
259 | + | |
260 | +static int cdrom_flush_cache(struct cdrom_device_info *cdi) | |
261 | +{ | |
262 | + struct cdrom_generic_command cgc; | |
263 | + | |
264 | + init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE); | |
265 | + cgc.cmd[0] = GPCMD_FLUSH_CACHE; | |
266 | + | |
267 | + cgc.timeout = 5 * 60 * HZ; | |
268 | + | |
269 | + return cdi->ops->generic_packet(cdi, &cgc); | |
270 | +} | |
271 | + | |
272 | +static int cdrom_mrw_exit(struct cdrom_device_info *cdi) | |
273 | +{ | |
274 | + disc_information di; | |
275 | + int ret = 0; | |
276 | + | |
277 | + if (cdrom_get_disc_info(cdi, &di)) | |
278 | + return 1; | |
279 | + | |
280 | + if (di.mrw_status == CDM_MRW_BGFORMAT_ACTIVE) { | |
281 | + printk("cdrom: issuing MRW back ground format suspend\n"); | |
282 | + ret = cdrom_mrw_bgformat_susp(cdi, 0); | |
283 | + } | |
284 | + | |
285 | + if (!ret) | |
286 | + ret = cdrom_flush_cache(cdi); | |
287 | + | |
288 | + return ret; | |
289 | +} | |
290 | + | |
291 | +static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) | |
292 | +{ | |
293 | + struct cdrom_generic_command cgc; | |
294 | + struct mode_page_header *mph; | |
295 | + char buffer[16]; | |
296 | + int ret, offset, size; | |
297 | + | |
298 | + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); | |
299 | + | |
300 | + cgc.buffer = buffer; | |
301 | + cgc.buflen = sizeof(buffer); | |
302 | + | |
303 | + if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) | |
304 | + return ret; | |
305 | + | |
306 | + mph = (struct mode_page_header *) buffer; | |
307 | + offset = be16_to_cpu(mph->desc_length); | |
308 | + size = be16_to_cpu(mph->mode_data_length) + 2; | |
309 | + | |
310 | + buffer[offset + 3] = space; | |
311 | + cgc.buflen = size; | |
312 | + | |
313 | + if ((ret = cdrom_mode_select(cdi, &cgc))) | |
314 | + return ret; | |
315 | + | |
316 | + printk("cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); | |
317 | + return 0; | |
318 | +} | |
319 | + | |
320 | +static int cdrom_media_erasable(struct cdrom_device_info *cdi) | |
321 | +{ | |
322 | + disc_information di; | |
323 | + | |
324 | + if (cdrom_get_disc_info(cdi, &di)) | |
325 | + return 0; | |
326 | + | |
327 | + return di.erasable; | |
328 | +} | |
329 | + | |
330 | +/* | |
331 | + * FIXME: check RO bit | |
332 | + */ | |
333 | +static int cdrom_dvdram_open_write(struct cdrom_device_info *cdi) | |
334 | +{ | |
335 | + return !cdrom_media_erasable(cdi); | |
336 | +} | |
337 | + | |
338 | +static int cdrom_mrw_open_write(struct cdrom_device_info *cdi) | |
339 | +{ | |
340 | + disc_information di; | |
341 | + int ret; | |
342 | + | |
343 | + /* | |
344 | + * always reset to DMA lba space on open | |
345 | + */ | |
346 | + if (cdrom_mrw_set_lba_space(cdi, MRW_LBA_DMA)) { | |
347 | + printk("failed setting lba address space\n"); | |
348 | + return 1; | |
349 | + } | |
350 | + | |
351 | + if (cdrom_get_disc_info(cdi, &di)) | |
352 | + return 1; | |
353 | + | |
354 | + if (!di.erasable) { | |
355 | + printk("cdrom not erasable\n"); | |
356 | + return 1; | |
357 | + } | |
358 | + | |
359 | + /* | |
360 | + * mrw_status | |
361 | + * 0 - not MRW formatted | |
362 | + * 1 - MRW bgformat started, but not running or complete | |
363 | + * 2 - MRW bgformat in progress | |
364 | + * 3 - MRW formatting complete | |
365 | + */ | |
366 | + ret = 0; | |
367 | + printk("cdrom open: mrw_status '%s'\n", mrw_format_status[di.mrw_status]); | |
368 | + if (!di.mrw_status) | |
369 | + ret = 1; | |
370 | + else if (di.mrw_status == CDM_MRW_BGFORMAT_INACTIVE && mrw_format_restart) | |
371 | + ret = cdrom_mrw_bgformat(cdi, 1); | |
372 | + | |
373 | + return ret; | |
374 | +} | |
375 | + | |
376 | +/* | |
377 | + * returns 0 for ok to open write, non-0 to disallow | |
378 | + */ | |
379 | +static int cdrom_open_write(struct cdrom_device_info *cdi) | |
380 | +{ | |
381 | + int ret = 1; | |
382 | + | |
383 | + if (CDROM_CAN(CDC_MRW_W)) | |
384 | + ret = cdrom_mrw_open_write(cdi); | |
385 | + else if (CDROM_CAN(CDC_DVD_RAM)) | |
386 | + ret = cdrom_dvdram_open_write(cdi); | |
387 | + | |
388 | + return ret; | |
389 | +} | |
390 | + | |
391 | +static int cdrom_close_write(struct cdrom_device_info *cdi) | |
392 | +{ | |
393 | +#if 0 | |
394 | + return cdrom_flush_cache(cdi); | |
395 | +#else | |
396 | + return 0; | |
397 | +#endif | |
398 | +} | |
399 | + | |
400 | /* We use the open-option O_NONBLOCK to indicate that the | |
401 | * purpose of opening is only for subsequent ioctl() calls; no device | |
402 | * integrity checks are performed. | |
403 | @@ -421,23 +739,32 @@ | |
404 | int ret; | |
405 | ||
406 | cdinfo(CD_OPEN, "entering cdrom_open\n"); | |
407 | + cdi->use_count++; | |
408 | + ret = -EROFS; | |
409 | + if (fp->f_mode & FMODE_WRITE) { | |
410 | + printk("cdrom: %s opening for WRITE\n", current->comm); | |
411 | + if (!CDROM_CAN(CDC_RAM)) { | |
412 | + printk("bzzt\n"); | |
413 | + goto out; | |
414 | + } | |
415 | + if (cdrom_open_write(cdi)) | |
416 | + goto out; | |
417 | + } | |
418 | + | |
419 | /* if this was a O_NONBLOCK open and we should honor the flags, | |
420 | * do a quick open without drive/disc integrity checks. */ | |
421 | if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) | |
422 | ret = cdi->ops->open(cdi, 1); | |
423 | - else { | |
424 | - if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_DVD_RAM)) | |
425 | - return -EROFS; | |
426 | - | |
427 | + else | |
428 | ret = open_for_data(cdi); | |
429 | - } | |
430 | - | |
431 | - if (!ret) cdi->use_count++; | |
432 | ||
433 | cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count); | |
434 | /* Do this on open. Don't wait for mount, because they might | |
435 | not be mounting, but opening with O_NONBLOCK */ | |
436 | check_disk_change(ip->i_bdev); | |
437 | +out: | |
438 | + if (ret) | |
439 | + cdi->use_count--; | |
440 | return ret; | |
441 | } | |
442 | ||
443 | @@ -525,7 +852,7 @@ | |
444 | cdinfo(CD_OPEN, "open device failed.\n"); | |
445 | goto clean_up_and_return; | |
446 | } | |
447 | - if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { | |
448 | + if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) { | |
449 | cdo->lock_door(cdi, 1); | |
450 | cdinfo(CD_OPEN, "door locked.\n"); | |
451 | } | |
452 | @@ -603,7 +930,6 @@ | |
453 | return 0; | |
454 | } | |
455 | ||
456 | - | |
457 | /* Admittedly, the logic below could be performed in a nicer way. */ | |
458 | int cdrom_release(struct cdrom_device_info *cdi, struct file *fp) | |
459 | { | |
460 | @@ -612,17 +938,23 @@ | |
461 | ||
462 | cdinfo(CD_CLOSE, "entering cdrom_release\n"); | |
463 | ||
464 | - if (cdi->use_count > 0) | |
465 | - cdi->use_count--; | |
466 | - if (cdi->use_count == 0) | |
467 | + if (!--cdi->use_count) { | |
468 | cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name); | |
469 | - if (cdi->use_count == 0 && | |
470 | - cdo->capability & CDC_LOCK && !keeplocked) { | |
471 | - cdinfo(CD_CLOSE, "Unlocking door!\n"); | |
472 | - cdo->lock_door(cdi, 0); | |
473 | + if ((cdo->capability & CDC_LOCK) && !keeplocked) { | |
474 | + cdinfo(CD_CLOSE, "Unlocking door!\n"); | |
475 | + cdo->lock_door(cdi, 0); | |
476 | + } | |
477 | } | |
478 | + | |
479 | opened_for_data = !(cdi->options & CDO_USE_FFLAGS) || | |
480 | !(fp && fp->f_flags & O_NONBLOCK); | |
481 | + | |
482 | + /* | |
483 | + * flush cache on last write release | |
484 | + */ | |
485 | + if (CDROM_CAN(CDC_RAM) && !cdi->use_count && opened_for_data) | |
486 | + cdrom_close_write(cdi); | |
487 | + | |
488 | cdo->release(cdi); | |
489 | if (cdi->use_count == 0) { /* last process that closes dev*/ | |
490 | if (opened_for_data && | |
491 | @@ -2203,7 +2535,6 @@ | |
492 | return cdo->generic_packet(cdi, &cgc); | |
493 | } | |
494 | ||
495 | - | |
496 | /* return the last written block on the CD-R media. this is for the udf | |
497 | file system. */ | |
498 | int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written) | |
499 | @@ -2310,6 +2641,8 @@ | |
500 | EXPORT_SYMBOL(cdrom_mode_select); | |
501 | EXPORT_SYMBOL(cdrom_mode_sense); | |
502 | EXPORT_SYMBOL(init_cdrom_command); | |
503 | +EXPORT_SYMBOL(cdrom_get_media_event); | |
504 | +EXPORT_SYMBOL(cdrom_is_mrw); | |
505 | ||
506 | #ifdef CONFIG_SYSCTL | |
507 | ||
508 | @@ -2405,6 +2738,14 @@ | |
509 | pos += sprintf(info+pos, "\nCan write DVD-RAM:"); | |
510 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | |
511 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0); | |
512 | + | |
513 | + pos += sprintf(info+pos, "\nCan read MRW:"); | |
514 | + for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | |
515 | + pos += sprintf(info+pos, "\t\t%d", CDROM_CAN(CDC_MRW) != 0); | |
516 | + | |
517 | + pos += sprintf(info+pos, "\nCan write MRW:"); | |
518 | + for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | |
519 | + pos += sprintf(info+pos, "\t\t%d", CDROM_CAN(CDC_MRW_W) != 0); | |
520 | ||
521 | strcpy(info+pos,"\n\n"); | |
522 | ||
523 | ===== drivers/ide/ide-cd.c 1.62 vs edited ===== | |
524 | --- 1.62/drivers/ide/ide-cd.c Sun Dec 14 01:01:28 2003 | |
525 | +++ edited/drivers/ide/ide-cd.c Thu Dec 18 12:33:11 2003 | |
526 | @@ -291,10 +291,13 @@ | |
527 | * - Use extended sense on drives that support it for | |
528 | * correctly reporting tray status -- from | |
529 | * Michael D Johnson <johnsom@orst.edu> | |
530 | + * 4.60 Dec 17, 2003 - Add mt rainier support | |
531 | + * - Bump timeout for packet commands, matches sr | |
532 | + * - Odd stuff | |
533 | * | |
534 | *************************************************************************/ | |
535 | ||
536 | -#define IDECD_VERSION "4.59-ac1" | |
537 | +#define IDECD_VERSION "4.60" | |
538 | ||
539 | #include <linux/config.h> | |
540 | #include <linux/module.h> | |
541 | @@ -774,11 +777,14 @@ | |
542 | ||
543 | if (sense_key == NOT_READY) { | |
544 | /* Tray open. */ | |
545 | - cdrom_saw_media_change (drive); | |
546 | + if (rq_data_dir(rq) == READ) { | |
547 | + cdrom_saw_media_change (drive); | |
548 | ||
549 | - /* Fail the request. */ | |
550 | - printk ("%s: tray open\n", drive->name); | |
551 | - do_end_request = 1; | |
552 | + /* Fail the request. */ | |
553 | + printk ("%s: tray open\n", drive->name); | |
554 | + do_end_request = 1; | |
555 | + } | |
556 | + /* FIXME: need to timeout writes */ | |
557 | } else if (sense_key == UNIT_ATTENTION) { | |
558 | /* Media change. */ | |
559 | cdrom_saw_media_change (drive); | |
560 | @@ -844,9 +850,13 @@ | |
561 | case GPCMD_BLANK: | |
562 | case GPCMD_FORMAT_UNIT: | |
563 | case GPCMD_RESERVE_RZONE_TRACK: | |
564 | - wait = WAIT_CMD; | |
565 | + case GPCMD_CLOSE_TRACK: | |
566 | + case GPCMD_FLUSH_CACHE: | |
567 | + wait = ATAPI_WAIT_PC; | |
568 | break; | |
569 | default: | |
570 | + if (!(rq->flags & REQ_QUIET)) | |
571 | + printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]); | |
572 | wait = 0; | |
573 | break; | |
574 | } | |
575 | @@ -894,7 +904,7 @@ | |
576 | ||
577 | if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { | |
578 | /* packet command */ | |
579 | - ide_execute_command(drive, WIN_PACKETCMD, handler, WAIT_CMD, cdrom_timer_expiry); | |
580 | + ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry); | |
581 | return ide_started; | |
582 | } else { | |
583 | /* packet command */ | |
584 | @@ -1167,7 +1177,7 @@ | |
585 | } | |
586 | ||
587 | /* Done moving data! Wait for another interrupt. */ | |
588 | - ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL); | |
589 | + ide_set_handler(drive, &cdrom_read_intr, ATAPI_WAIT_PC, NULL); | |
590 | return ide_started; | |
591 | } | |
592 | ||
593 | @@ -1277,7 +1287,7 @@ | |
594 | (65534 / CD_FRAMESIZE) : 65535); | |
595 | ||
596 | /* Set up the command */ | |
597 | - rq->timeout = WAIT_CMD; | |
598 | + rq->timeout = ATAPI_WAIT_PC; | |
599 | ||
600 | /* Send the command to the drive and return. */ | |
601 | return cdrom_transfer_packet_command(drive, rq, &cdrom_read_intr); | |
602 | @@ -1286,7 +1296,7 @@ | |
603 | ||
604 | #define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */ | |
605 | #define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */ | |
606 | -#define IDECD_SEEK_TIMEOUT WAIT_CMD /* 10 sec */ | |
607 | +#define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */ | |
608 | ||
609 | static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive) | |
610 | { | |
611 | @@ -1326,7 +1336,7 @@ | |
612 | rq->cmd[0] = GPCMD_SEEK; | |
613 | put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]); | |
614 | ||
615 | - rq->timeout = WAIT_CMD; | |
616 | + rq->timeout = ATAPI_WAIT_PC; | |
617 | return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); | |
618 | } | |
619 | ||
620 | @@ -1502,7 +1512,7 @@ | |
621 | } | |
622 | ||
623 | /* Now we wait for another interrupt. */ | |
624 | - ide_set_handler(drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry); | |
625 | + ide_set_handler(drive, &cdrom_pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry); | |
626 | return ide_started; | |
627 | } | |
628 | ||
629 | @@ -1511,7 +1521,7 @@ | |
630 | struct request *rq = HWGROUP(drive)->rq; | |
631 | ||
632 | if (!rq->timeout) | |
633 | - rq->timeout = WAIT_CMD; | |
634 | + rq->timeout = ATAPI_WAIT_PC; | |
635 | ||
636 | /* Send the command to the drive and return. */ | |
637 | return cdrom_transfer_packet_command(drive, rq, &cdrom_pc_intr); | |
638 | @@ -1716,11 +1726,8 @@ | |
639 | /* | |
640 | * If DRQ is clear, the command has completed. | |
641 | */ | |
642 | - if ((stat & DRQ_STAT) == 0) { | |
643 | - if (rq->data_len) | |
644 | - printk("%s: %u residual after xfer\n", __FUNCTION__, rq->data_len); | |
645 | + if ((stat & DRQ_STAT) == 0) | |
646 | goto end_request; | |
647 | - } | |
648 | ||
649 | /* | |
650 | * check which way to transfer data | |
651 | @@ -1826,10 +1833,8 @@ | |
652 | } | |
653 | } | |
654 | ||
655 | - if (cdrom_decode_status(drive, 0, &stat)) { | |
656 | - printk("ide-cd: write_intr decode_status bad\n"); | |
657 | + if (cdrom_decode_status(drive, 0, &stat)) | |
658 | return ide_stopped; | |
659 | - } | |
660 | ||
661 | /* | |
662 | * using dma, transfer is complete now | |
663 | @@ -1904,7 +1909,7 @@ | |
664 | } | |
665 | ||
666 | /* re-arm handler */ | |
667 | - ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL); | |
668 | + ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL); | |
669 | return ide_started; | |
670 | } | |
671 | ||
672 | @@ -1915,7 +1920,7 @@ | |
673 | #if 0 /* the immediate bit */ | |
674 | rq->cmd[1] = 1 << 3; | |
675 | #endif | |
676 | - rq->timeout = 2 * WAIT_CMD; | |
677 | + rq->timeout = ATAPI_WAIT_PC; | |
678 | ||
679 | return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr); | |
680 | } | |
681 | @@ -1956,7 +1961,7 @@ | |
682 | struct request *rq = HWGROUP(drive)->rq; | |
683 | ||
684 | if (!rq->timeout) | |
685 | - rq->timeout = WAIT_CMD; | |
686 | + rq->timeout = ATAPI_WAIT_PC; | |
687 | ||
688 | return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); | |
689 | } | |
690 | @@ -2483,7 +2488,7 @@ | |
691 | ide_drive_t *drive = (ide_drive_t*) cdi->handle; | |
692 | ||
693 | if (cgc->timeout <= 0) | |
694 | - cgc->timeout = WAIT_CMD; | |
695 | + cgc->timeout = ATAPI_WAIT_PC; | |
696 | ||
697 | /* here we queue the commands from the uniform CD-ROM | |
698 | layer. the packet must be complete, as we do not | |
699 | @@ -2688,37 +2693,49 @@ | |
700 | return 0; | |
701 | } | |
702 | ||
703 | +/* | |
704 | + * add logic to try GET_EVENT command first to check for media and tray | |
705 | + * status. this should be supported by newer cd-r/w and all DVD etc | |
706 | + * drives | |
707 | + */ | |
708 | static | |
709 | int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr) | |
710 | { | |
711 | ide_drive_t *drive = (ide_drive_t*) cdi->handle; | |
712 | + struct media_event_desc med; | |
713 | + struct request_sense sense; | |
714 | + int stat; | |
715 | ||
716 | - if (slot_nr == CDSL_CURRENT) { | |
717 | - struct request_sense sense; | |
718 | - int stat = cdrom_check_status(drive, &sense); | |
719 | - if (stat == 0 || sense.sense_key == UNIT_ATTENTION) | |
720 | - return CDS_DISC_OK; | |
721 | + if (slot_nr != CDSL_CURRENT) | |
722 | + return -EINVAL; | |
723 | ||
724 | - if (sense.sense_key == NOT_READY && sense.asc == 0x04 && | |
725 | - sense.ascq == 0x04) | |
726 | - return CDS_DISC_OK; | |
727 | + stat = cdrom_check_status(drive, &sense); | |
728 | + if (!stat || sense.sense_key == UNIT_ATTENTION) | |
729 | + return CDS_DISC_OK; | |
730 | ||
731 | + if (!cdrom_get_media_event(cdi, &med)) { | |
732 | + if (med.media_present) | |
733 | + return CDS_DISC_OK; | |
734 | + if (med.door_open) | |
735 | + return CDS_TRAY_OPEN; | |
736 | + } | |
737 | ||
738 | - /* | |
739 | - * If not using Mt Fuji extended media tray reports, | |
740 | - * just return TRAY_OPEN since ATAPI doesn't provide | |
741 | - * any other way to detect this... | |
742 | - */ | |
743 | - if (sense.sense_key == NOT_READY) { | |
744 | - if (sense.asc == 0x3a && sense.ascq == 1) | |
745 | - return CDS_NO_DISC; | |
746 | - else | |
747 | - return CDS_TRAY_OPEN; | |
748 | - } | |
749 | + if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04) | |
750 | + return CDS_DISC_OK; | |
751 | ||
752 | - return CDS_DRIVE_NOT_READY; | |
753 | + /* | |
754 | + * If not using Mt Fuji extended media tray reports, | |
755 | + * just return TRAY_OPEN since ATAPI doesn't provide | |
756 | + * any other way to detect this... | |
757 | + */ | |
758 | + if (sense.sense_key == NOT_READY) { | |
759 | + if (sense.asc == 0x3a && sense.ascq == 1) | |
760 | + return CDS_NO_DISC; | |
761 | + else | |
762 | + return CDS_TRAY_OPEN; | |
763 | } | |
764 | - return -EINVAL; | |
765 | + | |
766 | + return CDS_DRIVE_NOT_READY; | |
767 | } | |
768 | ||
769 | static | |
770 | @@ -2826,7 +2843,8 @@ | |
771 | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | | |
772 | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R | | |
773 | CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM | | |
774 | - CDC_GENERIC_PACKET | CDC_MO_DRIVE, | |
775 | + CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW | | |
776 | + CDC_MRW_W | CDC_RAM, | |
777 | .generic_packet = ide_cdrom_packet, | |
778 | }; | |
779 | ||
780 | @@ -2861,6 +2879,10 @@ | |
781 | devinfo->mask |= CDC_CLOSE_TRAY; | |
782 | if (!CDROM_CONFIG_FLAGS(drive)->mo_drive) | |
783 | devinfo->mask |= CDC_MO_DRIVE; | |
784 | + if (!CDROM_CONFIG_FLAGS(drive)->mrw) | |
785 | + devinfo->mask |= CDC_MRW; | |
786 | + if (!CDROM_CONFIG_FLAGS(drive)->mrw_w) | |
787 | + devinfo->mask |= CDC_MRW_W; | |
788 | ||
789 | return register_cdrom(devinfo); | |
790 | } | |
791 | @@ -2881,14 +2903,6 @@ | |
792 | !strcmp(drive->id->model, "WPI CDS-32X"))) | |
793 | size -= sizeof(cap->pad); | |
794 | ||
795 | - /* we have to cheat a little here. the packet will eventually | |
796 | - * be queued with ide_cdrom_packet(), which extracts the | |
797 | - * drive from cdi->handle. Since this device hasn't been | |
798 | - * registered with the Uniform layer yet, it can't do this. | |
799 | - * Same goes for cdi->ops. | |
800 | - */ | |
801 | - cdi->handle = (ide_drive_t *) drive; | |
802 | - cdi->ops = &ide_cdrom_dops; | |
803 | init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN); | |
804 | do { /* we seem to get stat=0x01,err=0x00 the first time (??) */ | |
805 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0); | |
806 | @@ -2904,7 +2918,7 @@ | |
807 | struct cdrom_info *info = drive->driver_data; | |
808 | struct cdrom_device_info *cdi = &info->devinfo; | |
809 | struct atapi_capabilities_page cap; | |
810 | - int nslots = 1; | |
811 | + int nslots = 1, mrw_write = 0; | |
812 | ||
813 | if (drive->media == ide_optical) { | |
814 | CDROM_CONFIG_FLAGS(drive)->mo_drive = 1; | |
815 | @@ -2912,15 +2926,34 @@ | |
816 | return nslots; | |
817 | } | |
818 | ||
819 | - if (CDROM_CONFIG_FLAGS(drive)->nec260) { | |
820 | - CDROM_CONFIG_FLAGS(drive)->no_eject = 0; | |
821 | - CDROM_CONFIG_FLAGS(drive)->audio_play = 1; | |
822 | + if (CDROM_CONFIG_FLAGS(drive)->nec260 || | |
823 | + !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) { | |
824 | + CDROM_CONFIG_FLAGS(drive)->no_eject = 0; | |
825 | + CDROM_CONFIG_FLAGS(drive)->audio_play = 1; | |
826 | return nslots; | |
827 | } | |
828 | ||
829 | + /* | |
830 | + * we have to cheat a little here. the packet will eventually | |
831 | + * be queued with ide_cdrom_packet(), which extracts the | |
832 | + * drive from cdi->handle. Since this device hasn't been | |
833 | + * registered with the Uniform layer yet, it can't do this. | |
834 | + * Same goes for cdi->ops. | |
835 | + */ | |
836 | + cdi->handle = (ide_drive_t *) drive; | |
837 | + cdi->ops = &ide_cdrom_dops; | |
838 | + | |
839 | if (ide_cdrom_get_capabilities(drive, &cap)) | |
840 | return 0; | |
841 | ||
842 | + if (!cdrom_is_mrw(cdi, &mrw_write)) { | |
843 | + CDROM_CONFIG_FLAGS(drive)->mrw = 1; | |
844 | + if (mrw_write) { | |
845 | + CDROM_CONFIG_FLAGS(drive)->mrw_w = 1; | |
846 | + CDROM_CONFIG_FLAGS(drive)->ram = 1; | |
847 | + } | |
848 | + } | |
849 | + | |
850 | if (cap.lock == 0) | |
851 | CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1; | |
852 | if (cap.eject) | |
853 | @@ -2933,8 +2966,10 @@ | |
854 | CDROM_CONFIG_FLAGS(drive)->test_write = 1; | |
855 | if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom) | |
856 | CDROM_CONFIG_FLAGS(drive)->dvd = 1; | |
857 | - if (cap.dvd_ram_write) | |
858 | + if (cap.dvd_ram_write) { | |
859 | CDROM_CONFIG_FLAGS(drive)->dvd_ram = 1; | |
860 | + CDROM_CONFIG_FLAGS(drive)->ram = 1; | |
861 | + } | |
862 | if (cap.dvd_r_write) | |
863 | CDROM_CONFIG_FLAGS(drive)->dvd_r = 1; | |
864 | if (cap.audio_play) | |
865 | @@ -2998,6 +3033,9 @@ | |
866 | (CDROM_CONFIG_FLAGS(drive)->cd_r)? "-R" : "", | |
867 | (CDROM_CONFIG_FLAGS(drive)->cd_rw)? "/RW" : ""); | |
868 | ||
869 | + if (CDROM_CONFIG_FLAGS(drive)->mrw || CDROM_CONFIG_FLAGS(drive)->mrw_w) | |
870 | + printk(" CD-MR%s", CDROM_CONFIG_FLAGS(drive)->mrw_w ? "W" : ""); | |
871 | + | |
872 | if (CDROM_CONFIG_FLAGS(drive)->is_changer) | |
873 | printk(" changer w/%d slots", nslots); | |
874 | else | |
875 | @@ -3105,12 +3143,6 @@ | |
876 | struct cdrom_device_info *cdi = &info->devinfo; | |
877 | int nslots; | |
878 | ||
879 | - /* | |
880 | - * default to read-only always and fix latter at the bottom | |
881 | - */ | |
882 | - set_disk_ro(drive->disk, 1); | |
883 | - blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); | |
884 | - | |
885 | blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); | |
886 | blk_queue_dma_alignment(drive->queue, 3); | |
887 | ||
888 | @@ -3215,8 +3247,11 @@ | |
889 | ||
890 | nslots = ide_cdrom_probe_capabilities (drive); | |
891 | ||
892 | - if (CDROM_CONFIG_FLAGS(drive)->dvd_ram) | |
893 | - set_disk_ro(drive->disk, 0); | |
894 | + /* | |
895 | + * set correct block size and read-only for non-ram media | |
896 | + */ | |
897 | + set_disk_ro(drive->disk, !CDROM_CONFIG_FLAGS(drive)->ram); | |
898 | + blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); | |
899 | ||
900 | #if 0 | |
901 | drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1; | |
902 | ===== drivers/ide/ide-cd.h 1.7 vs edited ===== | |
903 | --- 1.7/drivers/ide/ide-cd.h Sun Dec 14 00:58:07 2003 | |
904 | +++ edited/drivers/ide/ide-cd.h Wed Dec 17 21:57:43 2003 | |
905 | @@ -35,6 +35,11 @@ | |
906 | #define NO_DOOR_LOCKING 0 | |
907 | #endif | |
908 | ||
909 | +/* | |
910 | + * typical timeout for packet command | |
911 | + */ | |
912 | +#define ATAPI_WAIT_PC (60 * HZ) | |
913 | + | |
914 | /************************************************************************/ | |
915 | ||
916 | #define SECTOR_BITS 9 | |
917 | @@ -75,6 +80,9 @@ | |
918 | __u8 dvd : 1; /* Drive is a DVD-ROM */ | |
919 | __u8 dvd_r : 1; /* Drive can write DVD-R */ | |
920 | __u8 dvd_ram : 1; /* Drive can write DVD-RAM */ | |
921 | + __u8 mrw : 1; /* drive can read mrw */ | |
922 | + __u8 mrw_w : 1; /* drive can write mrw */ | |
923 | + __u8 ram : 1; /* generic WRITE (dvd-ram/mrw) */ | |
924 | __u8 test_write : 1; /* Drive can fake writes */ | |
925 | __u8 supp_disc_present : 1; /* Changer can report exact contents | |
926 | of slots. */ | |
927 | ===== drivers/scsi/sr.c 1.95 vs edited ===== | |
928 | --- 1.95/drivers/scsi/sr.c Wed Oct 22 07:09:52 2003 | |
929 | +++ edited/drivers/scsi/sr.c Wed Dec 17 21:53:24 2003 | |
930 | @@ -67,7 +67,8 @@ | |
931 | (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ | |
932 | CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \ | |
933 | CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \ | |
934 | - CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET) | |
935 | + CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \ | |
936 | + CDC_MRW|CDC_MRW_R|CDC_RAM) | |
937 | ||
938 | static int sr_probe(struct device *); | |
939 | static int sr_remove(struct device *); | |
940 | @@ -692,7 +693,7 @@ | |
941 | static void get_capabilities(struct scsi_cd *cd) | |
942 | { | |
943 | unsigned char *buffer; | |
944 | - int rc, n; | |
945 | + int rc, n, mwr_write = 0, mrw = 1; | |
946 | struct scsi_mode_data data; | |
947 | struct scsi_request *SRpnt; | |
948 | unsigned char cmd[MAX_COMMAND_SIZE]; | |
949 | @@ -765,6 +766,15 @@ | |
950 | printk("%s: scsi-1 drive\n", cd->cdi.name); | |
951 | return; | |
952 | } | |
953 | + | |
954 | + if (cdrom_is_mrw(&scsi_CDs[i].cdi, &mrw_write)) { | |
955 | + mrw = 0; | |
956 | + scsi_CDs[i].cdi.mask |= CDC_MRW; | |
957 | + scsi_CDs[i].cdi.mask |= CDC_MRW_W; | |
958 | + } | |
959 | + if (!mrw_write) | |
960 | + scsi_CDs[i].cdi.mask |= CDC_MRW_W; | |
961 | + | |
962 | n = data.header_length + data.block_descriptor_length; | |
963 | cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176; | |
964 | cd->readcd_known = 1; | |
965 | @@ -788,9 +798,7 @@ | |
966 | if ((buffer[n + 3] & 0x20) == 0) { | |
967 | /* can't write DVD-RAM media */ | |
968 | cd->cdi.mask |= CDC_DVD_RAM; | |
969 | - } else { | |
970 | - cd->device->writeable = 1; | |
971 | - } | |
972 | + } else | |
973 | if ((buffer[n + 3] & 0x10) == 0) | |
974 | /* can't write DVD-R media */ | |
975 | cd->cdi.mask |= CDC_DVD_R; | |
976 | @@ -813,6 +821,12 @@ | |
977 | cd->cdi.mask |= CDC_SELECT_DISC; | |
978 | /*else I don't think it can close its tray | |
979 | cd->cdi.mask |= CDC_CLOSE_TRAY; */ | |
980 | + | |
981 | + /* | |
982 | + * if DVD-RAM of MRW-W, we are randomly writeable | |
983 | + */ | |
984 | + if ((scsi_CDs[i].cdi.mask & (CDC_DVD_RAM | CDC_MRW_W)) != (CDC_DVD_RAM | CDC_MRW_W)) | |
985 | + scsi_CDs[i].device->writeable = 1; | |
986 | ||
987 | scsi_release_request(SRpnt); | |
988 | kfree(buffer); | |
989 | ===== include/linux/cdrom.h 1.14 vs edited ===== | |
990 | --- 1.14/include/linux/cdrom.h Fri Jun 6 15:05:30 2003 | |
991 | +++ edited/include/linux/cdrom.h Thu Dec 18 11:23:29 2003 | |
992 | @@ -5,7 +5,7 @@ | |
993 | * 1994, 1995 Eberhard Moenkeberg, emoenke@gwdg.de | |
994 | * 1996 David van Leeuwen, david@tm.tno.nl | |
995 | * 1997, 1998 Erik Andersen, andersee@debian.org | |
996 | - * 1998-2000 Jens Axboe, axboe@suse.de | |
997 | + * 1998-2002 Jens Axboe, axboe@suse.de | |
998 | */ | |
999 | ||
1000 | #ifndef _LINUX_CDROM_H | |
1001 | @@ -388,6 +388,9 @@ | |
1002 | #define CDC_DVD_R 0x10000 /* drive can write DVD-R */ | |
1003 | #define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */ | |
1004 | #define CDC_MO_DRIVE 0x40000 /* drive is an MO device */ | |
1005 | +#define CDC_MRW 0x80000 /* drive can read MRW */ | |
1006 | +#define CDC_MRW_W 0x100000 /* drive can write MRW */ | |
1007 | +#define CDC_RAM 0x200000 /* ok to open for WRITE */ | |
1008 | ||
1009 | /* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ | |
1010 | #define CDS_NO_INFO 0 /* if not implemented */ | |
1011 | @@ -715,92 +718,57 @@ | |
1012 | __u8 asb[46]; | |
1013 | }; | |
1014 | ||
1015 | -#ifdef __KERNEL__ | |
1016 | -#include <linux/fs.h> /* not really needed, later.. */ | |
1017 | -#include <linux/device.h> | |
1018 | - | |
1019 | -struct cdrom_write_settings { | |
1020 | - unsigned char fpacket; /* fixed/variable packets */ | |
1021 | - unsigned long packet_size; /* write out this number of packets */ | |
1022 | - unsigned long nwa; /* next writeable address */ | |
1023 | - unsigned char writeable; /* cdrom is writeable */ | |
1024 | -}; | |
1025 | - | |
1026 | -/* Uniform cdrom data structures for cdrom.c */ | |
1027 | -struct cdrom_device_info { | |
1028 | - struct cdrom_device_ops *ops; /* link to device_ops */ | |
1029 | - struct cdrom_device_info *next; /* next device_info for this major */ | |
1030 | - void *handle; /* driver-dependent data */ | |
1031 | -/* specifications */ | |
1032 | - int mask; /* mask of capability: disables them */ | |
1033 | - int speed; /* maximum speed for reading data */ | |
1034 | - int capacity; /* number of discs in jukebox */ | |
1035 | -/* device-related storage */ | |
1036 | - int options : 30; /* options flags */ | |
1037 | - unsigned mc_flags : 2; /* media change buffer flags */ | |
1038 | - int use_count; /* number of times device opened */ | |
1039 | - char name[20]; /* name of the device type */ | |
1040 | -/* per-device flags */ | |
1041 | - __u8 sanyo_slot : 2; /* Sanyo 3 CD changer support */ | |
1042 | - __u8 reserved : 6; /* not used yet */ | |
1043 | - struct cdrom_write_settings write; | |
1044 | -}; | |
1045 | - | |
1046 | -struct cdrom_device_ops { | |
1047 | -/* routines */ | |
1048 | - int (*open) (struct cdrom_device_info *, int); | |
1049 | - void (*release) (struct cdrom_device_info *); | |
1050 | - int (*drive_status) (struct cdrom_device_info *, int); | |
1051 | - int (*media_changed) (struct cdrom_device_info *, int); | |
1052 | - int (*tray_move) (struct cdrom_device_info *, int); | |
1053 | - int (*lock_door) (struct cdrom_device_info *, int); | |
1054 | - int (*select_speed) (struct cdrom_device_info *, int); | |
1055 | - int (*select_disc) (struct cdrom_device_info *, int); | |
1056 | - int (*get_last_session) (struct cdrom_device_info *, | |
1057 | - struct cdrom_multisession *); | |
1058 | - int (*get_mcn) (struct cdrom_device_info *, | |
1059 | - struct cdrom_mcn *); | |
1060 | - /* hard reset device */ | |
1061 | - int (*reset) (struct cdrom_device_info *); | |
1062 | - /* play stuff */ | |
1063 | - int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *); | |
1064 | - /* dev-specific */ | |
1065 | - int (*dev_ioctl) (struct cdrom_device_info *, | |
1066 | - unsigned int, unsigned long); | |
1067 | -/* driver specifications */ | |
1068 | - const int capability; /* capability flags */ | |
1069 | - int n_minors; /* number of active minor devices */ | |
1070 | - /* handle uniform packets for scsi type devices (scsi,atapi) */ | |
1071 | - int (*generic_packet) (struct cdrom_device_info *, | |
1072 | - struct cdrom_generic_command *); | |
1073 | -}; | |
1074 | +/* | |
1075 | + * feature profile | |
1076 | + */ | |
1077 | +#define CDF_MRW 0x28 | |
1078 | ||
1079 | -/* the general block_device operations structure: */ | |
1080 | -extern int cdrom_open(struct cdrom_device_info *, struct inode *, struct file *); | |
1081 | -extern int cdrom_release(struct cdrom_device_info *, struct file *); | |
1082 | -extern int cdrom_ioctl(struct cdrom_device_info *, struct inode *, unsigned, unsigned long); | |
1083 | -extern int cdrom_media_changed(struct cdrom_device_info *); | |
1084 | +/* | |
1085 | + * media status bits | |
1086 | + */ | |
1087 | +#define CDM_MRW_NOTMRW 0 | |
1088 | +#define CDM_MRW_BGFORMAT_INACTIVE 1 | |
1089 | +#define CDM_MRW_BGFORMAT_ACTIVE 2 | |
1090 | +#define CDM_MRW_BGFORMAT_COMPLETE 3 | |
1091 | ||
1092 | -extern int register_cdrom(struct cdrom_device_info *cdi); | |
1093 | -extern int unregister_cdrom(struct cdrom_device_info *cdi); | |
1094 | +/* | |
1095 | + * mrw address spaces | |
1096 | + */ | |
1097 | +#define MRW_LBA_DMA 0 | |
1098 | +#define MRW_LBA_GAA 1 | |
1099 | ||
1100 | -typedef struct { | |
1101 | - int data; | |
1102 | - int audio; | |
1103 | - int cdi; | |
1104 | - int xa; | |
1105 | - long error; | |
1106 | -} tracktype; | |
1107 | +/* | |
1108 | + * mrw mode pages (first is deprecated) -- probed at init time and | |
1109 | + * cdi->mrw_mode_page is set | |
1110 | + */ | |
1111 | +#define MRW_MODE_PC_PRE1 0x2c | |
1112 | +#define MRW_MODE_PC 0x03 | |
1113 | ||
1114 | -extern int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written); | |
1115 | -extern int cdrom_number_of_slots(struct cdrom_device_info *cdi); | |
1116 | -extern int cdrom_mode_select(struct cdrom_device_info *cdi, | |
1117 | - struct cdrom_generic_command *cgc); | |
1118 | -extern int cdrom_mode_sense(struct cdrom_device_info *cdi, | |
1119 | - struct cdrom_generic_command *cgc, | |
1120 | - int page_code, int page_control); | |
1121 | -extern void init_cdrom_command(struct cdrom_generic_command *cgc, | |
1122 | - void *buffer, int len, int type); | |
1123 | +struct mrw_feature_desc { | |
1124 | + __u16 feature_code; | |
1125 | +#if defined(__BIG_ENDIAN_BITFIELD) | |
1126 | + __u8 reserved1 : 2; | |
1127 | + __u8 feature_version : 4; | |
1128 | + __u8 persistent : 1; | |
1129 | + __u8 curr : 1; | |
1130 | +#elif defined(__LITTLE_ENDIAN_BITFIELD) | |
1131 | + __u8 curr : 1; | |
1132 | + __u8 persistent : 1; | |
1133 | + __u8 feature_version : 4; | |
1134 | + __u8 reserved1 : 2; | |
1135 | +#endif | |
1136 | + __u8 add_len; | |
1137 | +#if defined(__BIG_ENDIAN_BITFIELD) | |
1138 | + __u8 reserved2 : 7; | |
1139 | + __u8 write : 1; | |
1140 | +#elif defined(__LITTLE_ENDIAN_BITFIELD) | |
1141 | + __u8 write : 1; | |
1142 | + __u8 reserved2 : 7; | |
1143 | +#endif | |
1144 | + __u8 reserved3; | |
1145 | + __u8 reserved4; | |
1146 | + __u8 reserved5; | |
1147 | +}; | |
1148 | ||
1149 | typedef struct { | |
1150 | __u16 disc_information_length; | |
1151 | @@ -825,9 +793,13 @@ | |
1152 | __u8 did_v : 1; | |
1153 | __u8 dbc_v : 1; | |
1154 | __u8 uru : 1; | |
1155 | - __u8 reserved2 : 5; | |
1156 | + __u8 reserved2 : 2; | |
1157 | + __u8 dbit : 1; | |
1158 | + __u8 mrw_status : 2; | |
1159 | #elif defined(__LITTLE_ENDIAN_BITFIELD) | |
1160 | - __u8 reserved2 : 5; | |
1161 | + __u8 mrw_status : 2; | |
1162 | + __u8 dbit : 1; | |
1163 | + __u8 reserved2 : 2; | |
1164 | __u8 uru : 1; | |
1165 | __u8 dbc_v : 1; | |
1166 | __u8 did_v : 1; | |
1167 | @@ -884,6 +856,103 @@ | |
1168 | __u32 last_rec_address; | |
1169 | } track_information; | |
1170 | ||
1171 | +struct feature_header { | |
1172 | + __u32 data_len; | |
1173 | + __u8 reserved1; | |
1174 | + __u8 reserved2; | |
1175 | + __u16 curr_profile; | |
1176 | +}; | |
1177 | + | |
1178 | +struct mode_page_header { | |
1179 | + __u16 mode_data_length; | |
1180 | + __u8 medium_type; | |
1181 | + __u8 reserved1; | |
1182 | + __u8 reserved2; | |
1183 | + __u8 reserved3; | |
1184 | + __u16 desc_length; | |
1185 | +}; | |
1186 | + | |
1187 | +#ifdef __KERNEL__ | |
1188 | +#include <linux/fs.h> /* not really needed, later.. */ | |
1189 | +#include <linux/device.h> | |
1190 | + | |
1191 | +/* Uniform cdrom data structures for cdrom.c */ | |
1192 | +struct cdrom_device_info { | |
1193 | + struct cdrom_device_ops *ops; /* link to device_ops */ | |
1194 | + struct cdrom_device_info *next; /* next device_info for this major */ | |
1195 | + void *handle; /* driver-dependent data */ | |
1196 | +/* specifications */ | |
1197 | + int mask; /* mask of capability: disables them */ | |
1198 | + int speed; /* maximum speed for reading data */ | |
1199 | + int capacity; /* number of discs in jukebox */ | |
1200 | +/* device-related storage */ | |
1201 | + int options : 30; /* options flags */ | |
1202 | + unsigned mc_flags : 2; /* media change buffer flags */ | |
1203 | + int use_count; /* number of times device opened */ | |
1204 | + char name[20]; /* name of the device type */ | |
1205 | +/* per-device flags */ | |
1206 | + __u8 sanyo_slot : 2; /* Sanyo 3 CD changer support */ | |
1207 | + __u8 reserved : 6; /* not used yet */ | |
1208 | + int (*exit)(struct cdrom_device_info *); | |
1209 | + int mrw_mode_page; | |
1210 | +}; | |
1211 | + | |
1212 | +struct cdrom_device_ops { | |
1213 | +/* routines */ | |
1214 | + int (*open) (struct cdrom_device_info *, int); | |
1215 | + void (*release) (struct cdrom_device_info *); | |
1216 | + int (*drive_status) (struct cdrom_device_info *, int); | |
1217 | + int (*media_changed) (struct cdrom_device_info *, int); | |
1218 | + int (*tray_move) (struct cdrom_device_info *, int); | |
1219 | + int (*lock_door) (struct cdrom_device_info *, int); | |
1220 | + int (*select_speed) (struct cdrom_device_info *, int); | |
1221 | + int (*select_disc) (struct cdrom_device_info *, int); | |
1222 | + int (*get_last_session) (struct cdrom_device_info *, | |
1223 | + struct cdrom_multisession *); | |
1224 | + int (*get_mcn) (struct cdrom_device_info *, | |
1225 | + struct cdrom_mcn *); | |
1226 | + /* hard reset device */ | |
1227 | + int (*reset) (struct cdrom_device_info *); | |
1228 | + /* play stuff */ | |
1229 | + int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *); | |
1230 | + /* dev-specific */ | |
1231 | + int (*dev_ioctl) (struct cdrom_device_info *, | |
1232 | + unsigned int, unsigned long); | |
1233 | +/* driver specifications */ | |
1234 | + const int capability; /* capability flags */ | |
1235 | + int n_minors; /* number of active minor devices */ | |
1236 | + /* handle uniform packets for scsi type devices (scsi,atapi) */ | |
1237 | + int (*generic_packet) (struct cdrom_device_info *, | |
1238 | + struct cdrom_generic_command *); | |
1239 | +}; | |
1240 | + | |
1241 | +/* the general block_device operations structure: */ | |
1242 | +extern int cdrom_open(struct cdrom_device_info *, struct inode *, struct file *); | |
1243 | +extern int cdrom_release(struct cdrom_device_info *, struct file *); | |
1244 | +extern int cdrom_ioctl(struct cdrom_device_info *, struct inode *, unsigned, unsigned long); | |
1245 | +extern int cdrom_media_changed(struct cdrom_device_info *); | |
1246 | + | |
1247 | +extern int register_cdrom(struct cdrom_device_info *cdi); | |
1248 | +extern int unregister_cdrom(struct cdrom_device_info *cdi); | |
1249 | + | |
1250 | +typedef struct { | |
1251 | + int data; | |
1252 | + int audio; | |
1253 | + int cdi; | |
1254 | + int xa; | |
1255 | + long error; | |
1256 | +} tracktype; | |
1257 | + | |
1258 | +extern int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written); | |
1259 | +extern int cdrom_number_of_slots(struct cdrom_device_info *cdi); | |
1260 | +extern int cdrom_mode_select(struct cdrom_device_info *cdi, | |
1261 | + struct cdrom_generic_command *cgc); | |
1262 | +extern int cdrom_mode_sense(struct cdrom_device_info *cdi, | |
1263 | + struct cdrom_generic_command *cgc, | |
1264 | + int page_code, int page_control); | |
1265 | +extern void init_cdrom_command(struct cdrom_generic_command *cgc, | |
1266 | + void *buffer, int len, int type); | |
1267 | + | |
1268 | /* The SCSI spec says there could be 256 slots. */ | |
1269 | #define CDROM_MAX_SLOTS 256 | |
1270 | ||
1271 | @@ -934,15 +1003,6 @@ | |
1272 | mechtype_cartridge_changer = 5 | |
1273 | } mechtype_t; | |
1274 | ||
1275 | -struct mode_page_header { | |
1276 | - __u16 mode_data_length; | |
1277 | - __u8 medium_type; | |
1278 | - __u8 reserved1; | |
1279 | - __u8 reserved2; | |
1280 | - __u8 reserved3; | |
1281 | - __u16 desc_length; | |
1282 | -}; | |
1283 | - | |
1284 | typedef struct { | |
1285 | #if defined(__BIG_ENDIAN_BITFIELD) | |
1286 | __u8 ps : 1; | |
1287 | @@ -1031,6 +1091,41 @@ | |
1288 | __u8 rpc_scheme; | |
1289 | __u8 reserved3; | |
1290 | } rpc_state_t; | |
1291 | + | |
1292 | +struct event_header { | |
1293 | + __u16 data_len; | |
1294 | +#if defined(__BIG_ENDIAN_BITFIELD) | |
1295 | + __u8 nea : 1; | |
1296 | + __u8 reserved1 : 4; | |
1297 | + __u8 notification_class : 3; | |
1298 | +#elif defined(__LITTLE_ENDIAN_BITFIELD) | |
1299 | + __u8 notification_class : 3; | |
1300 | + __u8 reserved1 : 4; | |
1301 | + __u8 nea : 1; | |
1302 | +#endif | |
1303 | + __u8 supp_event_class; | |
1304 | +}; | |
1305 | + | |
1306 | +struct media_event_desc { | |
1307 | +#if defined(__BIG_ENDIAN_BITFIELD) | |
1308 | + __u8 reserved1 : 4; | |
1309 | + __u8 media_event_code : 4; | |
1310 | + __u8 reserved2 : 6; | |
1311 | + __u8 media_present : 1; | |
1312 | + __u8 door_open : 1; | |
1313 | +#elif defined(__LITTLE_ENDIAN_BITFIELD) | |
1314 | + __u8 media_event_code : 4; | |
1315 | + __u8 reserved1 : 4; | |
1316 | + __u8 door_open : 1; | |
1317 | + __u8 media_present : 1; | |
1318 | + __u8 reserved2 : 6; | |
1319 | +#endif | |
1320 | + __u8 start_slot; | |
1321 | + __u8 end_slot; | |
1322 | +}; | |
1323 | + | |
1324 | +extern int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med); | |
1325 | +extern int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write); | |
1326 | ||
1327 | #endif /* End of kernel only stuff */ | |
1328 |