1 | /* |
2 | * Copyright (C) 2000 Jens Axboe <axboe@suse.de> |
3 | * Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com> |
4 | * Copyright (C) 2006 Thomas Maier <balagi@justmail.de> |
5 | * |
6 | * May be copied or modified under the terms of the GNU General Public |
7 | * License. See linux/COPYING for more information. |
8 | * |
9 | * Packet writing layer for ATAPI and SCSI CD-RW, DVD+RW, DVD-RW and |
10 | * DVD-RAM devices. |
11 | * |
12 | * Theory of operation: |
13 | * |
14 | * At the lowest level, there is the standard driver for the CD/DVD device, |
15 | * such as drivers/scsi/sr.c. This driver can handle read and write requests, |
16 | * but it doesn't know anything about the special restrictions that apply to |
17 | * packet writing. One restriction is that write requests must be aligned to |
18 | * packet boundaries on the physical media, and the size of a write request |
19 | * must be equal to the packet size. Another restriction is that a |
20 | * GPCMD_FLUSH_CACHE command has to be issued to the drive before a read |
21 | * command, if the previous command was a write. |
22 | * |
23 | * The purpose of the packet writing driver is to hide these restrictions from |
24 | * higher layers, such as file systems, and present a block device that can be |
25 | * randomly read and written using 2kB-sized blocks. |
26 | * |
27 | * The lowest layer in the packet writing driver is the packet I/O scheduler. |
28 | * Its data is defined by the struct packet_iosched and includes two bio |
29 | * queues with pending read and write requests. These queues are processed |
30 | * by the pkt_iosched_process_queue() function. The write requests in this |
31 | * queue are already properly aligned and sized. This layer is responsible for |
32 | * issuing the flush cache commands and scheduling the I/O in a good order. |
33 | * |
34 | * The next layer transforms unaligned write requests to aligned writes. This |
35 | * transformation requires reading missing pieces of data from the underlying |
36 | * block device, assembling the pieces to full packets and queuing them to the |
37 | * packet I/O scheduler. |
38 | * |
39 | * At the top layer there is a custom ->submit_bio function that forwards |
40 | * read requests directly to the iosched queue and puts write requests in the |
41 | * unaligned write queue. A kernel thread performs the necessary read |
42 | * gathering to convert the unaligned writes to aligned writes and then feeds |
43 | * them to the packet I/O scheduler. |
44 | * |
45 | *************************************************************************/ |
46 | |
47 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
48 | |
49 | #include <linux/backing-dev.h> |
50 | #include <linux/compat.h> |
51 | #include <linux/debugfs.h> |
52 | #include <linux/device.h> |
53 | #include <linux/errno.h> |
54 | #include <linux/file.h> |
55 | #include <linux/freezer.h> |
56 | #include <linux/kernel.h> |
57 | #include <linux/kthread.h> |
58 | #include <linux/miscdevice.h> |
59 | #include <linux/module.h> |
60 | #include <linux/mutex.h> |
61 | #include <linux/nospec.h> |
62 | #include <linux/pktcdvd.h> |
63 | #include <linux/proc_fs.h> |
64 | #include <linux/seq_file.h> |
65 | #include <linux/slab.h> |
66 | #include <linux/spinlock.h> |
67 | #include <linux/types.h> |
68 | #include <linux/uaccess.h> |
69 | |
70 | #include <scsi/scsi.h> |
71 | #include <scsi/scsi_cmnd.h> |
72 | #include <scsi/scsi_ioctl.h> |
73 | |
74 | #include <asm/unaligned.h> |
75 | |
76 | #define DRIVER_NAME "pktcdvd" |
77 | |
78 | #define MAX_SPEED 0xffff |
79 | |
80 | static DEFINE_MUTEX(pktcdvd_mutex); |
81 | static struct pktcdvd_device *pkt_devs[MAX_WRITERS]; |
82 | static struct proc_dir_entry *pkt_proc; |
83 | static int pktdev_major; |
84 | static int write_congestion_on = PKT_WRITE_CONGESTION_ON; |
85 | static int write_congestion_off = PKT_WRITE_CONGESTION_OFF; |
86 | static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */ |
87 | static mempool_t psd_pool; |
88 | static struct bio_set pkt_bio_set; |
89 | |
90 | /* /sys/class/pktcdvd */ |
91 | static struct class class_pktcdvd; |
92 | static struct dentry *pkt_debugfs_root = NULL; /* /sys/kernel/debug/pktcdvd */ |
93 | |
94 | /* forward declaration */ |
95 | static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev); |
96 | static int pkt_remove_dev(dev_t pkt_dev); |
97 | |
98 | static sector_t get_zone(sector_t sector, struct pktcdvd_device *pd) |
99 | { |
100 | return (sector + pd->offset) & ~(sector_t)(pd->settings.size - 1); |
101 | } |
102 | |
103 | /********************************************************** |
104 | * sysfs interface for pktcdvd |
105 | * by (C) 2006 Thomas Maier <balagi@justmail.de> |
106 | |
107 | /sys/class/pktcdvd/pktcdvd[0-7]/ |
108 | stat/reset |
109 | stat/packets_started |
110 | stat/packets_finished |
111 | stat/kb_written |
112 | stat/kb_read |
113 | stat/kb_read_gather |
114 | write_queue/size |
115 | write_queue/congestion_off |
116 | write_queue/congestion_on |
117 | **********************************************************/ |
118 | |
119 | static ssize_t packets_started_show(struct device *dev, |
120 | struct device_attribute *attr, char *buf) |
121 | { |
122 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
123 | |
124 | return sysfs_emit(buf, fmt: "%lu\n" , pd->stats.pkt_started); |
125 | } |
126 | static DEVICE_ATTR_RO(packets_started); |
127 | |
128 | static ssize_t packets_finished_show(struct device *dev, |
129 | struct device_attribute *attr, char *buf) |
130 | { |
131 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
132 | |
133 | return sysfs_emit(buf, fmt: "%lu\n" , pd->stats.pkt_ended); |
134 | } |
135 | static DEVICE_ATTR_RO(packets_finished); |
136 | |
137 | static ssize_t kb_written_show(struct device *dev, |
138 | struct device_attribute *attr, char *buf) |
139 | { |
140 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
141 | |
142 | return sysfs_emit(buf, fmt: "%lu\n" , pd->stats.secs_w >> 1); |
143 | } |
144 | static DEVICE_ATTR_RO(kb_written); |
145 | |
146 | static ssize_t kb_read_show(struct device *dev, |
147 | struct device_attribute *attr, char *buf) |
148 | { |
149 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
150 | |
151 | return sysfs_emit(buf, fmt: "%lu\n" , pd->stats.secs_r >> 1); |
152 | } |
153 | static DEVICE_ATTR_RO(kb_read); |
154 | |
155 | static ssize_t kb_read_gather_show(struct device *dev, |
156 | struct device_attribute *attr, char *buf) |
157 | { |
158 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
159 | |
160 | return sysfs_emit(buf, fmt: "%lu\n" , pd->stats.secs_rg >> 1); |
161 | } |
162 | static DEVICE_ATTR_RO(kb_read_gather); |
163 | |
164 | static ssize_t reset_store(struct device *dev, struct device_attribute *attr, |
165 | const char *buf, size_t len) |
166 | { |
167 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
168 | |
169 | if (len > 0) { |
170 | pd->stats.pkt_started = 0; |
171 | pd->stats.pkt_ended = 0; |
172 | pd->stats.secs_w = 0; |
173 | pd->stats.secs_rg = 0; |
174 | pd->stats.secs_r = 0; |
175 | } |
176 | return len; |
177 | } |
178 | static DEVICE_ATTR_WO(reset); |
179 | |
180 | static struct attribute *pkt_stat_attrs[] = { |
181 | &dev_attr_packets_finished.attr, |
182 | &dev_attr_packets_started.attr, |
183 | &dev_attr_kb_read.attr, |
184 | &dev_attr_kb_written.attr, |
185 | &dev_attr_kb_read_gather.attr, |
186 | &dev_attr_reset.attr, |
187 | NULL, |
188 | }; |
189 | |
190 | static const struct attribute_group pkt_stat_group = { |
191 | .name = "stat" , |
192 | .attrs = pkt_stat_attrs, |
193 | }; |
194 | |
195 | static ssize_t size_show(struct device *dev, |
196 | struct device_attribute *attr, char *buf) |
197 | { |
198 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
199 | int n; |
200 | |
201 | spin_lock(lock: &pd->lock); |
202 | n = sysfs_emit(buf, fmt: "%d\n" , pd->bio_queue_size); |
203 | spin_unlock(lock: &pd->lock); |
204 | return n; |
205 | } |
206 | static DEVICE_ATTR_RO(size); |
207 | |
208 | static void init_write_congestion_marks(int* lo, int* hi) |
209 | { |
210 | if (*hi > 0) { |
211 | *hi = max(*hi, 500); |
212 | *hi = min(*hi, 1000000); |
213 | if (*lo <= 0) |
214 | *lo = *hi - 100; |
215 | else { |
216 | *lo = min(*lo, *hi - 100); |
217 | *lo = max(*lo, 100); |
218 | } |
219 | } else { |
220 | *hi = -1; |
221 | *lo = -1; |
222 | } |
223 | } |
224 | |
225 | static ssize_t congestion_off_show(struct device *dev, |
226 | struct device_attribute *attr, char *buf) |
227 | { |
228 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
229 | int n; |
230 | |
231 | spin_lock(lock: &pd->lock); |
232 | n = sysfs_emit(buf, fmt: "%d\n" , pd->write_congestion_off); |
233 | spin_unlock(lock: &pd->lock); |
234 | return n; |
235 | } |
236 | |
237 | static ssize_t congestion_off_store(struct device *dev, |
238 | struct device_attribute *attr, |
239 | const char *buf, size_t len) |
240 | { |
241 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
242 | int val, ret; |
243 | |
244 | ret = kstrtoint(s: buf, base: 10, res: &val); |
245 | if (ret) |
246 | return ret; |
247 | |
248 | spin_lock(lock: &pd->lock); |
249 | pd->write_congestion_off = val; |
250 | init_write_congestion_marks(lo: &pd->write_congestion_off, hi: &pd->write_congestion_on); |
251 | spin_unlock(lock: &pd->lock); |
252 | return len; |
253 | } |
254 | static DEVICE_ATTR_RW(congestion_off); |
255 | |
256 | static ssize_t congestion_on_show(struct device *dev, |
257 | struct device_attribute *attr, char *buf) |
258 | { |
259 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
260 | int n; |
261 | |
262 | spin_lock(lock: &pd->lock); |
263 | n = sysfs_emit(buf, fmt: "%d\n" , pd->write_congestion_on); |
264 | spin_unlock(lock: &pd->lock); |
265 | return n; |
266 | } |
267 | |
268 | static ssize_t congestion_on_store(struct device *dev, |
269 | struct device_attribute *attr, |
270 | const char *buf, size_t len) |
271 | { |
272 | struct pktcdvd_device *pd = dev_get_drvdata(dev); |
273 | int val, ret; |
274 | |
275 | ret = kstrtoint(s: buf, base: 10, res: &val); |
276 | if (ret) |
277 | return ret; |
278 | |
279 | spin_lock(lock: &pd->lock); |
280 | pd->write_congestion_on = val; |
281 | init_write_congestion_marks(lo: &pd->write_congestion_off, hi: &pd->write_congestion_on); |
282 | spin_unlock(lock: &pd->lock); |
283 | return len; |
284 | } |
285 | static DEVICE_ATTR_RW(congestion_on); |
286 | |
287 | static struct attribute *pkt_wq_attrs[] = { |
288 | &dev_attr_congestion_on.attr, |
289 | &dev_attr_congestion_off.attr, |
290 | &dev_attr_size.attr, |
291 | NULL, |
292 | }; |
293 | |
294 | static const struct attribute_group pkt_wq_group = { |
295 | .name = "write_queue" , |
296 | .attrs = pkt_wq_attrs, |
297 | }; |
298 | |
299 | static const struct attribute_group *pkt_groups[] = { |
300 | &pkt_stat_group, |
301 | &pkt_wq_group, |
302 | NULL, |
303 | }; |
304 | |
305 | static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) |
306 | { |
307 | if (class_is_registered(class: &class_pktcdvd)) { |
308 | pd->dev = device_create_with_groups(cls: &class_pktcdvd, NULL, |
309 | MKDEV(0, 0), drvdata: pd, groups: pkt_groups, |
310 | fmt: "%s" , pd->disk->disk_name); |
311 | if (IS_ERR(ptr: pd->dev)) |
312 | pd->dev = NULL; |
313 | } |
314 | } |
315 | |
316 | static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd) |
317 | { |
318 | if (class_is_registered(class: &class_pktcdvd)) |
319 | device_unregister(dev: pd->dev); |
320 | } |
321 | |
322 | |
323 | /******************************************************************** |
324 | /sys/class/pktcdvd/ |
325 | add map block device |
326 | remove unmap packet dev |
327 | device_map show mappings |
328 | *******************************************************************/ |
329 | |
330 | static ssize_t device_map_show(const struct class *c, const struct class_attribute *attr, |
331 | char *data) |
332 | { |
333 | int n = 0; |
334 | int idx; |
335 | mutex_lock_nested(lock: &ctl_mutex, SINGLE_DEPTH_NESTING); |
336 | for (idx = 0; idx < MAX_WRITERS; idx++) { |
337 | struct pktcdvd_device *pd = pkt_devs[idx]; |
338 | if (!pd) |
339 | continue; |
340 | n += sysfs_emit_at(buf: data, at: n, fmt: "%s %u:%u %u:%u\n" , |
341 | pd->disk->disk_name, |
342 | MAJOR(pd->pkt_dev), MINOR(pd->pkt_dev), |
343 | MAJOR(pd->bdev_handle->bdev->bd_dev), |
344 | MINOR(pd->bdev_handle->bdev->bd_dev)); |
345 | } |
346 | mutex_unlock(lock: &ctl_mutex); |
347 | return n; |
348 | } |
349 | static CLASS_ATTR_RO(device_map); |
350 | |
351 | static ssize_t add_store(const struct class *c, const struct class_attribute *attr, |
352 | const char *buf, size_t count) |
353 | { |
354 | unsigned int major, minor; |
355 | |
356 | if (sscanf(buf, "%u:%u" , &major, &minor) == 2) { |
357 | /* pkt_setup_dev() expects caller to hold reference to self */ |
358 | if (!try_module_get(THIS_MODULE)) |
359 | return -ENODEV; |
360 | |
361 | pkt_setup_dev(MKDEV(major, minor), NULL); |
362 | |
363 | module_put(THIS_MODULE); |
364 | |
365 | return count; |
366 | } |
367 | |
368 | return -EINVAL; |
369 | } |
370 | static CLASS_ATTR_WO(add); |
371 | |
372 | static ssize_t remove_store(const struct class *c, const struct class_attribute *attr, |
373 | const char *buf, size_t count) |
374 | { |
375 | unsigned int major, minor; |
376 | if (sscanf(buf, "%u:%u" , &major, &minor) == 2) { |
377 | pkt_remove_dev(MKDEV(major, minor)); |
378 | return count; |
379 | } |
380 | return -EINVAL; |
381 | } |
382 | static CLASS_ATTR_WO(remove); |
383 | |
384 | static struct attribute *class_pktcdvd_attrs[] = { |
385 | &class_attr_add.attr, |
386 | &class_attr_remove.attr, |
387 | &class_attr_device_map.attr, |
388 | NULL, |
389 | }; |
390 | ATTRIBUTE_GROUPS(class_pktcdvd); |
391 | |
392 | static struct class class_pktcdvd = { |
393 | .name = DRIVER_NAME, |
394 | .class_groups = class_pktcdvd_groups, |
395 | }; |
396 | |
397 | static int pkt_sysfs_init(void) |
398 | { |
399 | /* |
400 | * create control files in sysfs |
401 | * /sys/class/pktcdvd/... |
402 | */ |
403 | return class_register(class: &class_pktcdvd); |
404 | } |
405 | |
406 | static void pkt_sysfs_cleanup(void) |
407 | { |
408 | class_unregister(class: &class_pktcdvd); |
409 | } |
410 | |
411 | /******************************************************************** |
412 | entries in debugfs |
413 | |
414 | /sys/kernel/debug/pktcdvd[0-7]/ |
415 | info |
416 | |
417 | *******************************************************************/ |
418 | |
419 | static void pkt_count_states(struct pktcdvd_device *pd, int *states) |
420 | { |
421 | struct packet_data *pkt; |
422 | int i; |
423 | |
424 | for (i = 0; i < PACKET_NUM_STATES; i++) |
425 | states[i] = 0; |
426 | |
427 | spin_lock(lock: &pd->cdrw.active_list_lock); |
428 | list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { |
429 | states[pkt->state]++; |
430 | } |
431 | spin_unlock(lock: &pd->cdrw.active_list_lock); |
432 | } |
433 | |
434 | static int pkt_seq_show(struct seq_file *m, void *p) |
435 | { |
436 | struct pktcdvd_device *pd = m->private; |
437 | char *msg; |
438 | int states[PACKET_NUM_STATES]; |
439 | |
440 | seq_printf(m, fmt: "Writer %s mapped to %pg:\n" , pd->disk->disk_name, |
441 | pd->bdev_handle->bdev); |
442 | |
443 | seq_printf(m, fmt: "\nSettings:\n" ); |
444 | seq_printf(m, fmt: "\tpacket size:\t\t%dkB\n" , pd->settings.size / 2); |
445 | |
446 | if (pd->settings.write_type == 0) |
447 | msg = "Packet" ; |
448 | else |
449 | msg = "Unknown" ; |
450 | seq_printf(m, fmt: "\twrite type:\t\t%s\n" , msg); |
451 | |
452 | seq_printf(m, fmt: "\tpacket type:\t\t%s\n" , pd->settings.fp ? "Fixed" : "Variable" ); |
453 | seq_printf(m, fmt: "\tlink loss:\t\t%d\n" , pd->settings.link_loss); |
454 | |
455 | seq_printf(m, fmt: "\ttrack mode:\t\t%d\n" , pd->settings.track_mode); |
456 | |
457 | if (pd->settings.block_mode == PACKET_BLOCK_MODE1) |
458 | msg = "Mode 1" ; |
459 | else if (pd->settings.block_mode == PACKET_BLOCK_MODE2) |
460 | msg = "Mode 2" ; |
461 | else |
462 | msg = "Unknown" ; |
463 | seq_printf(m, fmt: "\tblock mode:\t\t%s\n" , msg); |
464 | |
465 | seq_printf(m, fmt: "\nStatistics:\n" ); |
466 | seq_printf(m, fmt: "\tpackets started:\t%lu\n" , pd->stats.pkt_started); |
467 | seq_printf(m, fmt: "\tpackets ended:\t\t%lu\n" , pd->stats.pkt_ended); |
468 | seq_printf(m, fmt: "\twritten:\t\t%lukB\n" , pd->stats.secs_w >> 1); |
469 | seq_printf(m, fmt: "\tread gather:\t\t%lukB\n" , pd->stats.secs_rg >> 1); |
470 | seq_printf(m, fmt: "\tread:\t\t\t%lukB\n" , pd->stats.secs_r >> 1); |
471 | |
472 | seq_printf(m, fmt: "\nMisc:\n" ); |
473 | seq_printf(m, fmt: "\treference count:\t%d\n" , pd->refcnt); |
474 | seq_printf(m, fmt: "\tflags:\t\t\t0x%lx\n" , pd->flags); |
475 | seq_printf(m, fmt: "\tread speed:\t\t%ukB/s\n" , pd->read_speed); |
476 | seq_printf(m, fmt: "\twrite speed:\t\t%ukB/s\n" , pd->write_speed); |
477 | seq_printf(m, fmt: "\tstart offset:\t\t%lu\n" , pd->offset); |
478 | seq_printf(m, fmt: "\tmode page offset:\t%u\n" , pd->mode_offset); |
479 | |
480 | seq_printf(m, fmt: "\nQueue state:\n" ); |
481 | seq_printf(m, fmt: "\tbios queued:\t\t%d\n" , pd->bio_queue_size); |
482 | seq_printf(m, fmt: "\tbios pending:\t\t%d\n" , atomic_read(v: &pd->cdrw.pending_bios)); |
483 | seq_printf(m, fmt: "\tcurrent sector:\t\t0x%llx\n" , pd->current_sector); |
484 | |
485 | pkt_count_states(pd, states); |
486 | seq_printf(m, fmt: "\tstate:\t\t\ti:%d ow:%d rw:%d ww:%d rec:%d fin:%d\n" , |
487 | states[0], states[1], states[2], states[3], states[4], states[5]); |
488 | |
489 | seq_printf(m, fmt: "\twrite congestion marks:\toff=%d on=%d\n" , |
490 | pd->write_congestion_off, |
491 | pd->write_congestion_on); |
492 | return 0; |
493 | } |
494 | DEFINE_SHOW_ATTRIBUTE(pkt_seq); |
495 | |
496 | static void pkt_debugfs_dev_new(struct pktcdvd_device *pd) |
497 | { |
498 | if (!pkt_debugfs_root) |
499 | return; |
500 | pd->dfs_d_root = debugfs_create_dir(name: pd->disk->disk_name, parent: pkt_debugfs_root); |
501 | if (!pd->dfs_d_root) |
502 | return; |
503 | |
504 | pd->dfs_f_info = debugfs_create_file(name: "info" , mode: 0444, parent: pd->dfs_d_root, |
505 | data: pd, fops: &pkt_seq_fops); |
506 | } |
507 | |
508 | static void pkt_debugfs_dev_remove(struct pktcdvd_device *pd) |
509 | { |
510 | if (!pkt_debugfs_root) |
511 | return; |
512 | debugfs_remove(dentry: pd->dfs_f_info); |
513 | debugfs_remove(dentry: pd->dfs_d_root); |
514 | pd->dfs_f_info = NULL; |
515 | pd->dfs_d_root = NULL; |
516 | } |
517 | |
518 | static void pkt_debugfs_init(void) |
519 | { |
520 | pkt_debugfs_root = debugfs_create_dir(DRIVER_NAME, NULL); |
521 | } |
522 | |
523 | static void pkt_debugfs_cleanup(void) |
524 | { |
525 | debugfs_remove(dentry: pkt_debugfs_root); |
526 | pkt_debugfs_root = NULL; |
527 | } |
528 | |
529 | /* ----------------------------------------------------------*/ |
530 | |
531 | |
532 | static void pkt_bio_finished(struct pktcdvd_device *pd) |
533 | { |
534 | struct device *ddev = disk_to_dev(pd->disk); |
535 | |
536 | BUG_ON(atomic_read(&pd->cdrw.pending_bios) <= 0); |
537 | if (atomic_dec_and_test(v: &pd->cdrw.pending_bios)) { |
538 | dev_dbg(ddev, "queue empty\n" ); |
539 | atomic_set(v: &pd->iosched.attention, i: 1); |
540 | wake_up(&pd->wqueue); |
541 | } |
542 | } |
543 | |
544 | /* |
545 | * Allocate a packet_data struct |
546 | */ |
547 | static struct packet_data *pkt_alloc_packet_data(int frames) |
548 | { |
549 | int i; |
550 | struct packet_data *pkt; |
551 | |
552 | pkt = kzalloc(size: sizeof(struct packet_data), GFP_KERNEL); |
553 | if (!pkt) |
554 | goto no_pkt; |
555 | |
556 | pkt->frames = frames; |
557 | pkt->w_bio = bio_kmalloc(nr_vecs: frames, GFP_KERNEL); |
558 | if (!pkt->w_bio) |
559 | goto no_bio; |
560 | |
561 | for (i = 0; i < frames / FRAMES_PER_PAGE; i++) { |
562 | pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); |
563 | if (!pkt->pages[i]) |
564 | goto no_page; |
565 | } |
566 | |
567 | spin_lock_init(&pkt->lock); |
568 | bio_list_init(bl: &pkt->orig_bios); |
569 | |
570 | for (i = 0; i < frames; i++) { |
571 | pkt->r_bios[i] = bio_kmalloc(nr_vecs: 1, GFP_KERNEL); |
572 | if (!pkt->r_bios[i]) |
573 | goto no_rd_bio; |
574 | } |
575 | |
576 | return pkt; |
577 | |
578 | no_rd_bio: |
579 | for (i = 0; i < frames; i++) |
580 | kfree(objp: pkt->r_bios[i]); |
581 | no_page: |
582 | for (i = 0; i < frames / FRAMES_PER_PAGE; i++) |
583 | if (pkt->pages[i]) |
584 | __free_page(pkt->pages[i]); |
585 | kfree(objp: pkt->w_bio); |
586 | no_bio: |
587 | kfree(objp: pkt); |
588 | no_pkt: |
589 | return NULL; |
590 | } |
591 | |
592 | /* |
593 | * Free a packet_data struct |
594 | */ |
595 | static void pkt_free_packet_data(struct packet_data *pkt) |
596 | { |
597 | int i; |
598 | |
599 | for (i = 0; i < pkt->frames; i++) |
600 | kfree(objp: pkt->r_bios[i]); |
601 | for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++) |
602 | __free_page(pkt->pages[i]); |
603 | kfree(objp: pkt->w_bio); |
604 | kfree(objp: pkt); |
605 | } |
606 | |
607 | static void pkt_shrink_pktlist(struct pktcdvd_device *pd) |
608 | { |
609 | struct packet_data *pkt, *next; |
610 | |
611 | BUG_ON(!list_empty(&pd->cdrw.pkt_active_list)); |
612 | |
613 | list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) { |
614 | pkt_free_packet_data(pkt); |
615 | } |
616 | INIT_LIST_HEAD(list: &pd->cdrw.pkt_free_list); |
617 | } |
618 | |
619 | static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets) |
620 | { |
621 | struct packet_data *pkt; |
622 | |
623 | BUG_ON(!list_empty(&pd->cdrw.pkt_free_list)); |
624 | |
625 | while (nr_packets > 0) { |
626 | pkt = pkt_alloc_packet_data(frames: pd->settings.size >> 2); |
627 | if (!pkt) { |
628 | pkt_shrink_pktlist(pd); |
629 | return 0; |
630 | } |
631 | pkt->id = nr_packets; |
632 | pkt->pd = pd; |
633 | list_add(new: &pkt->list, head: &pd->cdrw.pkt_free_list); |
634 | nr_packets--; |
635 | } |
636 | return 1; |
637 | } |
638 | |
639 | static inline struct pkt_rb_node *pkt_rbtree_next(struct pkt_rb_node *node) |
640 | { |
641 | struct rb_node *n = rb_next(&node->rb_node); |
642 | if (!n) |
643 | return NULL; |
644 | return rb_entry(n, struct pkt_rb_node, rb_node); |
645 | } |
646 | |
647 | static void pkt_rbtree_erase(struct pktcdvd_device *pd, struct pkt_rb_node *node) |
648 | { |
649 | rb_erase(&node->rb_node, &pd->bio_queue); |
650 | mempool_free(element: node, pool: &pd->rb_pool); |
651 | pd->bio_queue_size--; |
652 | BUG_ON(pd->bio_queue_size < 0); |
653 | } |
654 | |
655 | /* |
656 | * Find the first node in the pd->bio_queue rb tree with a starting sector >= s. |
657 | */ |
658 | static struct pkt_rb_node *pkt_rbtree_find(struct pktcdvd_device *pd, sector_t s) |
659 | { |
660 | struct rb_node *n = pd->bio_queue.rb_node; |
661 | struct rb_node *next; |
662 | struct pkt_rb_node *tmp; |
663 | |
664 | if (!n) { |
665 | BUG_ON(pd->bio_queue_size > 0); |
666 | return NULL; |
667 | } |
668 | |
669 | for (;;) { |
670 | tmp = rb_entry(n, struct pkt_rb_node, rb_node); |
671 | if (s <= tmp->bio->bi_iter.bi_sector) |
672 | next = n->rb_left; |
673 | else |
674 | next = n->rb_right; |
675 | if (!next) |
676 | break; |
677 | n = next; |
678 | } |
679 | |
680 | if (s > tmp->bio->bi_iter.bi_sector) { |
681 | tmp = pkt_rbtree_next(node: tmp); |
682 | if (!tmp) |
683 | return NULL; |
684 | } |
685 | BUG_ON(s > tmp->bio->bi_iter.bi_sector); |
686 | return tmp; |
687 | } |
688 | |
689 | /* |
690 | * Insert a node into the pd->bio_queue rb tree. |
691 | */ |
692 | static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *node) |
693 | { |
694 | struct rb_node **p = &pd->bio_queue.rb_node; |
695 | struct rb_node *parent = NULL; |
696 | sector_t s = node->bio->bi_iter.bi_sector; |
697 | struct pkt_rb_node *tmp; |
698 | |
699 | while (*p) { |
700 | parent = *p; |
701 | tmp = rb_entry(parent, struct pkt_rb_node, rb_node); |
702 | if (s < tmp->bio->bi_iter.bi_sector) |
703 | p = &(*p)->rb_left; |
704 | else |
705 | p = &(*p)->rb_right; |
706 | } |
707 | rb_link_node(node: &node->rb_node, parent, rb_link: p); |
708 | rb_insert_color(&node->rb_node, &pd->bio_queue); |
709 | pd->bio_queue_size++; |
710 | } |
711 | |
712 | /* |
713 | * Send a packet_command to the underlying block device and |
714 | * wait for completion. |
715 | */ |
716 | static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc) |
717 | { |
718 | struct request_queue *q = bdev_get_queue(bdev: pd->bdev_handle->bdev); |
719 | struct scsi_cmnd *scmd; |
720 | struct request *rq; |
721 | int ret = 0; |
722 | |
723 | rq = scsi_alloc_request(q, opf: (cgc->data_direction == CGC_DATA_WRITE) ? |
724 | REQ_OP_DRV_OUT : REQ_OP_DRV_IN, flags: 0); |
725 | if (IS_ERR(ptr: rq)) |
726 | return PTR_ERR(ptr: rq); |
727 | scmd = blk_mq_rq_to_pdu(rq); |
728 | |
729 | if (cgc->buflen) { |
730 | ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, |
731 | GFP_NOIO); |
732 | if (ret) |
733 | goto out; |
734 | } |
735 | |
736 | scmd->cmd_len = COMMAND_SIZE(cgc->cmd[0]); |
737 | memcpy(scmd->cmnd, cgc->cmd, CDROM_PACKET_SIZE); |
738 | |
739 | rq->timeout = 60*HZ; |
740 | if (cgc->quiet) |
741 | rq->rq_flags |= RQF_QUIET; |
742 | |
743 | blk_execute_rq(rq, at_head: false); |
744 | if (scmd->result) |
745 | ret = -EIO; |
746 | out: |
747 | blk_mq_free_request(rq); |
748 | return ret; |
749 | } |
750 | |
751 | static const char *sense_key_string(__u8 index) |
752 | { |
753 | static const char * const info[] = { |
754 | "No sense" , "Recovered error" , "Not ready" , |
755 | "Medium error" , "Hardware error" , "Illegal request" , |
756 | "Unit attention" , "Data protect" , "Blank check" , |
757 | }; |
758 | |
759 | return index < ARRAY_SIZE(info) ? info[index] : "INVALID" ; |
760 | } |
761 | |
762 | /* |
763 | * A generic sense dump / resolve mechanism should be implemented across |
764 | * all ATAPI + SCSI devices. |
765 | */ |
766 | static void pkt_dump_sense(struct pktcdvd_device *pd, |
767 | struct packet_command *cgc) |
768 | { |
769 | struct device *ddev = disk_to_dev(pd->disk); |
770 | struct scsi_sense_hdr *sshdr = cgc->sshdr; |
771 | |
772 | if (sshdr) |
773 | dev_err(ddev, "%*ph - sense %02x.%02x.%02x (%s)\n" , |
774 | CDROM_PACKET_SIZE, cgc->cmd, |
775 | sshdr->sense_key, sshdr->asc, sshdr->ascq, |
776 | sense_key_string(sshdr->sense_key)); |
777 | else |
778 | dev_err(ddev, "%*ph - no sense\n" , CDROM_PACKET_SIZE, cgc->cmd); |
779 | } |
780 | |
781 | /* |
782 | * flush the drive cache to media |
783 | */ |
784 | static int pkt_flush_cache(struct pktcdvd_device *pd) |
785 | { |
786 | struct packet_command cgc; |
787 | |
788 | init_cdrom_command(cgc: &cgc, NULL, len: 0, CGC_DATA_NONE); |
789 | cgc.cmd[0] = GPCMD_FLUSH_CACHE; |
790 | cgc.quiet = 1; |
791 | |
792 | /* |
793 | * the IMMED bit -- we default to not setting it, although that |
794 | * would allow a much faster close, this is safer |
795 | */ |
796 | #if 0 |
797 | cgc.cmd[1] = 1 << 1; |
798 | #endif |
799 | return pkt_generic_packet(pd, cgc: &cgc); |
800 | } |
801 | |
802 | /* |
803 | * speed is given as the normal factor, e.g. 4 for 4x |
804 | */ |
805 | static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd, |
806 | unsigned write_speed, unsigned read_speed) |
807 | { |
808 | struct packet_command cgc; |
809 | struct scsi_sense_hdr sshdr; |
810 | int ret; |
811 | |
812 | init_cdrom_command(cgc: &cgc, NULL, len: 0, CGC_DATA_NONE); |
813 | cgc.sshdr = &sshdr; |
814 | cgc.cmd[0] = GPCMD_SET_SPEED; |
815 | put_unaligned_be16(val: read_speed, p: &cgc.cmd[2]); |
816 | put_unaligned_be16(val: write_speed, p: &cgc.cmd[4]); |
817 | |
818 | ret = pkt_generic_packet(pd, cgc: &cgc); |
819 | if (ret) |
820 | pkt_dump_sense(pd, cgc: &cgc); |
821 | |
822 | return ret; |
823 | } |
824 | |
825 | /* |
826 | * Queue a bio for processing by the low-level CD device. Must be called |
827 | * from process context. |
828 | */ |
829 | static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio) |
830 | { |
831 | spin_lock(lock: &pd->iosched.lock); |
832 | if (bio_data_dir(bio) == READ) |
833 | bio_list_add(bl: &pd->iosched.read_queue, bio); |
834 | else |
835 | bio_list_add(bl: &pd->iosched.write_queue, bio); |
836 | spin_unlock(lock: &pd->iosched.lock); |
837 | |
838 | atomic_set(v: &pd->iosched.attention, i: 1); |
839 | wake_up(&pd->wqueue); |
840 | } |
841 | |
842 | /* |
843 | * Process the queued read/write requests. This function handles special |
844 | * requirements for CDRW drives: |
845 | * - A cache flush command must be inserted before a read request if the |
846 | * previous request was a write. |
847 | * - Switching between reading and writing is slow, so don't do it more often |
848 | * than necessary. |
849 | * - Optimize for throughput at the expense of latency. This means that streaming |
850 | * writes will never be interrupted by a read, but if the drive has to seek |
851 | * before the next write, switch to reading instead if there are any pending |
852 | * read requests. |
853 | * - Set the read speed according to current usage pattern. When only reading |
854 | * from the device, it's best to use the highest possible read speed, but |
855 | * when switching often between reading and writing, it's better to have the |
856 | * same read and write speeds. |
857 | */ |
858 | static void pkt_iosched_process_queue(struct pktcdvd_device *pd) |
859 | { |
860 | struct device *ddev = disk_to_dev(pd->disk); |
861 | |
862 | if (atomic_read(v: &pd->iosched.attention) == 0) |
863 | return; |
864 | atomic_set(v: &pd->iosched.attention, i: 0); |
865 | |
866 | for (;;) { |
867 | struct bio *bio; |
868 | int reads_queued, writes_queued; |
869 | |
870 | spin_lock(lock: &pd->iosched.lock); |
871 | reads_queued = !bio_list_empty(bl: &pd->iosched.read_queue); |
872 | writes_queued = !bio_list_empty(bl: &pd->iosched.write_queue); |
873 | spin_unlock(lock: &pd->iosched.lock); |
874 | |
875 | if (!reads_queued && !writes_queued) |
876 | break; |
877 | |
878 | if (pd->iosched.writing) { |
879 | int need_write_seek = 1; |
880 | spin_lock(lock: &pd->iosched.lock); |
881 | bio = bio_list_peek(bl: &pd->iosched.write_queue); |
882 | spin_unlock(lock: &pd->iosched.lock); |
883 | if (bio && (bio->bi_iter.bi_sector == |
884 | pd->iosched.last_write)) |
885 | need_write_seek = 0; |
886 | if (need_write_seek && reads_queued) { |
887 | if (atomic_read(v: &pd->cdrw.pending_bios) > 0) { |
888 | dev_dbg(ddev, "write, waiting\n" ); |
889 | break; |
890 | } |
891 | pkt_flush_cache(pd); |
892 | pd->iosched.writing = 0; |
893 | } |
894 | } else { |
895 | if (!reads_queued && writes_queued) { |
896 | if (atomic_read(v: &pd->cdrw.pending_bios) > 0) { |
897 | dev_dbg(ddev, "read, waiting\n" ); |
898 | break; |
899 | } |
900 | pd->iosched.writing = 1; |
901 | } |
902 | } |
903 | |
904 | spin_lock(lock: &pd->iosched.lock); |
905 | if (pd->iosched.writing) |
906 | bio = bio_list_pop(bl: &pd->iosched.write_queue); |
907 | else |
908 | bio = bio_list_pop(bl: &pd->iosched.read_queue); |
909 | spin_unlock(lock: &pd->iosched.lock); |
910 | |
911 | if (!bio) |
912 | continue; |
913 | |
914 | if (bio_data_dir(bio) == READ) |
915 | pd->iosched.successive_reads += |
916 | bio->bi_iter.bi_size >> 10; |
917 | else { |
918 | pd->iosched.successive_reads = 0; |
919 | pd->iosched.last_write = bio_end_sector(bio); |
920 | } |
921 | if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) { |
922 | if (pd->read_speed == pd->write_speed) { |
923 | pd->read_speed = MAX_SPEED; |
924 | pkt_set_speed(pd, write_speed: pd->write_speed, read_speed: pd->read_speed); |
925 | } |
926 | } else { |
927 | if (pd->read_speed != pd->write_speed) { |
928 | pd->read_speed = pd->write_speed; |
929 | pkt_set_speed(pd, write_speed: pd->write_speed, read_speed: pd->read_speed); |
930 | } |
931 | } |
932 | |
933 | atomic_inc(v: &pd->cdrw.pending_bios); |
934 | submit_bio_noacct(bio); |
935 | } |
936 | } |
937 | |
938 | /* |
939 | * Special care is needed if the underlying block device has a small |
940 | * max_phys_segments value. |
941 | */ |
942 | static int pkt_set_segment_merging(struct pktcdvd_device *pd, struct request_queue *q) |
943 | { |
944 | struct device *ddev = disk_to_dev(pd->disk); |
945 | |
946 | if ((pd->settings.size << 9) / CD_FRAMESIZE <= queue_max_segments(q)) { |
947 | /* |
948 | * The cdrom device can handle one segment/frame |
949 | */ |
950 | clear_bit(PACKET_MERGE_SEGS, addr: &pd->flags); |
951 | return 0; |
952 | } |
953 | |
954 | if ((pd->settings.size << 9) / PAGE_SIZE <= queue_max_segments(q)) { |
955 | /* |
956 | * We can handle this case at the expense of some extra memory |
957 | * copies during write operations |
958 | */ |
959 | set_bit(PACKET_MERGE_SEGS, addr: &pd->flags); |
960 | return 0; |
961 | } |
962 | |
963 | dev_err(ddev, "cdrom max_phys_segments too small\n" ); |
964 | return -EIO; |
965 | } |
966 | |
967 | static void pkt_end_io_read(struct bio *bio) |
968 | { |
969 | struct packet_data *pkt = bio->bi_private; |
970 | struct pktcdvd_device *pd = pkt->pd; |
971 | BUG_ON(!pd); |
972 | |
973 | dev_dbg(disk_to_dev(pd->disk), "bio=%p sec0=%llx sec=%llx err=%d\n" , |
974 | bio, pkt->sector, bio->bi_iter.bi_sector, bio->bi_status); |
975 | |
976 | if (bio->bi_status) |
977 | atomic_inc(v: &pkt->io_errors); |
978 | bio_uninit(bio); |
979 | if (atomic_dec_and_test(v: &pkt->io_wait)) { |
980 | atomic_inc(v: &pkt->run_sm); |
981 | wake_up(&pd->wqueue); |
982 | } |
983 | pkt_bio_finished(pd); |
984 | } |
985 | |
986 | static void pkt_end_io_packet_write(struct bio *bio) |
987 | { |
988 | struct packet_data *pkt = bio->bi_private; |
989 | struct pktcdvd_device *pd = pkt->pd; |
990 | BUG_ON(!pd); |
991 | |
992 | dev_dbg(disk_to_dev(pd->disk), "id=%d, err=%d\n" , pkt->id, bio->bi_status); |
993 | |
994 | pd->stats.pkt_ended++; |
995 | |
996 | bio_uninit(bio); |
997 | pkt_bio_finished(pd); |
998 | atomic_dec(v: &pkt->io_wait); |
999 | atomic_inc(v: &pkt->run_sm); |
1000 | wake_up(&pd->wqueue); |
1001 | } |
1002 | |
1003 | /* |
1004 | * Schedule reads for the holes in a packet |
1005 | */ |
1006 | static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) |
1007 | { |
1008 | struct device *ddev = disk_to_dev(pd->disk); |
1009 | int frames_read = 0; |
1010 | struct bio *bio; |
1011 | int f; |
1012 | char written[PACKET_MAX_SIZE]; |
1013 | |
1014 | BUG_ON(bio_list_empty(&pkt->orig_bios)); |
1015 | |
1016 | atomic_set(v: &pkt->io_wait, i: 0); |
1017 | atomic_set(v: &pkt->io_errors, i: 0); |
1018 | |
1019 | /* |
1020 | * Figure out which frames we need to read before we can write. |
1021 | */ |
1022 | memset(written, 0, sizeof(written)); |
1023 | spin_lock(lock: &pkt->lock); |
1024 | bio_list_for_each(bio, &pkt->orig_bios) { |
1025 | int first_frame = (bio->bi_iter.bi_sector - pkt->sector) / |
1026 | (CD_FRAMESIZE >> 9); |
1027 | int num_frames = bio->bi_iter.bi_size / CD_FRAMESIZE; |
1028 | pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9); |
1029 | BUG_ON(first_frame < 0); |
1030 | BUG_ON(first_frame + num_frames > pkt->frames); |
1031 | for (f = first_frame; f < first_frame + num_frames; f++) |
1032 | written[f] = 1; |
1033 | } |
1034 | spin_unlock(lock: &pkt->lock); |
1035 | |
1036 | if (pkt->cache_valid) { |
1037 | dev_dbg(ddev, "zone %llx cached\n" , pkt->sector); |
1038 | goto out_account; |
1039 | } |
1040 | |
1041 | /* |
1042 | * Schedule reads for missing parts of the packet. |
1043 | */ |
1044 | for (f = 0; f < pkt->frames; f++) { |
1045 | int p, offset; |
1046 | |
1047 | if (written[f]) |
1048 | continue; |
1049 | |
1050 | bio = pkt->r_bios[f]; |
1051 | bio_init(bio, bdev: pd->bdev_handle->bdev, table: bio->bi_inline_vecs, max_vecs: 1, |
1052 | opf: REQ_OP_READ); |
1053 | bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9); |
1054 | bio->bi_end_io = pkt_end_io_read; |
1055 | bio->bi_private = pkt; |
1056 | |
1057 | p = (f * CD_FRAMESIZE) / PAGE_SIZE; |
1058 | offset = (f * CD_FRAMESIZE) % PAGE_SIZE; |
1059 | dev_dbg(ddev, "Adding frame %d, page:%p offs:%d\n" , f, |
1060 | pkt->pages[p], offset); |
1061 | if (!bio_add_page(bio, page: pkt->pages[p], CD_FRAMESIZE, off: offset)) |
1062 | BUG(); |
1063 | |
1064 | atomic_inc(v: &pkt->io_wait); |
1065 | pkt_queue_bio(pd, bio); |
1066 | frames_read++; |
1067 | } |
1068 | |
1069 | out_account: |
1070 | dev_dbg(ddev, "need %d frames for zone %llx\n" , frames_read, pkt->sector); |
1071 | pd->stats.pkt_started++; |
1072 | pd->stats.secs_rg += frames_read * (CD_FRAMESIZE >> 9); |
1073 | } |
1074 | |
1075 | /* |
1076 | * Find a packet matching zone, or the least recently used packet if |
1077 | * there is no match. |
1078 | */ |
1079 | static struct packet_data *pkt_get_packet_data(struct pktcdvd_device *pd, int zone) |
1080 | { |
1081 | struct packet_data *pkt; |
1082 | |
1083 | list_for_each_entry(pkt, &pd->cdrw.pkt_free_list, list) { |
1084 | if (pkt->sector == zone || pkt->list.next == &pd->cdrw.pkt_free_list) { |
1085 | list_del_init(entry: &pkt->list); |
1086 | if (pkt->sector != zone) |
1087 | pkt->cache_valid = 0; |
1088 | return pkt; |
1089 | } |
1090 | } |
1091 | BUG(); |
1092 | return NULL; |
1093 | } |
1094 | |
1095 | static void pkt_put_packet_data(struct pktcdvd_device *pd, struct packet_data *pkt) |
1096 | { |
1097 | if (pkt->cache_valid) { |
1098 | list_add(new: &pkt->list, head: &pd->cdrw.pkt_free_list); |
1099 | } else { |
1100 | list_add_tail(new: &pkt->list, head: &pd->cdrw.pkt_free_list); |
1101 | } |
1102 | } |
1103 | |
1104 | static inline void pkt_set_state(struct device *ddev, struct packet_data *pkt, |
1105 | enum packet_data_state state) |
1106 | { |
1107 | static const char *state_name[] = { |
1108 | "IDLE" , "WAITING" , "READ_WAIT" , "WRITE_WAIT" , "RECOVERY" , "FINISHED" |
1109 | }; |
1110 | enum packet_data_state old_state = pkt->state; |
1111 | |
1112 | dev_dbg(ddev, "pkt %2d : s=%6llx %s -> %s\n" , |
1113 | pkt->id, pkt->sector, state_name[old_state], state_name[state]); |
1114 | |
1115 | pkt->state = state; |
1116 | } |
1117 | |
1118 | /* |
1119 | * Scan the work queue to see if we can start a new packet. |
1120 | * returns non-zero if any work was done. |
1121 | */ |
1122 | static int pkt_handle_queue(struct pktcdvd_device *pd) |
1123 | { |
1124 | struct device *ddev = disk_to_dev(pd->disk); |
1125 | struct packet_data *pkt, *p; |
1126 | struct bio *bio = NULL; |
1127 | sector_t zone = 0; /* Suppress gcc warning */ |
1128 | struct pkt_rb_node *node, *first_node; |
1129 | struct rb_node *n; |
1130 | |
1131 | atomic_set(v: &pd->scan_queue, i: 0); |
1132 | |
1133 | if (list_empty(head: &pd->cdrw.pkt_free_list)) { |
1134 | dev_dbg(ddev, "no pkt\n" ); |
1135 | return 0; |
1136 | } |
1137 | |
1138 | /* |
1139 | * Try to find a zone we are not already working on. |
1140 | */ |
1141 | spin_lock(lock: &pd->lock); |
1142 | first_node = pkt_rbtree_find(pd, s: pd->current_sector); |
1143 | if (!first_node) { |
1144 | n = rb_first(&pd->bio_queue); |
1145 | if (n) |
1146 | first_node = rb_entry(n, struct pkt_rb_node, rb_node); |
1147 | } |
1148 | node = first_node; |
1149 | while (node) { |
1150 | bio = node->bio; |
1151 | zone = get_zone(sector: bio->bi_iter.bi_sector, pd); |
1152 | list_for_each_entry(p, &pd->cdrw.pkt_active_list, list) { |
1153 | if (p->sector == zone) { |
1154 | bio = NULL; |
1155 | goto try_next_bio; |
1156 | } |
1157 | } |
1158 | break; |
1159 | try_next_bio: |
1160 | node = pkt_rbtree_next(node); |
1161 | if (!node) { |
1162 | n = rb_first(&pd->bio_queue); |
1163 | if (n) |
1164 | node = rb_entry(n, struct pkt_rb_node, rb_node); |
1165 | } |
1166 | if (node == first_node) |
1167 | node = NULL; |
1168 | } |
1169 | spin_unlock(lock: &pd->lock); |
1170 | if (!bio) { |
1171 | dev_dbg(ddev, "no bio\n" ); |
1172 | return 0; |
1173 | } |
1174 | |
1175 | pkt = pkt_get_packet_data(pd, zone); |
1176 | |
1177 | pd->current_sector = zone + pd->settings.size; |
1178 | pkt->sector = zone; |
1179 | BUG_ON(pkt->frames != pd->settings.size >> 2); |
1180 | pkt->write_size = 0; |
1181 | |
1182 | /* |
1183 | * Scan work queue for bios in the same zone and link them |
1184 | * to this packet. |
1185 | */ |
1186 | spin_lock(lock: &pd->lock); |
1187 | dev_dbg(ddev, "looking for zone %llx\n" , zone); |
1188 | while ((node = pkt_rbtree_find(pd, s: zone)) != NULL) { |
1189 | sector_t tmp = get_zone(sector: node->bio->bi_iter.bi_sector, pd); |
1190 | |
1191 | bio = node->bio; |
1192 | dev_dbg(ddev, "found zone=%llx\n" , tmp); |
1193 | if (tmp != zone) |
1194 | break; |
1195 | pkt_rbtree_erase(pd, node); |
1196 | spin_lock(lock: &pkt->lock); |
1197 | bio_list_add(bl: &pkt->orig_bios, bio); |
1198 | pkt->write_size += bio->bi_iter.bi_size / CD_FRAMESIZE; |
1199 | spin_unlock(lock: &pkt->lock); |
1200 | } |
1201 | /* check write congestion marks, and if bio_queue_size is |
1202 | * below, wake up any waiters |
1203 | */ |
1204 | if (pd->congested && |
1205 | pd->bio_queue_size <= pd->write_congestion_off) { |
1206 | pd->congested = false; |
1207 | wake_up_var(var: &pd->congested); |
1208 | } |
1209 | spin_unlock(lock: &pd->lock); |
1210 | |
1211 | pkt->sleep_time = max(PACKET_WAIT_TIME, 1); |
1212 | pkt_set_state(ddev, pkt, state: PACKET_WAITING_STATE); |
1213 | atomic_set(v: &pkt->run_sm, i: 1); |
1214 | |
1215 | spin_lock(lock: &pd->cdrw.active_list_lock); |
1216 | list_add(new: &pkt->list, head: &pd->cdrw.pkt_active_list); |
1217 | spin_unlock(lock: &pd->cdrw.active_list_lock); |
1218 | |
1219 | return 1; |
1220 | } |
1221 | |
1222 | /** |
1223 | * bio_list_copy_data - copy contents of data buffers from one chain of bios to |
1224 | * another |
1225 | * @src: source bio list |
1226 | * @dst: destination bio list |
1227 | * |
1228 | * Stops when it reaches the end of either the @src list or @dst list - that is, |
1229 | * copies min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of |
1230 | * bios). |
1231 | */ |
1232 | static void bio_list_copy_data(struct bio *dst, struct bio *src) |
1233 | { |
1234 | struct bvec_iter src_iter = src->bi_iter; |
1235 | struct bvec_iter dst_iter = dst->bi_iter; |
1236 | |
1237 | while (1) { |
1238 | if (!src_iter.bi_size) { |
1239 | src = src->bi_next; |
1240 | if (!src) |
1241 | break; |
1242 | |
1243 | src_iter = src->bi_iter; |
1244 | } |
1245 | |
1246 | if (!dst_iter.bi_size) { |
1247 | dst = dst->bi_next; |
1248 | if (!dst) |
1249 | break; |
1250 | |
1251 | dst_iter = dst->bi_iter; |
1252 | } |
1253 | |
1254 | bio_copy_data_iter(dst, dst_iter: &dst_iter, src, src_iter: &src_iter); |
1255 | } |
1256 | } |
1257 | |
1258 | /* |
1259 | * Assemble a bio to write one packet and queue the bio for processing |
1260 | * by the underlying block device. |
1261 | */ |
1262 | static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) |
1263 | { |
1264 | struct device *ddev = disk_to_dev(pd->disk); |
1265 | int f; |
1266 | |
1267 | bio_init(bio: pkt->w_bio, bdev: pd->bdev_handle->bdev, table: pkt->w_bio->bi_inline_vecs, |
1268 | max_vecs: pkt->frames, opf: REQ_OP_WRITE); |
1269 | pkt->w_bio->bi_iter.bi_sector = pkt->sector; |
1270 | pkt->w_bio->bi_end_io = pkt_end_io_packet_write; |
1271 | pkt->w_bio->bi_private = pkt; |
1272 | |
1273 | /* XXX: locking? */ |
1274 | for (f = 0; f < pkt->frames; f++) { |
1275 | struct page *page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; |
1276 | unsigned offset = (f * CD_FRAMESIZE) % PAGE_SIZE; |
1277 | |
1278 | if (!bio_add_page(bio: pkt->w_bio, page, CD_FRAMESIZE, off: offset)) |
1279 | BUG(); |
1280 | } |
1281 | dev_dbg(ddev, "vcnt=%d\n" , pkt->w_bio->bi_vcnt); |
1282 | |
1283 | /* |
1284 | * Fill-in bvec with data from orig_bios. |
1285 | */ |
1286 | spin_lock(lock: &pkt->lock); |
1287 | bio_list_copy_data(dst: pkt->w_bio, src: pkt->orig_bios.head); |
1288 | |
1289 | pkt_set_state(ddev, pkt, state: PACKET_WRITE_WAIT_STATE); |
1290 | spin_unlock(lock: &pkt->lock); |
1291 | |
1292 | dev_dbg(ddev, "Writing %d frames for zone %llx\n" , pkt->write_size, pkt->sector); |
1293 | |
1294 | if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) |
1295 | pkt->cache_valid = 1; |
1296 | else |
1297 | pkt->cache_valid = 0; |
1298 | |
1299 | /* Start the write request */ |
1300 | atomic_set(v: &pkt->io_wait, i: 1); |
1301 | pkt_queue_bio(pd, bio: pkt->w_bio); |
1302 | } |
1303 | |
1304 | static void pkt_finish_packet(struct packet_data *pkt, blk_status_t status) |
1305 | { |
1306 | struct bio *bio; |
1307 | |
1308 | if (status) |
1309 | pkt->cache_valid = 0; |
1310 | |
1311 | /* Finish all bios corresponding to this packet */ |
1312 | while ((bio = bio_list_pop(bl: &pkt->orig_bios))) { |
1313 | bio->bi_status = status; |
1314 | bio_endio(bio); |
1315 | } |
1316 | } |
1317 | |
1318 | static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data *pkt) |
1319 | { |
1320 | struct device *ddev = disk_to_dev(pd->disk); |
1321 | |
1322 | dev_dbg(ddev, "pkt %d\n" , pkt->id); |
1323 | |
1324 | for (;;) { |
1325 | switch (pkt->state) { |
1326 | case PACKET_WAITING_STATE: |
1327 | if ((pkt->write_size < pkt->frames) && (pkt->sleep_time > 0)) |
1328 | return; |
1329 | |
1330 | pkt->sleep_time = 0; |
1331 | pkt_gather_data(pd, pkt); |
1332 | pkt_set_state(ddev, pkt, state: PACKET_READ_WAIT_STATE); |
1333 | break; |
1334 | |
1335 | case PACKET_READ_WAIT_STATE: |
1336 | if (atomic_read(v: &pkt->io_wait) > 0) |
1337 | return; |
1338 | |
1339 | if (atomic_read(v: &pkt->io_errors) > 0) { |
1340 | pkt_set_state(ddev, pkt, state: PACKET_RECOVERY_STATE); |
1341 | } else { |
1342 | pkt_start_write(pd, pkt); |
1343 | } |
1344 | break; |
1345 | |
1346 | case PACKET_WRITE_WAIT_STATE: |
1347 | if (atomic_read(v: &pkt->io_wait) > 0) |
1348 | return; |
1349 | |
1350 | if (!pkt->w_bio->bi_status) { |
1351 | pkt_set_state(ddev, pkt, state: PACKET_FINISHED_STATE); |
1352 | } else { |
1353 | pkt_set_state(ddev, pkt, state: PACKET_RECOVERY_STATE); |
1354 | } |
1355 | break; |
1356 | |
1357 | case PACKET_RECOVERY_STATE: |
1358 | dev_dbg(ddev, "No recovery possible\n" ); |
1359 | pkt_set_state(ddev, pkt, state: PACKET_FINISHED_STATE); |
1360 | break; |
1361 | |
1362 | case PACKET_FINISHED_STATE: |
1363 | pkt_finish_packet(pkt, status: pkt->w_bio->bi_status); |
1364 | return; |
1365 | |
1366 | default: |
1367 | BUG(); |
1368 | break; |
1369 | } |
1370 | } |
1371 | } |
1372 | |
1373 | static void pkt_handle_packets(struct pktcdvd_device *pd) |
1374 | { |
1375 | struct device *ddev = disk_to_dev(pd->disk); |
1376 | struct packet_data *pkt, *next; |
1377 | |
1378 | /* |
1379 | * Run state machine for active packets |
1380 | */ |
1381 | list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { |
1382 | if (atomic_read(v: &pkt->run_sm) > 0) { |
1383 | atomic_set(v: &pkt->run_sm, i: 0); |
1384 | pkt_run_state_machine(pd, pkt); |
1385 | } |
1386 | } |
1387 | |
1388 | /* |
1389 | * Move no longer active packets to the free list |
1390 | */ |
1391 | spin_lock(lock: &pd->cdrw.active_list_lock); |
1392 | list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_active_list, list) { |
1393 | if (pkt->state == PACKET_FINISHED_STATE) { |
1394 | list_del(entry: &pkt->list); |
1395 | pkt_put_packet_data(pd, pkt); |
1396 | pkt_set_state(ddev, pkt, state: PACKET_IDLE_STATE); |
1397 | atomic_set(v: &pd->scan_queue, i: 1); |
1398 | } |
1399 | } |
1400 | spin_unlock(lock: &pd->cdrw.active_list_lock); |
1401 | } |
1402 | |
1403 | /* |
1404 | * kcdrwd is woken up when writes have been queued for one of our |
1405 | * registered devices |
1406 | */ |
1407 | static int kcdrwd(void *foobar) |
1408 | { |
1409 | struct pktcdvd_device *pd = foobar; |
1410 | struct device *ddev = disk_to_dev(pd->disk); |
1411 | struct packet_data *pkt; |
1412 | int states[PACKET_NUM_STATES]; |
1413 | long min_sleep_time, residue; |
1414 | |
1415 | set_user_nice(current, MIN_NICE); |
1416 | set_freezable(); |
1417 | |
1418 | for (;;) { |
1419 | DECLARE_WAITQUEUE(wait, current); |
1420 | |
1421 | /* |
1422 | * Wait until there is something to do |
1423 | */ |
1424 | add_wait_queue(wq_head: &pd->wqueue, wq_entry: &wait); |
1425 | for (;;) { |
1426 | set_current_state(TASK_INTERRUPTIBLE); |
1427 | |
1428 | /* Check if we need to run pkt_handle_queue */ |
1429 | if (atomic_read(v: &pd->scan_queue) > 0) |
1430 | goto work_to_do; |
1431 | |
1432 | /* Check if we need to run the state machine for some packet */ |
1433 | list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { |
1434 | if (atomic_read(v: &pkt->run_sm) > 0) |
1435 | goto work_to_do; |
1436 | } |
1437 | |
1438 | /* Check if we need to process the iosched queues */ |
1439 | if (atomic_read(v: &pd->iosched.attention) != 0) |
1440 | goto work_to_do; |
1441 | |
1442 | /* Otherwise, go to sleep */ |
1443 | pkt_count_states(pd, states); |
1444 | dev_dbg(ddev, "i:%d ow:%d rw:%d ww:%d rec:%d fin:%d\n" , |
1445 | states[0], states[1], states[2], states[3], states[4], states[5]); |
1446 | |
1447 | min_sleep_time = MAX_SCHEDULE_TIMEOUT; |
1448 | list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { |
1449 | if (pkt->sleep_time && pkt->sleep_time < min_sleep_time) |
1450 | min_sleep_time = pkt->sleep_time; |
1451 | } |
1452 | |
1453 | dev_dbg(ddev, "sleeping\n" ); |
1454 | residue = schedule_timeout(timeout: min_sleep_time); |
1455 | dev_dbg(ddev, "wake up\n" ); |
1456 | |
1457 | /* make swsusp happy with our thread */ |
1458 | try_to_freeze(); |
1459 | |
1460 | list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { |
1461 | if (!pkt->sleep_time) |
1462 | continue; |
1463 | pkt->sleep_time -= min_sleep_time - residue; |
1464 | if (pkt->sleep_time <= 0) { |
1465 | pkt->sleep_time = 0; |
1466 | atomic_inc(v: &pkt->run_sm); |
1467 | } |
1468 | } |
1469 | |
1470 | if (kthread_should_stop()) |
1471 | break; |
1472 | } |
1473 | work_to_do: |
1474 | set_current_state(TASK_RUNNING); |
1475 | remove_wait_queue(wq_head: &pd->wqueue, wq_entry: &wait); |
1476 | |
1477 | if (kthread_should_stop()) |
1478 | break; |
1479 | |
1480 | /* |
1481 | * if pkt_handle_queue returns true, we can queue |
1482 | * another request. |
1483 | */ |
1484 | while (pkt_handle_queue(pd)) |
1485 | ; |
1486 | |
1487 | /* |
1488 | * Handle packet state machine |
1489 | */ |
1490 | pkt_handle_packets(pd); |
1491 | |
1492 | /* |
1493 | * Handle iosched queues |
1494 | */ |
1495 | pkt_iosched_process_queue(pd); |
1496 | } |
1497 | |
1498 | return 0; |
1499 | } |
1500 | |
1501 | static void pkt_print_settings(struct pktcdvd_device *pd) |
1502 | { |
1503 | dev_info(disk_to_dev(pd->disk), "%s packets, %u blocks, Mode-%c disc\n" , |
1504 | pd->settings.fp ? "Fixed" : "Variable" , |
1505 | pd->settings.size >> 2, |
1506 | pd->settings.block_mode == 8 ? '1' : '2'); |
1507 | } |
1508 | |
1509 | static int pkt_mode_sense(struct pktcdvd_device *pd, struct packet_command *cgc, int page_code, int page_control) |
1510 | { |
1511 | memset(cgc->cmd, 0, sizeof(cgc->cmd)); |
1512 | |
1513 | cgc->cmd[0] = GPCMD_MODE_SENSE_10; |
1514 | cgc->cmd[2] = page_code | (page_control << 6); |
1515 | put_unaligned_be16(val: cgc->buflen, p: &cgc->cmd[7]); |
1516 | cgc->data_direction = CGC_DATA_READ; |
1517 | return pkt_generic_packet(pd, cgc); |
1518 | } |
1519 | |
1520 | static int pkt_mode_select(struct pktcdvd_device *pd, struct packet_command *cgc) |
1521 | { |
1522 | memset(cgc->cmd, 0, sizeof(cgc->cmd)); |
1523 | memset(cgc->buffer, 0, 2); |
1524 | cgc->cmd[0] = GPCMD_MODE_SELECT_10; |
1525 | cgc->cmd[1] = 0x10; /* PF */ |
1526 | put_unaligned_be16(val: cgc->buflen, p: &cgc->cmd[7]); |
1527 | cgc->data_direction = CGC_DATA_WRITE; |
1528 | return pkt_generic_packet(pd, cgc); |
1529 | } |
1530 | |
1531 | static int pkt_get_disc_info(struct pktcdvd_device *pd, disc_information *di) |
1532 | { |
1533 | struct packet_command cgc; |
1534 | int ret; |
1535 | |
1536 | /* set up command and get the disc info */ |
1537 | init_cdrom_command(cgc: &cgc, buffer: di, len: sizeof(*di), CGC_DATA_READ); |
1538 | cgc.cmd[0] = GPCMD_READ_DISC_INFO; |
1539 | cgc.cmd[8] = cgc.buflen = 2; |
1540 | cgc.quiet = 1; |
1541 | |
1542 | ret = pkt_generic_packet(pd, cgc: &cgc); |
1543 | if (ret) |
1544 | return ret; |
1545 | |
1546 | /* not all drives have the same disc_info length, so requeue |
1547 | * packet with the length the drive tells us it can supply |
1548 | */ |
1549 | cgc.buflen = be16_to_cpu(di->disc_information_length) + |
1550 | sizeof(di->disc_information_length); |
1551 | |
1552 | if (cgc.buflen > sizeof(disc_information)) |
1553 | cgc.buflen = sizeof(disc_information); |
1554 | |
1555 | cgc.cmd[8] = cgc.buflen; |
1556 | return pkt_generic_packet(pd, cgc: &cgc); |
1557 | } |
1558 | |
1559 | static int pkt_get_track_info(struct pktcdvd_device *pd, __u16 track, __u8 type, track_information *ti) |
1560 | { |
1561 | struct packet_command cgc; |
1562 | int ret; |
1563 | |
1564 | init_cdrom_command(cgc: &cgc, buffer: ti, len: 8, CGC_DATA_READ); |
1565 | cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO; |
1566 | cgc.cmd[1] = type & 3; |
1567 | put_unaligned_be16(val: track, p: &cgc.cmd[4]); |
1568 | cgc.cmd[8] = 8; |
1569 | cgc.quiet = 1; |
1570 | |
1571 | ret = pkt_generic_packet(pd, cgc: &cgc); |
1572 | if (ret) |
1573 | return ret; |
1574 | |
1575 | cgc.buflen = be16_to_cpu(ti->track_information_length) + |
1576 | sizeof(ti->track_information_length); |
1577 | |
1578 | if (cgc.buflen > sizeof(track_information)) |
1579 | cgc.buflen = sizeof(track_information); |
1580 | |
1581 | cgc.cmd[8] = cgc.buflen; |
1582 | return pkt_generic_packet(pd, cgc: &cgc); |
1583 | } |
1584 | |
1585 | static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd, |
1586 | long *last_written) |
1587 | { |
1588 | disc_information di; |
1589 | track_information ti; |
1590 | __u32 last_track; |
1591 | int ret; |
1592 | |
1593 | ret = pkt_get_disc_info(pd, di: &di); |
1594 | if (ret) |
1595 | return ret; |
1596 | |
1597 | last_track = (di.last_track_msb << 8) | di.last_track_lsb; |
1598 | ret = pkt_get_track_info(pd, track: last_track, type: 1, ti: &ti); |
1599 | if (ret) |
1600 | return ret; |
1601 | |
1602 | /* if this track is blank, try the previous. */ |
1603 | if (ti.blank) { |
1604 | last_track--; |
1605 | ret = pkt_get_track_info(pd, track: last_track, type: 1, ti: &ti); |
1606 | if (ret) |
1607 | return ret; |
1608 | } |
1609 | |
1610 | /* if last recorded field is valid, return it. */ |
1611 | if (ti.lra_v) { |
1612 | *last_written = be32_to_cpu(ti.last_rec_address); |
1613 | } else { |
1614 | /* make it up instead */ |
1615 | *last_written = be32_to_cpu(ti.track_start) + |
1616 | be32_to_cpu(ti.track_size); |
1617 | if (ti.free_blocks) |
1618 | *last_written -= (be32_to_cpu(ti.free_blocks) + 7); |
1619 | } |
1620 | return 0; |
1621 | } |
1622 | |
1623 | /* |
1624 | * write mode select package based on pd->settings |
1625 | */ |
1626 | static noinline_for_stack int pkt_set_write_settings(struct pktcdvd_device *pd) |
1627 | { |
1628 | struct device *ddev = disk_to_dev(pd->disk); |
1629 | struct packet_command cgc; |
1630 | struct scsi_sense_hdr sshdr; |
1631 | write_param_page *wp; |
1632 | char buffer[128]; |
1633 | int ret, size; |
1634 | |
1635 | /* doesn't apply to DVD+RW or DVD-RAM */ |
1636 | if ((pd->mmc3_profile == 0x1a) || (pd->mmc3_profile == 0x12)) |
1637 | return 0; |
1638 | |
1639 | memset(buffer, 0, sizeof(buffer)); |
1640 | init_cdrom_command(cgc: &cgc, buffer, len: sizeof(*wp), CGC_DATA_READ); |
1641 | cgc.sshdr = &sshdr; |
1642 | ret = pkt_mode_sense(pd, cgc: &cgc, GPMODE_WRITE_PARMS_PAGE, page_control: 0); |
1643 | if (ret) { |
1644 | pkt_dump_sense(pd, cgc: &cgc); |
1645 | return ret; |
1646 | } |
1647 | |
1648 | size = 2 + get_unaligned_be16(p: &buffer[0]); |
1649 | pd->mode_offset = get_unaligned_be16(p: &buffer[6]); |
1650 | if (size > sizeof(buffer)) |
1651 | size = sizeof(buffer); |
1652 | |
1653 | /* |
1654 | * now get it all |
1655 | */ |
1656 | init_cdrom_command(cgc: &cgc, buffer, len: size, CGC_DATA_READ); |
1657 | cgc.sshdr = &sshdr; |
1658 | ret = pkt_mode_sense(pd, cgc: &cgc, GPMODE_WRITE_PARMS_PAGE, page_control: 0); |
1659 | if (ret) { |
1660 | pkt_dump_sense(pd, cgc: &cgc); |
1661 | return ret; |
1662 | } |
1663 | |
1664 | /* |
1665 | * write page is offset header + block descriptor length |
1666 | */ |
1667 | wp = (write_param_page *) &buffer[sizeof(struct mode_page_header) + pd->mode_offset]; |
1668 | |
1669 | wp->fp = pd->settings.fp; |
1670 | wp->track_mode = pd->settings.track_mode; |
1671 | wp->write_type = pd->settings.write_type; |
1672 | wp->data_block_type = pd->settings.block_mode; |
1673 | |
1674 | wp->multi_session = 0; |
1675 | |
1676 | #ifdef PACKET_USE_LS |
1677 | wp->link_size = 7; |
1678 | wp->ls_v = 1; |
1679 | #endif |
1680 | |
1681 | if (wp->data_block_type == PACKET_BLOCK_MODE1) { |
1682 | wp->session_format = 0; |
1683 | wp->subhdr2 = 0x20; |
1684 | } else if (wp->data_block_type == PACKET_BLOCK_MODE2) { |
1685 | wp->session_format = 0x20; |
1686 | wp->subhdr2 = 8; |
1687 | #if 0 |
1688 | wp->mcn[0] = 0x80; |
1689 | memcpy(&wp->mcn[1], PACKET_MCN, sizeof(wp->mcn) - 1); |
1690 | #endif |
1691 | } else { |
1692 | /* |
1693 | * paranoia |
1694 | */ |
1695 | dev_err(ddev, "write mode wrong %d\n" , wp->data_block_type); |
1696 | return 1; |
1697 | } |
1698 | wp->packet_size = cpu_to_be32(pd->settings.size >> 2); |
1699 | |
1700 | cgc.buflen = cgc.cmd[8] = size; |
1701 | ret = pkt_mode_select(pd, cgc: &cgc); |
1702 | if (ret) { |
1703 | pkt_dump_sense(pd, cgc: &cgc); |
1704 | return ret; |
1705 | } |
1706 | |
1707 | pkt_print_settings(pd); |
1708 | return 0; |
1709 | } |
1710 | |
1711 | /* |
1712 | * 1 -- we can write to this track, 0 -- we can't |
1713 | */ |
1714 | static int pkt_writable_track(struct pktcdvd_device *pd, track_information *ti) |
1715 | { |
1716 | struct device *ddev = disk_to_dev(pd->disk); |
1717 | |
1718 | switch (pd->mmc3_profile) { |
1719 | case 0x1a: /* DVD+RW */ |
1720 | case 0x12: /* DVD-RAM */ |
1721 | /* The track is always writable on DVD+RW/DVD-RAM */ |
1722 | return 1; |
1723 | default: |
1724 | break; |
1725 | } |
1726 | |
1727 | if (!ti->packet || !ti->fp) |
1728 | return 0; |
1729 | |
1730 | /* |
1731 | * "good" settings as per Mt Fuji. |
1732 | */ |
1733 | if (ti->rt == 0 && ti->blank == 0) |
1734 | return 1; |
1735 | |
1736 | if (ti->rt == 0 && ti->blank == 1) |
1737 | return 1; |
1738 | |
1739 | if (ti->rt == 1 && ti->blank == 0) |
1740 | return 1; |
1741 | |
1742 | dev_err(ddev, "bad state %d-%d-%d\n" , ti->rt, ti->blank, ti->packet); |
1743 | return 0; |
1744 | } |
1745 | |
1746 | /* |
1747 | * 1 -- we can write to this disc, 0 -- we can't |
1748 | */ |
1749 | static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di) |
1750 | { |
1751 | struct device *ddev = disk_to_dev(pd->disk); |
1752 | |
1753 | switch (pd->mmc3_profile) { |
1754 | case 0x0a: /* CD-RW */ |
1755 | case 0xffff: /* MMC3 not supported */ |
1756 | break; |
1757 | case 0x1a: /* DVD+RW */ |
1758 | case 0x13: /* DVD-RW */ |
1759 | case 0x12: /* DVD-RAM */ |
1760 | return 1; |
1761 | default: |
1762 | dev_dbg(ddev, "Wrong disc profile (%x)\n" , pd->mmc3_profile); |
1763 | return 0; |
1764 | } |
1765 | |
1766 | /* |
1767 | * for disc type 0xff we should probably reserve a new track. |
1768 | * but i'm not sure, should we leave this to user apps? probably. |
1769 | */ |
1770 | if (di->disc_type == 0xff) { |
1771 | dev_notice(ddev, "unknown disc - no track?\n" ); |
1772 | return 0; |
1773 | } |
1774 | |
1775 | if (di->disc_type != 0x20 && di->disc_type != 0) { |
1776 | dev_err(ddev, "wrong disc type (%x)\n" , di->disc_type); |
1777 | return 0; |
1778 | } |
1779 | |
1780 | if (di->erasable == 0) { |
1781 | dev_err(ddev, "disc not erasable\n" ); |
1782 | return 0; |
1783 | } |
1784 | |
1785 | if (di->border_status == PACKET_SESSION_RESERVED) { |
1786 | dev_err(ddev, "can't write to last track (reserved)\n" ); |
1787 | return 0; |
1788 | } |
1789 | |
1790 | return 1; |
1791 | } |
1792 | |
1793 | static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd) |
1794 | { |
1795 | struct device *ddev = disk_to_dev(pd->disk); |
1796 | struct packet_command cgc; |
1797 | unsigned char buf[12]; |
1798 | disc_information di; |
1799 | track_information ti; |
1800 | int ret, track; |
1801 | |
1802 | init_cdrom_command(cgc: &cgc, buffer: buf, len: sizeof(buf), CGC_DATA_READ); |
1803 | cgc.cmd[0] = GPCMD_GET_CONFIGURATION; |
1804 | cgc.cmd[8] = 8; |
1805 | ret = pkt_generic_packet(pd, cgc: &cgc); |
1806 | pd->mmc3_profile = ret ? 0xffff : get_unaligned_be16(p: &buf[6]); |
1807 | |
1808 | memset(&di, 0, sizeof(disc_information)); |
1809 | memset(&ti, 0, sizeof(track_information)); |
1810 | |
1811 | ret = pkt_get_disc_info(pd, di: &di); |
1812 | if (ret) { |
1813 | dev_err(ddev, "failed get_disc\n" ); |
1814 | return ret; |
1815 | } |
1816 | |
1817 | if (!pkt_writable_disc(pd, di: &di)) |
1818 | return -EROFS; |
1819 | |
1820 | pd->type = di.erasable ? PACKET_CDRW : PACKET_CDR; |
1821 | |
1822 | track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */ |
1823 | ret = pkt_get_track_info(pd, track, type: 1, ti: &ti); |
1824 | if (ret) { |
1825 | dev_err(ddev, "failed get_track\n" ); |
1826 | return ret; |
1827 | } |
1828 | |
1829 | if (!pkt_writable_track(pd, ti: &ti)) { |
1830 | dev_err(ddev, "can't write to this track\n" ); |
1831 | return -EROFS; |
1832 | } |
1833 | |
1834 | /* |
1835 | * we keep packet size in 512 byte units, makes it easier to |
1836 | * deal with request calculations. |
1837 | */ |
1838 | pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; |
1839 | if (pd->settings.size == 0) { |
1840 | dev_notice(ddev, "detected zero packet size!\n" ); |
1841 | return -ENXIO; |
1842 | } |
1843 | if (pd->settings.size > PACKET_MAX_SECTORS) { |
1844 | dev_err(ddev, "packet size is too big\n" ); |
1845 | return -EROFS; |
1846 | } |
1847 | pd->settings.fp = ti.fp; |
1848 | pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1); |
1849 | |
1850 | if (ti.nwa_v) { |
1851 | pd->nwa = be32_to_cpu(ti.next_writable); |
1852 | set_bit(PACKET_NWA_VALID, addr: &pd->flags); |
1853 | } |
1854 | |
1855 | /* |
1856 | * in theory we could use lra on -RW media as well and just zero |
1857 | * blocks that haven't been written yet, but in practice that |
1858 | * is just a no-go. we'll use that for -R, naturally. |
1859 | */ |
1860 | if (ti.lra_v) { |
1861 | pd->lra = be32_to_cpu(ti.last_rec_address); |
1862 | set_bit(PACKET_LRA_VALID, addr: &pd->flags); |
1863 | } else { |
1864 | pd->lra = 0xffffffff; |
1865 | set_bit(PACKET_LRA_VALID, addr: &pd->flags); |
1866 | } |
1867 | |
1868 | /* |
1869 | * fine for now |
1870 | */ |
1871 | pd->settings.link_loss = 7; |
1872 | pd->settings.write_type = 0; /* packet */ |
1873 | pd->settings.track_mode = ti.track_mode; |
1874 | |
1875 | /* |
1876 | * mode1 or mode2 disc |
1877 | */ |
1878 | switch (ti.data_mode) { |
1879 | case PACKET_MODE1: |
1880 | pd->settings.block_mode = PACKET_BLOCK_MODE1; |
1881 | break; |
1882 | case PACKET_MODE2: |
1883 | pd->settings.block_mode = PACKET_BLOCK_MODE2; |
1884 | break; |
1885 | default: |
1886 | dev_err(ddev, "unknown data mode\n" ); |
1887 | return -EROFS; |
1888 | } |
1889 | return 0; |
1890 | } |
1891 | |
1892 | /* |
1893 | * enable/disable write caching on drive |
1894 | */ |
1895 | static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd) |
1896 | { |
1897 | struct device *ddev = disk_to_dev(pd->disk); |
1898 | struct packet_command cgc; |
1899 | struct scsi_sense_hdr sshdr; |
1900 | unsigned char buf[64]; |
1901 | bool set = IS_ENABLED(CONFIG_CDROM_PKTCDVD_WCACHE); |
1902 | int ret; |
1903 | |
1904 | init_cdrom_command(cgc: &cgc, buffer: buf, len: sizeof(buf), CGC_DATA_READ); |
1905 | cgc.sshdr = &sshdr; |
1906 | cgc.buflen = pd->mode_offset + 12; |
1907 | |
1908 | /* |
1909 | * caching mode page might not be there, so quiet this command |
1910 | */ |
1911 | cgc.quiet = 1; |
1912 | |
1913 | ret = pkt_mode_sense(pd, cgc: &cgc, GPMODE_WCACHING_PAGE, page_control: 0); |
1914 | if (ret) |
1915 | return ret; |
1916 | |
1917 | /* |
1918 | * use drive write caching -- we need deferred error handling to be |
1919 | * able to successfully recover with this option (drive will return good |
1920 | * status as soon as the cdb is validated). |
1921 | */ |
1922 | buf[pd->mode_offset + 10] |= (set << 2); |
1923 | |
1924 | cgc.buflen = cgc.cmd[8] = 2 + get_unaligned_be16(p: &buf[0]); |
1925 | ret = pkt_mode_select(pd, cgc: &cgc); |
1926 | if (ret) { |
1927 | dev_err(ddev, "write caching control failed\n" ); |
1928 | pkt_dump_sense(pd, cgc: &cgc); |
1929 | } else if (!ret && set) |
1930 | dev_notice(ddev, "enabled write caching\n" ); |
1931 | return ret; |
1932 | } |
1933 | |
1934 | static int pkt_lock_door(struct pktcdvd_device *pd, int lockflag) |
1935 | { |
1936 | struct packet_command cgc; |
1937 | |
1938 | init_cdrom_command(cgc: &cgc, NULL, len: 0, CGC_DATA_NONE); |
1939 | cgc.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; |
1940 | cgc.cmd[4] = lockflag ? 1 : 0; |
1941 | return pkt_generic_packet(pd, cgc: &cgc); |
1942 | } |
1943 | |
1944 | /* |
1945 | * Returns drive maximum write speed |
1946 | */ |
1947 | static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd, |
1948 | unsigned *write_speed) |
1949 | { |
1950 | struct packet_command cgc; |
1951 | struct scsi_sense_hdr sshdr; |
1952 | unsigned char buf[256+18]; |
1953 | unsigned char *cap_buf; |
1954 | int ret, offset; |
1955 | |
1956 | cap_buf = &buf[sizeof(struct mode_page_header) + pd->mode_offset]; |
1957 | init_cdrom_command(cgc: &cgc, buffer: buf, len: sizeof(buf), CGC_DATA_UNKNOWN); |
1958 | cgc.sshdr = &sshdr; |
1959 | |
1960 | ret = pkt_mode_sense(pd, cgc: &cgc, GPMODE_CAPABILITIES_PAGE, page_control: 0); |
1961 | if (ret) { |
1962 | cgc.buflen = pd->mode_offset + cap_buf[1] + 2 + |
1963 | sizeof(struct mode_page_header); |
1964 | ret = pkt_mode_sense(pd, cgc: &cgc, GPMODE_CAPABILITIES_PAGE, page_control: 0); |
1965 | if (ret) { |
1966 | pkt_dump_sense(pd, cgc: &cgc); |
1967 | return ret; |
1968 | } |
1969 | } |
1970 | |
1971 | offset = 20; /* Obsoleted field, used by older drives */ |
1972 | if (cap_buf[1] >= 28) |
1973 | offset = 28; /* Current write speed selected */ |
1974 | if (cap_buf[1] >= 30) { |
1975 | /* If the drive reports at least one "Logical Unit Write |
1976 | * Speed Performance Descriptor Block", use the information |
1977 | * in the first block. (contains the highest speed) |
1978 | */ |
1979 | int num_spdb = get_unaligned_be16(p: &cap_buf[30]); |
1980 | if (num_spdb > 0) |
1981 | offset = 34; |
1982 | } |
1983 | |
1984 | *write_speed = get_unaligned_be16(p: &cap_buf[offset]); |
1985 | return 0; |
1986 | } |
1987 | |
1988 | /* These tables from cdrecord - I don't have orange book */ |
1989 | /* standard speed CD-RW (1-4x) */ |
1990 | static char clv_to_speed[16] = { |
1991 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ |
1992 | 0, 2, 4, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
1993 | }; |
1994 | /* high speed CD-RW (-10x) */ |
1995 | static char hs_clv_to_speed[16] = { |
1996 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ |
1997 | 0, 2, 4, 6, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
1998 | }; |
1999 | /* ultra high speed CD-RW */ |
2000 | static char us_clv_to_speed[16] = { |
2001 | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ |
2002 | 0, 2, 4, 8, 0, 0,16, 0,24,32,40,48, 0, 0, 0, 0 |
2003 | }; |
2004 | |
2005 | /* |
2006 | * reads the maximum media speed from ATIP |
2007 | */ |
2008 | static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd, |
2009 | unsigned *speed) |
2010 | { |
2011 | struct device *ddev = disk_to_dev(pd->disk); |
2012 | struct packet_command cgc; |
2013 | struct scsi_sense_hdr sshdr; |
2014 | unsigned char buf[64]; |
2015 | unsigned int size, st, sp; |
2016 | int ret; |
2017 | |
2018 | init_cdrom_command(cgc: &cgc, buffer: buf, len: 2, CGC_DATA_READ); |
2019 | cgc.sshdr = &sshdr; |
2020 | cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; |
2021 | cgc.cmd[1] = 2; |
2022 | cgc.cmd[2] = 4; /* READ ATIP */ |
2023 | cgc.cmd[8] = 2; |
2024 | ret = pkt_generic_packet(pd, cgc: &cgc); |
2025 | if (ret) { |
2026 | pkt_dump_sense(pd, cgc: &cgc); |
2027 | return ret; |
2028 | } |
2029 | size = 2 + get_unaligned_be16(p: &buf[0]); |
2030 | if (size > sizeof(buf)) |
2031 | size = sizeof(buf); |
2032 | |
2033 | init_cdrom_command(cgc: &cgc, buffer: buf, len: size, CGC_DATA_READ); |
2034 | cgc.sshdr = &sshdr; |
2035 | cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; |
2036 | cgc.cmd[1] = 2; |
2037 | cgc.cmd[2] = 4; |
2038 | cgc.cmd[8] = size; |
2039 | ret = pkt_generic_packet(pd, cgc: &cgc); |
2040 | if (ret) { |
2041 | pkt_dump_sense(pd, cgc: &cgc); |
2042 | return ret; |
2043 | } |
2044 | |
2045 | if (!(buf[6] & 0x40)) { |
2046 | dev_notice(ddev, "disc type is not CD-RW\n" ); |
2047 | return 1; |
2048 | } |
2049 | if (!(buf[6] & 0x4)) { |
2050 | dev_notice(ddev, "A1 values on media are not valid, maybe not CDRW?\n" ); |
2051 | return 1; |
2052 | } |
2053 | |
2054 | st = (buf[6] >> 3) & 0x7; /* disc sub-type */ |
2055 | |
2056 | sp = buf[16] & 0xf; /* max speed from ATIP A1 field */ |
2057 | |
2058 | /* Info from cdrecord */ |
2059 | switch (st) { |
2060 | case 0: /* standard speed */ |
2061 | *speed = clv_to_speed[sp]; |
2062 | break; |
2063 | case 1: /* high speed */ |
2064 | *speed = hs_clv_to_speed[sp]; |
2065 | break; |
2066 | case 2: /* ultra high speed */ |
2067 | *speed = us_clv_to_speed[sp]; |
2068 | break; |
2069 | default: |
2070 | dev_notice(ddev, "unknown disc sub-type %d\n" , st); |
2071 | return 1; |
2072 | } |
2073 | if (*speed) { |
2074 | dev_info(ddev, "maximum media speed: %d\n" , *speed); |
2075 | return 0; |
2076 | } else { |
2077 | dev_notice(ddev, "unknown speed %d for sub-type %d\n" , sp, st); |
2078 | return 1; |
2079 | } |
2080 | } |
2081 | |
2082 | static noinline_for_stack int pkt_perform_opc(struct pktcdvd_device *pd) |
2083 | { |
2084 | struct device *ddev = disk_to_dev(pd->disk); |
2085 | struct packet_command cgc; |
2086 | struct scsi_sense_hdr sshdr; |
2087 | int ret; |
2088 | |
2089 | dev_dbg(ddev, "Performing OPC\n" ); |
2090 | |
2091 | init_cdrom_command(cgc: &cgc, NULL, len: 0, CGC_DATA_NONE); |
2092 | cgc.sshdr = &sshdr; |
2093 | cgc.timeout = 60*HZ; |
2094 | cgc.cmd[0] = GPCMD_SEND_OPC; |
2095 | cgc.cmd[1] = 1; |
2096 | ret = pkt_generic_packet(pd, cgc: &cgc); |
2097 | if (ret) |
2098 | pkt_dump_sense(pd, cgc: &cgc); |
2099 | return ret; |
2100 | } |
2101 | |
2102 | static int pkt_open_write(struct pktcdvd_device *pd) |
2103 | { |
2104 | struct device *ddev = disk_to_dev(pd->disk); |
2105 | int ret; |
2106 | unsigned int write_speed, media_write_speed, read_speed; |
2107 | |
2108 | ret = pkt_probe_settings(pd); |
2109 | if (ret) { |
2110 | dev_dbg(ddev, "failed probe\n" ); |
2111 | return ret; |
2112 | } |
2113 | |
2114 | ret = pkt_set_write_settings(pd); |
2115 | if (ret) { |
2116 | dev_notice(ddev, "failed saving write settings\n" ); |
2117 | return -EIO; |
2118 | } |
2119 | |
2120 | pkt_write_caching(pd); |
2121 | |
2122 | ret = pkt_get_max_speed(pd, write_speed: &write_speed); |
2123 | if (ret) |
2124 | write_speed = 16 * 177; |
2125 | switch (pd->mmc3_profile) { |
2126 | case 0x13: /* DVD-RW */ |
2127 | case 0x1a: /* DVD+RW */ |
2128 | case 0x12: /* DVD-RAM */ |
2129 | dev_notice(ddev, "write speed %ukB/s\n" , write_speed); |
2130 | break; |
2131 | default: |
2132 | ret = pkt_media_speed(pd, speed: &media_write_speed); |
2133 | if (ret) |
2134 | media_write_speed = 16; |
2135 | write_speed = min(write_speed, media_write_speed * 177); |
2136 | dev_notice(ddev, "write speed %ux\n" , write_speed / 176); |
2137 | break; |
2138 | } |
2139 | read_speed = write_speed; |
2140 | |
2141 | ret = pkt_set_speed(pd, write_speed, read_speed); |
2142 | if (ret) { |
2143 | dev_notice(ddev, "couldn't set write speed\n" ); |
2144 | return -EIO; |
2145 | } |
2146 | pd->write_speed = write_speed; |
2147 | pd->read_speed = read_speed; |
2148 | |
2149 | ret = pkt_perform_opc(pd); |
2150 | if (ret) |
2151 | dev_notice(ddev, "Optimum Power Calibration failed\n" ); |
2152 | |
2153 | return 0; |
2154 | } |
2155 | |
2156 | /* |
2157 | * called at open time. |
2158 | */ |
2159 | static int pkt_open_dev(struct pktcdvd_device *pd, bool write) |
2160 | { |
2161 | struct device *ddev = disk_to_dev(pd->disk); |
2162 | int ret; |
2163 | long lba; |
2164 | struct request_queue *q; |
2165 | struct bdev_handle *bdev_handle; |
2166 | |
2167 | /* |
2168 | * We need to re-open the cdrom device without O_NONBLOCK to be able |
2169 | * to read/write from/to it. It is already opened in O_NONBLOCK mode |
2170 | * so open should not fail. |
2171 | */ |
2172 | bdev_handle = bdev_open_by_dev(dev: pd->bdev_handle->bdev->bd_dev, |
2173 | BLK_OPEN_READ, holder: pd, NULL); |
2174 | if (IS_ERR(ptr: bdev_handle)) { |
2175 | ret = PTR_ERR(ptr: bdev_handle); |
2176 | goto out; |
2177 | } |
2178 | pd->open_bdev_handle = bdev_handle; |
2179 | |
2180 | ret = pkt_get_last_written(pd, last_written: &lba); |
2181 | if (ret) { |
2182 | dev_err(ddev, "pkt_get_last_written failed\n" ); |
2183 | goto out_putdev; |
2184 | } |
2185 | |
2186 | set_capacity(disk: pd->disk, size: lba << 2); |
2187 | set_capacity_and_notify(disk: pd->bdev_handle->bdev->bd_disk, size: lba << 2); |
2188 | |
2189 | q = bdev_get_queue(bdev: pd->bdev_handle->bdev); |
2190 | if (write) { |
2191 | ret = pkt_open_write(pd); |
2192 | if (ret) |
2193 | goto out_putdev; |
2194 | /* |
2195 | * Some CDRW drives can not handle writes larger than one packet, |
2196 | * even if the size is a multiple of the packet size. |
2197 | */ |
2198 | blk_queue_max_hw_sectors(q, pd->settings.size); |
2199 | set_bit(PACKET_WRITABLE, addr: &pd->flags); |
2200 | } else { |
2201 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); |
2202 | clear_bit(PACKET_WRITABLE, addr: &pd->flags); |
2203 | } |
2204 | |
2205 | ret = pkt_set_segment_merging(pd, q); |
2206 | if (ret) |
2207 | goto out_putdev; |
2208 | |
2209 | if (write) { |
2210 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { |
2211 | dev_err(ddev, "not enough memory for buffers\n" ); |
2212 | ret = -ENOMEM; |
2213 | goto out_putdev; |
2214 | } |
2215 | dev_info(ddev, "%lukB available on disc\n" , lba << 1); |
2216 | } |
2217 | |
2218 | return 0; |
2219 | |
2220 | out_putdev: |
2221 | bdev_release(handle: bdev_handle); |
2222 | out: |
2223 | return ret; |
2224 | } |
2225 | |
2226 | /* |
2227 | * called when the device is closed. makes sure that the device flushes |
2228 | * the internal cache before we close. |
2229 | */ |
2230 | static void pkt_release_dev(struct pktcdvd_device *pd, int flush) |
2231 | { |
2232 | struct device *ddev = disk_to_dev(pd->disk); |
2233 | |
2234 | if (flush && pkt_flush_cache(pd)) |
2235 | dev_notice(ddev, "not flushing cache\n" ); |
2236 | |
2237 | pkt_lock_door(pd, lockflag: 0); |
2238 | |
2239 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); |
2240 | bdev_release(handle: pd->open_bdev_handle); |
2241 | pd->open_bdev_handle = NULL; |
2242 | |
2243 | pkt_shrink_pktlist(pd); |
2244 | } |
2245 | |
2246 | static struct pktcdvd_device *pkt_find_dev_from_minor(unsigned int dev_minor) |
2247 | { |
2248 | if (dev_minor >= MAX_WRITERS) |
2249 | return NULL; |
2250 | |
2251 | dev_minor = array_index_nospec(dev_minor, MAX_WRITERS); |
2252 | return pkt_devs[dev_minor]; |
2253 | } |
2254 | |
2255 | static int pkt_open(struct gendisk *disk, blk_mode_t mode) |
2256 | { |
2257 | struct pktcdvd_device *pd = NULL; |
2258 | int ret; |
2259 | |
2260 | mutex_lock(&pktcdvd_mutex); |
2261 | mutex_lock(&ctl_mutex); |
2262 | pd = pkt_find_dev_from_minor(dev_minor: disk->first_minor); |
2263 | if (!pd) { |
2264 | ret = -ENODEV; |
2265 | goto out; |
2266 | } |
2267 | BUG_ON(pd->refcnt < 0); |
2268 | |
2269 | pd->refcnt++; |
2270 | if (pd->refcnt > 1) { |
2271 | if ((mode & BLK_OPEN_WRITE) && |
2272 | !test_bit(PACKET_WRITABLE, &pd->flags)) { |
2273 | ret = -EBUSY; |
2274 | goto out_dec; |
2275 | } |
2276 | } else { |
2277 | ret = pkt_open_dev(pd, write: mode & BLK_OPEN_WRITE); |
2278 | if (ret) |
2279 | goto out_dec; |
2280 | /* |
2281 | * needed here as well, since ext2 (among others) may change |
2282 | * the blocksize at mount time |
2283 | */ |
2284 | set_blocksize(bdev: disk->part0, CD_FRAMESIZE); |
2285 | } |
2286 | mutex_unlock(lock: &ctl_mutex); |
2287 | mutex_unlock(lock: &pktcdvd_mutex); |
2288 | return 0; |
2289 | |
2290 | out_dec: |
2291 | pd->refcnt--; |
2292 | out: |
2293 | mutex_unlock(lock: &ctl_mutex); |
2294 | mutex_unlock(lock: &pktcdvd_mutex); |
2295 | return ret; |
2296 | } |
2297 | |
2298 | static void pkt_release(struct gendisk *disk) |
2299 | { |
2300 | struct pktcdvd_device *pd = disk->private_data; |
2301 | |
2302 | mutex_lock(&pktcdvd_mutex); |
2303 | mutex_lock(&ctl_mutex); |
2304 | pd->refcnt--; |
2305 | BUG_ON(pd->refcnt < 0); |
2306 | if (pd->refcnt == 0) { |
2307 | int flush = test_bit(PACKET_WRITABLE, &pd->flags); |
2308 | pkt_release_dev(pd, flush); |
2309 | } |
2310 | mutex_unlock(lock: &ctl_mutex); |
2311 | mutex_unlock(lock: &pktcdvd_mutex); |
2312 | } |
2313 | |
2314 | |
2315 | static void pkt_end_io_read_cloned(struct bio *bio) |
2316 | { |
2317 | struct packet_stacked_data *psd = bio->bi_private; |
2318 | struct pktcdvd_device *pd = psd->pd; |
2319 | |
2320 | psd->bio->bi_status = bio->bi_status; |
2321 | bio_put(bio); |
2322 | bio_endio(psd->bio); |
2323 | mempool_free(element: psd, pool: &psd_pool); |
2324 | pkt_bio_finished(pd); |
2325 | } |
2326 | |
2327 | static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio) |
2328 | { |
2329 | struct bio *cloned_bio = bio_alloc_clone(bdev: pd->bdev_handle->bdev, bio_src: bio, |
2330 | GFP_NOIO, bs: &pkt_bio_set); |
2331 | struct packet_stacked_data *psd = mempool_alloc(pool: &psd_pool, GFP_NOIO); |
2332 | |
2333 | psd->pd = pd; |
2334 | psd->bio = bio; |
2335 | cloned_bio->bi_private = psd; |
2336 | cloned_bio->bi_end_io = pkt_end_io_read_cloned; |
2337 | pd->stats.secs_r += bio_sectors(bio); |
2338 | pkt_queue_bio(pd, bio: cloned_bio); |
2339 | } |
2340 | |
2341 | static void pkt_make_request_write(struct request_queue *q, struct bio *bio) |
2342 | { |
2343 | struct pktcdvd_device *pd = q->queuedata; |
2344 | sector_t zone; |
2345 | struct packet_data *pkt; |
2346 | int was_empty, blocked_bio; |
2347 | struct pkt_rb_node *node; |
2348 | |
2349 | zone = get_zone(sector: bio->bi_iter.bi_sector, pd); |
2350 | |
2351 | /* |
2352 | * If we find a matching packet in state WAITING or READ_WAIT, we can |
2353 | * just append this bio to that packet. |
2354 | */ |
2355 | spin_lock(lock: &pd->cdrw.active_list_lock); |
2356 | blocked_bio = 0; |
2357 | list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) { |
2358 | if (pkt->sector == zone) { |
2359 | spin_lock(lock: &pkt->lock); |
2360 | if ((pkt->state == PACKET_WAITING_STATE) || |
2361 | (pkt->state == PACKET_READ_WAIT_STATE)) { |
2362 | bio_list_add(bl: &pkt->orig_bios, bio); |
2363 | pkt->write_size += |
2364 | bio->bi_iter.bi_size / CD_FRAMESIZE; |
2365 | if ((pkt->write_size >= pkt->frames) && |
2366 | (pkt->state == PACKET_WAITING_STATE)) { |
2367 | atomic_inc(v: &pkt->run_sm); |
2368 | wake_up(&pd->wqueue); |
2369 | } |
2370 | spin_unlock(lock: &pkt->lock); |
2371 | spin_unlock(lock: &pd->cdrw.active_list_lock); |
2372 | return; |
2373 | } else { |
2374 | blocked_bio = 1; |
2375 | } |
2376 | spin_unlock(lock: &pkt->lock); |
2377 | } |
2378 | } |
2379 | spin_unlock(lock: &pd->cdrw.active_list_lock); |
2380 | |
2381 | /* |
2382 | * Test if there is enough room left in the bio work queue |
2383 | * (queue size >= congestion on mark). |
2384 | * If not, wait till the work queue size is below the congestion off mark. |
2385 | */ |
2386 | spin_lock(lock: &pd->lock); |
2387 | if (pd->write_congestion_on > 0 |
2388 | && pd->bio_queue_size >= pd->write_congestion_on) { |
2389 | struct wait_bit_queue_entry wqe; |
2390 | |
2391 | init_wait_var_entry(wbq_entry: &wqe, var: &pd->congested, flags: 0); |
2392 | for (;;) { |
2393 | prepare_to_wait_event(wq_head: __var_waitqueue(p: &pd->congested), |
2394 | wq_entry: &wqe.wq_entry, |
2395 | TASK_UNINTERRUPTIBLE); |
2396 | if (pd->bio_queue_size <= pd->write_congestion_off) |
2397 | break; |
2398 | pd->congested = true; |
2399 | spin_unlock(lock: &pd->lock); |
2400 | schedule(); |
2401 | spin_lock(lock: &pd->lock); |
2402 | } |
2403 | } |
2404 | spin_unlock(lock: &pd->lock); |
2405 | |
2406 | /* |
2407 | * No matching packet found. Store the bio in the work queue. |
2408 | */ |
2409 | node = mempool_alloc(pool: &pd->rb_pool, GFP_NOIO); |
2410 | node->bio = bio; |
2411 | spin_lock(lock: &pd->lock); |
2412 | BUG_ON(pd->bio_queue_size < 0); |
2413 | was_empty = (pd->bio_queue_size == 0); |
2414 | pkt_rbtree_insert(pd, node); |
2415 | spin_unlock(lock: &pd->lock); |
2416 | |
2417 | /* |
2418 | * Wake up the worker thread. |
2419 | */ |
2420 | atomic_set(v: &pd->scan_queue, i: 1); |
2421 | if (was_empty) { |
2422 | /* This wake_up is required for correct operation */ |
2423 | wake_up(&pd->wqueue); |
2424 | } else if (!list_empty(head: &pd->cdrw.pkt_free_list) && !blocked_bio) { |
2425 | /* |
2426 | * This wake up is not required for correct operation, |
2427 | * but improves performance in some cases. |
2428 | */ |
2429 | wake_up(&pd->wqueue); |
2430 | } |
2431 | } |
2432 | |
2433 | static void pkt_submit_bio(struct bio *bio) |
2434 | { |
2435 | struct pktcdvd_device *pd = bio->bi_bdev->bd_disk->queue->queuedata; |
2436 | struct device *ddev = disk_to_dev(pd->disk); |
2437 | struct bio *split; |
2438 | |
2439 | bio = bio_split_to_limits(bio); |
2440 | if (!bio) |
2441 | return; |
2442 | |
2443 | dev_dbg(ddev, "start = %6llx stop = %6llx\n" , |
2444 | bio->bi_iter.bi_sector, bio_end_sector(bio)); |
2445 | |
2446 | /* |
2447 | * Clone READ bios so we can have our own bi_end_io callback. |
2448 | */ |
2449 | if (bio_data_dir(bio) == READ) { |
2450 | pkt_make_request_read(pd, bio); |
2451 | return; |
2452 | } |
2453 | |
2454 | if (!test_bit(PACKET_WRITABLE, &pd->flags)) { |
2455 | dev_notice(ddev, "WRITE for ro device (%llu)\n" , bio->bi_iter.bi_sector); |
2456 | goto end_io; |
2457 | } |
2458 | |
2459 | if (!bio->bi_iter.bi_size || (bio->bi_iter.bi_size % CD_FRAMESIZE)) { |
2460 | dev_err(ddev, "wrong bio size\n" ); |
2461 | goto end_io; |
2462 | } |
2463 | |
2464 | do { |
2465 | sector_t zone = get_zone(sector: bio->bi_iter.bi_sector, pd); |
2466 | sector_t last_zone = get_zone(bio_end_sector(bio) - 1, pd); |
2467 | |
2468 | if (last_zone != zone) { |
2469 | BUG_ON(last_zone != zone + pd->settings.size); |
2470 | |
2471 | split = bio_split(bio, sectors: last_zone - |
2472 | bio->bi_iter.bi_sector, |
2473 | GFP_NOIO, bs: &pkt_bio_set); |
2474 | bio_chain(split, bio); |
2475 | } else { |
2476 | split = bio; |
2477 | } |
2478 | |
2479 | pkt_make_request_write(q: bio->bi_bdev->bd_disk->queue, bio: split); |
2480 | } while (split != bio); |
2481 | |
2482 | return; |
2483 | end_io: |
2484 | bio_io_error(bio); |
2485 | } |
2486 | |
2487 | static void pkt_init_queue(struct pktcdvd_device *pd) |
2488 | { |
2489 | struct request_queue *q = pd->disk->queue; |
2490 | |
2491 | blk_queue_logical_block_size(q, CD_FRAMESIZE); |
2492 | blk_queue_max_hw_sectors(q, PACKET_MAX_SECTORS); |
2493 | q->queuedata = pd; |
2494 | } |
2495 | |
2496 | static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) |
2497 | { |
2498 | struct device *ddev = disk_to_dev(pd->disk); |
2499 | int i; |
2500 | struct bdev_handle *bdev_handle; |
2501 | struct scsi_device *sdev; |
2502 | |
2503 | if (pd->pkt_dev == dev) { |
2504 | dev_err(ddev, "recursive setup not allowed\n" ); |
2505 | return -EBUSY; |
2506 | } |
2507 | for (i = 0; i < MAX_WRITERS; i++) { |
2508 | struct pktcdvd_device *pd2 = pkt_devs[i]; |
2509 | if (!pd2) |
2510 | continue; |
2511 | if (pd2->bdev_handle->bdev->bd_dev == dev) { |
2512 | dev_err(ddev, "%pg already setup\n" , |
2513 | pd2->bdev_handle->bdev); |
2514 | return -EBUSY; |
2515 | } |
2516 | if (pd2->pkt_dev == dev) { |
2517 | dev_err(ddev, "can't chain pktcdvd devices\n" ); |
2518 | return -EBUSY; |
2519 | } |
2520 | } |
2521 | |
2522 | bdev_handle = bdev_open_by_dev(dev, BLK_OPEN_READ | BLK_OPEN_NDELAY, |
2523 | NULL, NULL); |
2524 | if (IS_ERR(ptr: bdev_handle)) |
2525 | return PTR_ERR(ptr: bdev_handle); |
2526 | sdev = scsi_device_from_queue(q: bdev_handle->bdev->bd_disk->queue); |
2527 | if (!sdev) { |
2528 | bdev_release(handle: bdev_handle); |
2529 | return -EINVAL; |
2530 | } |
2531 | put_device(dev: &sdev->sdev_gendev); |
2532 | |
2533 | /* This is safe, since we have a reference from open(). */ |
2534 | __module_get(THIS_MODULE); |
2535 | |
2536 | pd->bdev_handle = bdev_handle; |
2537 | set_blocksize(bdev: bdev_handle->bdev, CD_FRAMESIZE); |
2538 | |
2539 | pkt_init_queue(pd); |
2540 | |
2541 | atomic_set(v: &pd->cdrw.pending_bios, i: 0); |
2542 | pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s" , pd->disk->disk_name); |
2543 | if (IS_ERR(ptr: pd->cdrw.thread)) { |
2544 | dev_err(ddev, "can't start kernel thread\n" ); |
2545 | goto out_mem; |
2546 | } |
2547 | |
2548 | proc_create_single_data(name: pd->disk->disk_name, mode: 0, parent: pkt_proc, show: pkt_seq_show, data: pd); |
2549 | dev_notice(ddev, "writer mapped to %pg\n" , bdev_handle->bdev); |
2550 | return 0; |
2551 | |
2552 | out_mem: |
2553 | bdev_release(handle: bdev_handle); |
2554 | /* This is safe: open() is still holding a reference. */ |
2555 | module_put(THIS_MODULE); |
2556 | return -ENOMEM; |
2557 | } |
2558 | |
2559 | static int pkt_ioctl(struct block_device *bdev, blk_mode_t mode, |
2560 | unsigned int cmd, unsigned long arg) |
2561 | { |
2562 | struct pktcdvd_device *pd = bdev->bd_disk->private_data; |
2563 | struct device *ddev = disk_to_dev(pd->disk); |
2564 | int ret; |
2565 | |
2566 | dev_dbg(ddev, "cmd %x, dev %d:%d\n" , cmd, MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); |
2567 | |
2568 | mutex_lock(&pktcdvd_mutex); |
2569 | switch (cmd) { |
2570 | case CDROMEJECT: |
2571 | /* |
2572 | * The door gets locked when the device is opened, so we |
2573 | * have to unlock it or else the eject command fails. |
2574 | */ |
2575 | if (pd->refcnt == 1) |
2576 | pkt_lock_door(pd, lockflag: 0); |
2577 | fallthrough; |
2578 | /* |
2579 | * forward selected CDROM ioctls to CD-ROM, for UDF |
2580 | */ |
2581 | case CDROMMULTISESSION: |
2582 | case CDROMREADTOCENTRY: |
2583 | case CDROM_LAST_WRITTEN: |
2584 | case CDROM_SEND_PACKET: |
2585 | case SCSI_IOCTL_SEND_COMMAND: |
2586 | if (!bdev->bd_disk->fops->ioctl) |
2587 | ret = -ENOTTY; |
2588 | else |
2589 | ret = bdev->bd_disk->fops->ioctl(bdev, mode, cmd, arg); |
2590 | break; |
2591 | default: |
2592 | dev_dbg(ddev, "Unknown ioctl (%x)\n" , cmd); |
2593 | ret = -ENOTTY; |
2594 | } |
2595 | mutex_unlock(lock: &pktcdvd_mutex); |
2596 | |
2597 | return ret; |
2598 | } |
2599 | |
2600 | static unsigned int pkt_check_events(struct gendisk *disk, |
2601 | unsigned int clearing) |
2602 | { |
2603 | struct pktcdvd_device *pd = disk->private_data; |
2604 | struct gendisk *attached_disk; |
2605 | |
2606 | if (!pd) |
2607 | return 0; |
2608 | if (!pd->bdev_handle) |
2609 | return 0; |
2610 | attached_disk = pd->bdev_handle->bdev->bd_disk; |
2611 | if (!attached_disk || !attached_disk->fops->check_events) |
2612 | return 0; |
2613 | return attached_disk->fops->check_events(attached_disk, clearing); |
2614 | } |
2615 | |
2616 | static char *pkt_devnode(struct gendisk *disk, umode_t *mode) |
2617 | { |
2618 | return kasprintf(GFP_KERNEL, fmt: "pktcdvd/%s" , disk->disk_name); |
2619 | } |
2620 | |
2621 | static const struct block_device_operations pktcdvd_ops = { |
2622 | .owner = THIS_MODULE, |
2623 | .submit_bio = pkt_submit_bio, |
2624 | .open = pkt_open, |
2625 | .release = pkt_release, |
2626 | .ioctl = pkt_ioctl, |
2627 | .compat_ioctl = blkdev_compat_ptr_ioctl, |
2628 | .check_events = pkt_check_events, |
2629 | .devnode = pkt_devnode, |
2630 | }; |
2631 | |
2632 | /* |
2633 | * Set up mapping from pktcdvd device to CD-ROM device. |
2634 | */ |
2635 | static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) |
2636 | { |
2637 | int idx; |
2638 | int ret = -ENOMEM; |
2639 | struct pktcdvd_device *pd; |
2640 | struct gendisk *disk; |
2641 | |
2642 | mutex_lock_nested(lock: &ctl_mutex, SINGLE_DEPTH_NESTING); |
2643 | |
2644 | for (idx = 0; idx < MAX_WRITERS; idx++) |
2645 | if (!pkt_devs[idx]) |
2646 | break; |
2647 | if (idx == MAX_WRITERS) { |
2648 | pr_err("max %d writers supported\n" , MAX_WRITERS); |
2649 | ret = -EBUSY; |
2650 | goto out_mutex; |
2651 | } |
2652 | |
2653 | pd = kzalloc(size: sizeof(struct pktcdvd_device), GFP_KERNEL); |
2654 | if (!pd) |
2655 | goto out_mutex; |
2656 | |
2657 | ret = mempool_init_kmalloc_pool(pool: &pd->rb_pool, PKT_RB_POOL_SIZE, |
2658 | size: sizeof(struct pkt_rb_node)); |
2659 | if (ret) |
2660 | goto out_mem; |
2661 | |
2662 | INIT_LIST_HEAD(list: &pd->cdrw.pkt_free_list); |
2663 | INIT_LIST_HEAD(list: &pd->cdrw.pkt_active_list); |
2664 | spin_lock_init(&pd->cdrw.active_list_lock); |
2665 | |
2666 | spin_lock_init(&pd->lock); |
2667 | spin_lock_init(&pd->iosched.lock); |
2668 | bio_list_init(bl: &pd->iosched.read_queue); |
2669 | bio_list_init(bl: &pd->iosched.write_queue); |
2670 | init_waitqueue_head(&pd->wqueue); |
2671 | pd->bio_queue = RB_ROOT; |
2672 | |
2673 | pd->write_congestion_on = write_congestion_on; |
2674 | pd->write_congestion_off = write_congestion_off; |
2675 | |
2676 | ret = -ENOMEM; |
2677 | disk = blk_alloc_disk(NUMA_NO_NODE); |
2678 | if (!disk) |
2679 | goto out_mem; |
2680 | pd->disk = disk; |
2681 | disk->major = pktdev_major; |
2682 | disk->first_minor = idx; |
2683 | disk->minors = 1; |
2684 | disk->fops = &pktcdvd_ops; |
2685 | disk->flags = GENHD_FL_REMOVABLE | GENHD_FL_NO_PART; |
2686 | snprintf(buf: disk->disk_name, size: sizeof(disk->disk_name), DRIVER_NAME"%d" , idx); |
2687 | disk->private_data = pd; |
2688 | |
2689 | pd->pkt_dev = MKDEV(pktdev_major, idx); |
2690 | ret = pkt_new_dev(pd, dev); |
2691 | if (ret) |
2692 | goto out_mem2; |
2693 | |
2694 | /* inherit events of the host device */ |
2695 | disk->events = pd->bdev_handle->bdev->bd_disk->events; |
2696 | |
2697 | ret = add_disk(disk); |
2698 | if (ret) |
2699 | goto out_mem2; |
2700 | |
2701 | pkt_sysfs_dev_new(pd); |
2702 | pkt_debugfs_dev_new(pd); |
2703 | |
2704 | pkt_devs[idx] = pd; |
2705 | if (pkt_dev) |
2706 | *pkt_dev = pd->pkt_dev; |
2707 | |
2708 | mutex_unlock(lock: &ctl_mutex); |
2709 | return 0; |
2710 | |
2711 | out_mem2: |
2712 | put_disk(disk); |
2713 | out_mem: |
2714 | mempool_exit(pool: &pd->rb_pool); |
2715 | kfree(objp: pd); |
2716 | out_mutex: |
2717 | mutex_unlock(lock: &ctl_mutex); |
2718 | pr_err("setup of pktcdvd device failed\n" ); |
2719 | return ret; |
2720 | } |
2721 | |
2722 | /* |
2723 | * Tear down mapping from pktcdvd device to CD-ROM device. |
2724 | */ |
2725 | static int pkt_remove_dev(dev_t pkt_dev) |
2726 | { |
2727 | struct pktcdvd_device *pd; |
2728 | struct device *ddev; |
2729 | int idx; |
2730 | int ret = 0; |
2731 | |
2732 | mutex_lock_nested(lock: &ctl_mutex, SINGLE_DEPTH_NESTING); |
2733 | |
2734 | for (idx = 0; idx < MAX_WRITERS; idx++) { |
2735 | pd = pkt_devs[idx]; |
2736 | if (pd && (pd->pkt_dev == pkt_dev)) |
2737 | break; |
2738 | } |
2739 | if (idx == MAX_WRITERS) { |
2740 | pr_debug("dev not setup\n" ); |
2741 | ret = -ENXIO; |
2742 | goto out; |
2743 | } |
2744 | |
2745 | if (pd->refcnt > 0) { |
2746 | ret = -EBUSY; |
2747 | goto out; |
2748 | } |
2749 | |
2750 | ddev = disk_to_dev(pd->disk); |
2751 | |
2752 | if (!IS_ERR(ptr: pd->cdrw.thread)) |
2753 | kthread_stop(k: pd->cdrw.thread); |
2754 | |
2755 | pkt_devs[idx] = NULL; |
2756 | |
2757 | pkt_debugfs_dev_remove(pd); |
2758 | pkt_sysfs_dev_remove(pd); |
2759 | |
2760 | bdev_release(handle: pd->bdev_handle); |
2761 | |
2762 | remove_proc_entry(pd->disk->disk_name, pkt_proc); |
2763 | dev_notice(ddev, "writer unmapped\n" ); |
2764 | |
2765 | del_gendisk(gp: pd->disk); |
2766 | put_disk(disk: pd->disk); |
2767 | |
2768 | mempool_exit(pool: &pd->rb_pool); |
2769 | kfree(objp: pd); |
2770 | |
2771 | /* This is safe: open() is still holding a reference. */ |
2772 | module_put(THIS_MODULE); |
2773 | |
2774 | out: |
2775 | mutex_unlock(lock: &ctl_mutex); |
2776 | return ret; |
2777 | } |
2778 | |
2779 | static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) |
2780 | { |
2781 | struct pktcdvd_device *pd; |
2782 | |
2783 | mutex_lock_nested(lock: &ctl_mutex, SINGLE_DEPTH_NESTING); |
2784 | |
2785 | pd = pkt_find_dev_from_minor(dev_minor: ctrl_cmd->dev_index); |
2786 | if (pd) { |
2787 | ctrl_cmd->dev = new_encode_dev(dev: pd->bdev_handle->bdev->bd_dev); |
2788 | ctrl_cmd->pkt_dev = new_encode_dev(dev: pd->pkt_dev); |
2789 | } else { |
2790 | ctrl_cmd->dev = 0; |
2791 | ctrl_cmd->pkt_dev = 0; |
2792 | } |
2793 | ctrl_cmd->num_devices = MAX_WRITERS; |
2794 | |
2795 | mutex_unlock(lock: &ctl_mutex); |
2796 | } |
2797 | |
2798 | static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2799 | { |
2800 | void __user *argp = (void __user *)arg; |
2801 | struct pkt_ctrl_command ctrl_cmd; |
2802 | int ret = 0; |
2803 | dev_t pkt_dev = 0; |
2804 | |
2805 | if (cmd != PACKET_CTRL_CMD) |
2806 | return -ENOTTY; |
2807 | |
2808 | if (copy_from_user(to: &ctrl_cmd, from: argp, n: sizeof(struct pkt_ctrl_command))) |
2809 | return -EFAULT; |
2810 | |
2811 | switch (ctrl_cmd.command) { |
2812 | case PKT_CTRL_CMD_SETUP: |
2813 | if (!capable(CAP_SYS_ADMIN)) |
2814 | return -EPERM; |
2815 | ret = pkt_setup_dev(dev: new_decode_dev(dev: ctrl_cmd.dev), pkt_dev: &pkt_dev); |
2816 | ctrl_cmd.pkt_dev = new_encode_dev(dev: pkt_dev); |
2817 | break; |
2818 | case PKT_CTRL_CMD_TEARDOWN: |
2819 | if (!capable(CAP_SYS_ADMIN)) |
2820 | return -EPERM; |
2821 | ret = pkt_remove_dev(pkt_dev: new_decode_dev(dev: ctrl_cmd.pkt_dev)); |
2822 | break; |
2823 | case PKT_CTRL_CMD_STATUS: |
2824 | pkt_get_status(ctrl_cmd: &ctrl_cmd); |
2825 | break; |
2826 | default: |
2827 | return -ENOTTY; |
2828 | } |
2829 | |
2830 | if (copy_to_user(to: argp, from: &ctrl_cmd, n: sizeof(struct pkt_ctrl_command))) |
2831 | return -EFAULT; |
2832 | return ret; |
2833 | } |
2834 | |
2835 | #ifdef CONFIG_COMPAT |
2836 | static long pkt_ctl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2837 | { |
2838 | return pkt_ctl_ioctl(file, cmd, arg: (unsigned long)compat_ptr(uptr: arg)); |
2839 | } |
2840 | #endif |
2841 | |
2842 | static const struct file_operations pkt_ctl_fops = { |
2843 | .open = nonseekable_open, |
2844 | .unlocked_ioctl = pkt_ctl_ioctl, |
2845 | #ifdef CONFIG_COMPAT |
2846 | .compat_ioctl = pkt_ctl_compat_ioctl, |
2847 | #endif |
2848 | .owner = THIS_MODULE, |
2849 | .llseek = no_llseek, |
2850 | }; |
2851 | |
2852 | static struct miscdevice pkt_misc = { |
2853 | .minor = MISC_DYNAMIC_MINOR, |
2854 | .name = DRIVER_NAME, |
2855 | .nodename = "pktcdvd/control" , |
2856 | .fops = &pkt_ctl_fops |
2857 | }; |
2858 | |
2859 | static int __init pkt_init(void) |
2860 | { |
2861 | int ret; |
2862 | |
2863 | mutex_init(&ctl_mutex); |
2864 | |
2865 | ret = mempool_init_kmalloc_pool(pool: &psd_pool, PSD_POOL_SIZE, |
2866 | size: sizeof(struct packet_stacked_data)); |
2867 | if (ret) |
2868 | return ret; |
2869 | ret = bioset_init(&pkt_bio_set, BIO_POOL_SIZE, 0, flags: 0); |
2870 | if (ret) { |
2871 | mempool_exit(pool: &psd_pool); |
2872 | return ret; |
2873 | } |
2874 | |
2875 | ret = register_blkdev(pktdev_major, DRIVER_NAME); |
2876 | if (ret < 0) { |
2877 | pr_err("unable to register block device\n" ); |
2878 | goto out2; |
2879 | } |
2880 | if (!pktdev_major) |
2881 | pktdev_major = ret; |
2882 | |
2883 | ret = pkt_sysfs_init(); |
2884 | if (ret) |
2885 | goto out; |
2886 | |
2887 | pkt_debugfs_init(); |
2888 | |
2889 | ret = misc_register(misc: &pkt_misc); |
2890 | if (ret) { |
2891 | pr_err("unable to register misc device\n" ); |
2892 | goto out_misc; |
2893 | } |
2894 | |
2895 | pkt_proc = proc_mkdir("driver/" DRIVER_NAME, NULL); |
2896 | |
2897 | return 0; |
2898 | |
2899 | out_misc: |
2900 | pkt_debugfs_cleanup(); |
2901 | pkt_sysfs_cleanup(); |
2902 | out: |
2903 | unregister_blkdev(major: pktdev_major, DRIVER_NAME); |
2904 | out2: |
2905 | mempool_exit(pool: &psd_pool); |
2906 | bioset_exit(&pkt_bio_set); |
2907 | return ret; |
2908 | } |
2909 | |
2910 | static void __exit pkt_exit(void) |
2911 | { |
2912 | remove_proc_entry("driver/" DRIVER_NAME, NULL); |
2913 | misc_deregister(misc: &pkt_misc); |
2914 | |
2915 | pkt_debugfs_cleanup(); |
2916 | pkt_sysfs_cleanup(); |
2917 | |
2918 | unregister_blkdev(major: pktdev_major, DRIVER_NAME); |
2919 | mempool_exit(pool: &psd_pool); |
2920 | bioset_exit(&pkt_bio_set); |
2921 | } |
2922 | |
2923 | MODULE_DESCRIPTION("Packet writing layer for CD/DVD drives" ); |
2924 | MODULE_AUTHOR("Jens Axboe <axboe@suse.de>" ); |
2925 | MODULE_LICENSE("GPL" ); |
2926 | |
2927 | module_init(pkt_init); |
2928 | module_exit(pkt_exit); |
2929 | |