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