diff --git a/debian/changelog b/debian/changelog index 37d5af34e..5149f7afd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -53,7 +53,12 @@ linux-2.6 (2.6.13-1) UNRELEASED; urgency=low * add m68k-42_dma.patch and m68k-sonic.patch that will be in upstream 2.6.14 (which makes sun3 build fail, needs fixing) - -- Bastian Blank Wed, 14 Sep 2005 10:02:21 +0000 + [ maximilian attems ] + * Drop drivers-add-scsi_changer.patch (merged) + * Drop drivers-ide-dma-blacklist-toshiba.patch (merged) + * Drop drivers-ide-__devinit.patch (merged) + + -- maximilian attems Wed, 14 Sep 2005 11:45:23 +0200 linux-2.6 (2.6.12-6) unstable; urgency=high diff --git a/debian/patches-debian/drivers-add-scsi_changer.patch b/debian/patches-debian/drivers-add-scsi_changer.patch deleted file mode 100644 index 5786a219c..000000000 --- a/debian/patches-debian/drivers-add-scsi_changer.patch +++ /dev/null @@ -1,1482 +0,0 @@ -From: Gerd Knorr - -This patch adds a device driver for scsi media changer devices (tape -libraries for example). - -It exists for quite some time (since 2.2.x or so ...), is used by several -people and also is in some vendor kernels (debian, suse, maybe others as -well). People bug be from time to time to submit it ;) - -Recently I went over it and did some 2.6 cleanups, module parameters and -the like. And now, finally, here it is. - -Signed-off-by: Gerd Knorr -Signed-off-by: Andrew Morton ---- - - 25-akpm/Documentation/scsi-changer.txt | 180 +++++ - 25-akpm/drivers/scsi/Kconfig | 18 - 25-akpm/drivers/scsi/Makefile | 1 - 25-akpm/drivers/scsi/ch.c | 1020 +++++++++++++++++++++++++++++++++ - 25-akpm/include/linux/chio.h | 168 +++++ - 25-akpm/include/linux/major.h | 1 - 25-akpm/include/scsi/scsi.h | 3 - 7 files changed, 1391 insertions(+) - -diff -aurN a/Documentation/scsi-changer.txt b/Documentation/scsi-changer.txt ---- a/Documentation/scsi-changer.txt 1969-12-31 19:00:00.000000000 -0500 -+++ b/Documentation/scsi-changer.txt 2005-06-15 22:00:21.000000000 -0400 -@@ -0,0 +1,180 @@ -+ -+README for the SCSI media changer driver -+======================================== -+ -+This is a driver for SCSI Medium Changer devices, which are listed -+with "Type: Medium Changer" in /proc/scsi/scsi. -+ -+This is for *real* Jukeboxes. It is *not* supported to work with -+common small CD-ROM changers, neither one-lun-per-slot SCSI changers -+nor IDE drives. -+ -+Userland tools available from here: -+ http://linux.bytesex.org/misc/changer.html -+ -+ -+General Information -+------------------- -+ -+First some words about how changers work: A changer has 2 (possibly -+more) SCSI ID's. One for the changer device which controls the robot, -+and one for the device which actually reads and writes the data. The -+later may be anything, a MOD, a CD-ROM, a tape or whatever. For the -+changer device this is a "don't care", he *only* shuffles around the -+media, nothing else. -+ -+ -+The SCSI changer model is complex, compared to - for example - IDE-CD -+changers. But it allows to handle nearly all possible cases. It knows -+4 different types of changer elements: -+ -+ media transport - this one shuffles around the media, i.e. the -+ transport arm. Also known as "picker". -+ storage - a slot which can hold a media. -+ import/export - the same as above, but is accessable from outside, -+ i.e. there the operator (you !) can use this to -+ fill in and remove media from the changer. -+ Sometimes named "mailslot". -+ data transfer - this is the device which reads/writes, i.e. the -+ CD-ROM / Tape / whatever drive. -+ -+None of these is limited to one: A huge Jukebox could have slots for -+123 CD-ROM's, 5 CD-ROM readers (and therefore 6 SCSI ID's: the changer -+and each CD-ROM) and 2 transport arms. No problem to handle. -+ -+ -+How it is implemented -+--------------------- -+ -+I implemented the driver as character device driver with a NetBSD-like -+ioctl interface. Just grabbed NetBSD's header file and one of the -+other linux SCSI device drivers as starting point. The interface -+should be source code compatible with NetBSD. So if there is any -+software (anybody knows ???) which supports a BSDish changer driver, -+it should work with this driver too. -+ -+Over time a few more ioctls where added, volume tag support for example -+wasn't covered by the NetBSD ioctl API. -+ -+ -+Current State -+------------- -+ -+Support for more than one transport arm is not implemented yet (and -+nobody asked for it so far...). -+ -+I test and use the driver myself with a 35 slot cdrom jukebox from -+Grundig. I got some reports telling it works ok with tape autoloaders -+(Exabyte, HP and DEC). Some People use this driver with amanda. It -+works fine with small (11 slots) and a huge (4 MOs, 88 slots) -+magneto-optical Jukebox. Probably with lots of other changers too, most -+(but not all :-) people mail me only if it does *not* work... -+ -+I don't have any device lists, neither black-list nor white-list. Thus -+it is quite useless to ask me whenever a specific device is supported or -+not. In theory every changer device which supports the SCSI-2 media -+changer command set should work out-of-the-box with this driver. If it -+doesn't, it is a bug. Either within the driver or within the firmware -+of the changer device. -+ -+ -+Using it -+-------- -+ -+This is a character device with major number is 86, so use -+"mknod /dev/sch0 c 86 0" to create the special file for the driver. -+ -+If the module finds the changer, it prints some messages about the -+device [ try "dmesg" if you don't see anything ] and should show up in -+/proc/devices. If not.... some changers use ID ? / LUN 0 for the -+device and ID ? / LUN 1 for the robot mechanism. But Linux does *not* -+look for LUN's other than 0 as default, becauce there are to many -+broken devices. So you can try: -+ -+ 1) echo "scsi add-single-device 0 0 ID 1" > /proc/scsi/scsi -+ (replace ID with the SCSI-ID of the device) -+ 2) boot the kernel with "max_scsi_luns=1" on the command line -+ (append="max_scsi_luns=1" in lilo.conf should do the trick) -+ -+ -+Trouble? -+-------- -+ -+If you insmod the driver with "insmod debug=1", it will be verbose and -+prints a lot of stuff to the syslog. Compiling the kernel with -+CONFIG_SCSI_CONSTANTS=y improves the quality of the error messages alot -+because the kernel will translate the error codes into human-readable -+strings then. -+ -+You can display these messages with the dmesg command (or check the -+logfiles). If you email me some question becauce of a problem with the -+driver, please include these messages. -+ -+ -+Insmod options -+-------------- -+ -+debug=0/1 -+ Enable debug messages (see above, default: 0). -+ -+verbose=0/1 -+ Be verbose (default: 1). -+ -+init=0/1 -+ Send INITIALIZE ELEMENT STATUS command to the changer -+ at insmod time (default: 1). -+ -+timeout_init= -+ timeout for the INITIALIZE ELEMENT STATUS command -+ (default: 3600). -+ -+timeout_move= -+ timeout for all other commands (default: 120). -+ -+dt_id=,,... -+dt_lun=,,... -+ These two allow to specify the SCSI ID and LUN for the data -+ transfer elements. You likely don't need this as the jukebox -+ should provide this information. But some devices don't ... -+ -+vendor_firsts= -+vendor_counts= -+vendor_labels= -+ These insmod options can be used to tell the driver that there -+ are some vendor-specific element types. Grundig for example -+ does this. Some jukeboxes have a printer to label fresh burned -+ CDs, which is addressed as element 0xc000 (type 5). To tell the -+ driver about this vendor-specific element, use this: -+ $ insmod ch \ -+ vendor_firsts=0xc000 \ -+ vendor_counts=1 \ -+ vendor_labels=printer -+ All three insmod options accept up to four comma-separated -+ values, this way you can configure the element types 5-8. -+ You likely need the SCSI specs for the device in question to -+ find the correct values as they are not covered by the SCSI-2 -+ standard. -+ -+ -+Credits -+------- -+ -+I wrote this driver using the famous mailing-patches-around-the-world -+method. With (more or less) help from: -+ -+ Daniel Moehwald -+ Dane Jasper -+ R. Scott Bailey -+ Jonathan Corbet -+ -+Special thanks go to -+ Martin Kuehne -+for a old, second-hand (but full functional) cdrom jukebox which I use -+to develop/test driver and tools now. -+ -+Have fun, -+ -+ Gerd -+ -+-- -+Gerd Knorr -diff -aurN a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig ---- a/drivers/scsi/Kconfig 2005-06-06 11:22:29.000000000 -0400 -+++ b/drivers/scsi/Kconfig 2005-06-15 22:00:21.000000000 -0400 -@@ -137,6 +137,24 @@ - - If unsure, say N. - -+config CHR_DEV_SCH -+ tristate "SCSI media changer support" -+ depends on SCSI -+ ---help--- -+ This is a driver for SCSI media changers. Most common devices are -+ tape libraries and MOD/CDROM jukeboxes. *Real* jukeboxes, you -+ don't need this for those tiny 6-slot cdrom changers. Media -+ changers are listed as "Type: Medium Changer" in /proc/scsi/scsi. -+ If you have such hardware and want to use it with linux, say Y -+ here. Check for details. -+ -+ If you want to compile this as a module ( = code which can be -+ inserted in and removed from the running kernel whenever you want), -+ say M here and read and -+ . The module will be called ch.o. -+ If unsure, say N. -+ -+ - comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs" - depends on SCSI - -diff -aurN a/drivers/scsi/Makefile b/drivers/scsi/Makefile ---- a/drivers/scsi/Makefile 2005-06-06 11:22:29.000000000 -0400 -+++ b/drivers/scsi/Makefile 2005-06-15 22:00:21.000000000 -0400 -@@ -142,6 +142,7 @@ - obj-$(CONFIG_BLK_DEV_SD) += sd_mod.o - obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o - obj-$(CONFIG_CHR_DEV_SG) += sg.o -+obj-$(CONFIG_CHR_DEV_SCH) += ch.o - - scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ - scsicam.o scsi_error.o scsi_lib.o \ -diff -aurN a/drivers/scsi/ch.c b/drivers/scsi/ch.c ---- a/drivers/scsi/ch.c 1969-12-31 19:00:00.000000000 -0500 -+++ b/drivers/scsi/ch.c 2005-06-15 22:00:21.000000000 -0400 -@@ -0,0 +1,1020 @@ -+/* -+ * SCSI Media Changer device driver for Linux 2.6 -+ * -+ * (c) 1996-2003 Gerd Knorr -+ * -+ */ -+ -+#define VERSION "0.24" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* here are all the ioctls */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define CH_DT_MAX 16 -+#define CH_TYPES 8 -+ -+MODULE_DESCRIPTION("device driver for scsi media changer devices"); -+MODULE_AUTHOR("Gerd Knorr "); -+MODULE_LICENSE("GPL"); -+ -+static int init = 1; -+module_param(init, int, 0444); -+MODULE_PARM_DESC(init, \ -+ "initialize element status on driver load (default: on)"); -+ -+static int timeout_move = 300; -+module_param(timeout_move, int, 0644); -+MODULE_PARM_DESC(timeout_move,"timeout for move commands " -+ "(default: 300 seconds)"); -+ -+static int timeout_init = 3600; -+module_param(timeout_init, int, 0644); -+MODULE_PARM_DESC(timeout_init,"timeout for INITIALIZE ELEMENT STATUS " -+ "(default: 3600 seconds)"); -+ -+static int verbose = 1; -+module_param(verbose, int, 0644); -+MODULE_PARM_DESC(verbose,"be verbose (default: on)"); -+ -+static int debug = 0; -+module_param(debug, int, 0644); -+MODULE_PARM_DESC(debug,"enable/disable debug messages, also prints more " -+ "detailed sense codes on scsi errors (default: off)"); -+ -+static int dt_id[CH_DT_MAX] = { [ 0 ... (CH_DT_MAX-1) ] = -1 }; -+static int dt_lun[CH_DT_MAX]; -+module_param_array(dt_id, int, NULL, 0444); -+module_param_array(dt_lun, int, NULL, 0444); -+ -+/* tell the driver about vendor-specific slots */ -+static int vendor_firsts[CH_TYPES-4]; -+static int vendor_counts[CH_TYPES-4]; -+module_param_array(vendor_firsts, int, NULL, 0444); -+module_param_array(vendor_counts, int, NULL, 0444); -+ -+static char *vendor_labels[CH_TYPES-4] = { -+ "v0", "v1", "v2", "v3" -+}; -+// module_param_string_array(vendor_labels, NULL, 0444); -+ -+#define dprintk(fmt, arg...) if (debug) \ -+ printk(KERN_DEBUG "%s: " fmt, ch->name, ##arg) -+#define vprintk(fmt, arg...) if (verbose) \ -+ printk(KERN_INFO "%s: " fmt, ch->name, ##arg) -+ -+/* ------------------------------------------------------------------- */ -+ -+#define MAX_RETRIES 1 -+ -+static int ch_probe(struct device *); -+static int ch_remove(struct device *); -+static int ch_open(struct inode * inode, struct file * filp); -+static int ch_release(struct inode * inode, struct file * filp); -+static int ch_ioctl(struct inode * inode, struct file * filp, -+ unsigned int cmd, unsigned long arg); -+static long ch_ioctl_compat(struct file * filp, -+ unsigned int cmd, unsigned long arg); -+ -+typedef struct { -+ struct list_head list; -+ int minor; -+ char name[8]; -+ struct scsi_device *device; -+ struct scsi_device **dt; /* ptrs to data transfer elements */ -+ u_int firsts[CH_TYPES]; -+ u_int counts[CH_TYPES]; -+ u_int unit_attention; -+ u_int voltags; -+ struct semaphore lock; -+} scsi_changer; -+ -+static LIST_HEAD(ch_devlist); -+static spinlock_t ch_devlist_lock = SPIN_LOCK_UNLOCKED; -+static int ch_devcount; -+ -+struct scsi_driver ch_template = -+{ -+ .owner = THIS_MODULE, -+ .gendrv = { -+ .name = "ch", -+ .probe = ch_probe, -+ .remove = ch_remove, -+ }, -+}; -+ -+static struct file_operations changer_fops = -+{ -+ .owner = THIS_MODULE, -+ .open = ch_open, -+ .release = ch_release, -+ .ioctl = ch_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = ch_ioctl_compat, -+#endif -+}; -+ -+static struct { -+ unsigned char sense; -+ unsigned char asc; -+ unsigned char ascq; -+ int errno; -+} err[] = { -+/* Just filled in what looks right. Hav'nt checked any standard paper for -+ these errno assignments, so they may be wrong... */ -+ { -+ .sense = ILLEGAL_REQUEST, -+ .asc = 0x21, -+ .ascq = 0x01, -+ .errno = EBADSLT, /* Invalid element address */ -+ },{ -+ .sense = ILLEGAL_REQUEST, -+ .asc = 0x28, -+ .ascq = 0x01, -+ .errno = EBADE, /* Import or export element accessed */ -+ },{ -+ .sense = ILLEGAL_REQUEST, -+ .asc = 0x3B, -+ .ascq = 0x0D, -+ .errno = EXFULL, /* Medium destination element full */ -+ },{ -+ .sense = ILLEGAL_REQUEST, -+ .asc = 0x3B, -+ .ascq = 0x0E, -+ .errno = EBADE, /* Medium source element empty */ -+ },{ -+ .sense = ILLEGAL_REQUEST, -+ .asc = 0x20, -+ .ascq = 0x00, -+ .errno = EBADRQC, /* Invalid command operation code */ -+ },{ -+ /* end of list */ -+ } -+}; -+ -+/* ------------------------------------------------------------------- */ -+ -+static int ch_find_errno(unsigned char *sense_buffer) -+{ -+ int i,errno = 0; -+ -+ /* Check to see if additional sense information is available */ -+ if (sense_buffer[7] > 5 && -+ sense_buffer[12] != 0) { -+ for (i = 0; err[i].errno != 0; i++) { -+ if (err[i].sense == sense_buffer[ 2] && -+ err[i].asc == sense_buffer[12] && -+ err[i].ascq == sense_buffer[13]) { -+ errno = -err[i].errno; -+ break; -+ } -+ } -+ } -+ if (errno == 0) -+ errno = -EIO; -+ return errno; -+} -+ -+static void -+ch_request_done(struct scsi_cmnd *sc) -+{ -+ sc->request->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ -+ if (sc->request->waiting != NULL) -+ complete(sc->request->waiting); -+} -+ -+static int -+ch_do_scsi(scsi_changer *ch, unsigned char *cmd, -+ void *buffer, unsigned buflength) -+{ -+ int errno, retries = 0, timeout; -+ DECLARE_COMPLETION(wait); -+ struct scsi_request *sr; -+ -+ sr = scsi_allocate_request(ch->device, GFP_KERNEL); -+ if (NULL == sr) -+ return -ENOMEM; -+ -+ retry: -+ errno = 0; -+ if (debug) { -+ dprintk("command: "); -+ __scsi_print_command(cmd); -+ } -+ -+ sr->sr_request->waiting = &wait; -+ timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS) -+ ? timeout_init : timeout_move; -+ scsi_do_req(sr, cmd, buffer, buflength, ch_request_done, -+ timeout * HZ, MAX_RETRIES); -+ wait_for_completion(&wait); -+ sr->sr_request->waiting = NULL; -+ -+ dprintk("result: 0x%x\n",sr->sr_result); -+ if (driver_byte(sr->sr_result) != 0) { -+ if (debug) -+ scsi_print_req_sense(ch->name, sr); -+ errno = ch_find_errno(sr->sr_sense_buffer); -+ -+ switch(sr->sr_sense_buffer[2] & 0xf) { -+ case UNIT_ATTENTION: -+ ch->unit_attention = 1; -+ if (retries++ < 3) -+ goto retry; -+ break; -+ } -+ } -+ scsi_release_request(sr); -+ return errno; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int -+ch_elem_to_typecode(scsi_changer *ch, u_int elem) -+{ -+ int i; -+ -+ for (i = 0; i < CH_TYPES; i++) { -+ if (elem >= ch->firsts[i] && -+ elem < ch->firsts[i] + -+ ch->counts[i]) -+ return i+1; -+ } -+ return 0; -+} -+ -+static int -+ch_read_element_status(scsi_changer *ch, u_int elem, char *data) -+{ -+ u_char cmd[12]; -+ u_char *buffer; -+ int result; -+ -+ buffer = kmalloc(512, GFP_KERNEL); -+ if(!buffer) -+ return -ENOMEM; -+ -+ retry: -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = READ_ELEMENT_STATUS; -+ cmd[1] = (ch->device->lun << 5) | -+ (ch->voltags ? 0x10 : 0) | -+ ch_elem_to_typecode(ch,elem); -+ cmd[2] = (elem >> 8) & 0xff; -+ cmd[3] = elem & 0xff; -+ cmd[5] = 1; -+ cmd[9] = 255; -+ if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256))) { -+ if (((buffer[16] << 8) | buffer[17]) != elem) { -+ dprintk("asked for element 0x%02x, got 0x%02x\n", -+ elem,(buffer[16] << 8) | buffer[17]); -+ kfree(buffer); -+ return -EIO; -+ } -+ memcpy(data,buffer+16,16); -+ } else { -+ if (ch->voltags) { -+ ch->voltags = 0; -+ vprintk("device has no volume tag support%s\n",""); -+ goto retry; -+ } -+ dprintk("READ ELEMENT STATUS for element 0x%x failed\n",elem); -+ } -+ kfree(buffer); -+ return result; -+} -+ -+static int -+ch_init_elem(scsi_changer *ch) -+{ -+ int err; -+ u_char cmd[6]; -+ -+ vprintk("INITIALIZE ELEMENT STATUS, may take some time ...%s\n",""); -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = INITIALIZE_ELEMENT_STATUS; -+ cmd[1] = ch->device->lun << 5; -+ err = ch_do_scsi(ch, cmd, NULL, 0); -+ vprintk("... finished%s\n",""); -+ return err; -+} -+ -+static int -+ch_readconfig(scsi_changer *ch) -+{ -+ u_char cmd[10], data[16]; -+ u_char *buffer; -+ int result,id,lun,i; -+ u_int elem; -+ -+ buffer = kmalloc(512, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ memset(buffer,0,512); -+ -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = MODE_SENSE; -+ cmd[1] = ch->device->lun << 5; -+ cmd[2] = 0x1d; -+ cmd[4] = 255; -+ result = ch_do_scsi(ch, cmd, buffer, 255); -+ if (0 != result) { -+ cmd[1] |= (1<<3); -+ result = ch_do_scsi(ch, cmd, buffer, 255); -+ } -+ if (0 == result) { -+ ch->firsts[CHET_MT] = -+ (buffer[buffer[3]+ 6] << 8) | buffer[buffer[3]+ 7]; -+ ch->counts[CHET_MT] = -+ (buffer[buffer[3]+ 8] << 8) | buffer[buffer[3]+ 9]; -+ ch->firsts[CHET_ST] = -+ (buffer[buffer[3]+10] << 8) | buffer[buffer[3]+11]; -+ ch->counts[CHET_ST] = -+ (buffer[buffer[3]+12] << 8) | buffer[buffer[3]+13]; -+ ch->firsts[CHET_IE] = -+ (buffer[buffer[3]+14] << 8) | buffer[buffer[3]+15]; -+ ch->counts[CHET_IE] = -+ (buffer[buffer[3]+16] << 8) | buffer[buffer[3]+17]; -+ ch->firsts[CHET_DT] = -+ (buffer[buffer[3]+18] << 8) | buffer[buffer[3]+19]; -+ ch->counts[CHET_DT] = -+ (buffer[buffer[3]+20] << 8) | buffer[buffer[3]+21]; -+ vprintk("type #1 (mt): 0x%x+%d [medium transport]\n", -+ ch->firsts[CHET_MT], -+ ch->counts[CHET_MT]); -+ vprintk("type #2 (st): 0x%x+%d [storage]\n", -+ ch->firsts[CHET_ST], -+ ch->counts[CHET_ST]); -+ vprintk("type #3 (ie): 0x%x+%d [import/export]\n", -+ ch->firsts[CHET_IE], -+ ch->counts[CHET_IE]); -+ vprintk("type #4 (dt): 0x%x+%d [data transfer]\n", -+ ch->firsts[CHET_DT], -+ ch->counts[CHET_DT]); -+ } else { -+ vprintk("reading element address assigment page failed!%s\n", -+ ""); -+ } -+ -+ /* vendor specific element types */ -+ for (i = 0; i < 4; i++) { -+ if (0 == vendor_counts[i]) -+ continue; -+ if (NULL == vendor_labels[i]) -+ continue; -+ ch->firsts[CHET_V1+i] = vendor_firsts[i]; -+ ch->counts[CHET_V1+i] = vendor_counts[i]; -+ vprintk("type #%d (v%d): 0x%x+%d [%s, vendor specific]\n", -+ i+5,i+1,vendor_firsts[i],vendor_counts[i], -+ vendor_labels[i]); -+ } -+ -+ /* look up the devices of the data transfer elements */ -+ ch->dt = kmalloc(ch->counts[CHET_DT]*sizeof(struct scsi_device), -+ GFP_KERNEL); -+ for (elem = 0; elem < ch->counts[CHET_DT]; elem++) { -+ id = -1; -+ lun = 0; -+ if (-1 != dt_id[elem]) { -+ id = dt_id[elem]; -+ lun = dt_lun[elem]; -+ vprintk("dt 0x%x: [insmod option] ", -+ elem+ch->firsts[CHET_DT]); -+ } else if (0 != ch_read_element_status -+ (ch,elem+ch->firsts[CHET_DT],data)) { -+ vprintk("dt 0x%x: READ ELEMENT STATUS failed\n", -+ elem+ch->firsts[CHET_DT]); -+ } else { -+ vprintk("dt 0x%x: ",elem+ch->firsts[CHET_DT]); -+ if (data[6] & 0x80) { -+ if (verbose) -+ printk("not this SCSI bus\n"); -+ ch->dt[elem] = NULL; -+ } else if (0 == (data[6] & 0x30)) { -+ if (verbose) -+ printk("ID/LUN unknown\n"); -+ ch->dt[elem] = NULL; -+ } else { -+ id = ch->device->id; -+ lun = 0; -+ if (data[6] & 0x20) id = data[7]; -+ if (data[6] & 0x10) lun = data[6] & 7; -+ } -+ } -+ if (-1 != id) { -+ if (verbose) -+ printk("ID %i, LUN %i, ",id,lun); -+ ch->dt[elem] = -+ scsi_device_lookup(ch->device->host, -+ ch->device->channel, -+ id,lun); -+ if (!ch->dt[elem]) { -+ /* should not happen */ -+ if (verbose) -+ printk("Huh? device not found!\n"); -+ } else { -+ if (verbose) -+ printk("name: %8.8s %16.16s %4.4s\n", -+ ch->dt[elem]->vendor, -+ ch->dt[elem]->model, -+ ch->dt[elem]->rev); -+ } -+ } -+ } -+ ch->voltags = 1; -+ kfree(buffer); -+ -+ return 0; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int -+ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate) -+{ -+ u_char cmd[10]; -+ -+ dprintk("position: 0x%x\n",elem); -+ if (0 == trans) -+ trans = ch->firsts[CHET_MT]; -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = POSITION_TO_ELEMENT; -+ cmd[1] = ch->device->lun << 5; -+ cmd[2] = (trans >> 8) & 0xff; -+ cmd[3] = trans & 0xff; -+ cmd[4] = (elem >> 8) & 0xff; -+ cmd[5] = elem & 0xff; -+ cmd[8] = rotate ? 1 : 0; -+ return ch_do_scsi(ch, cmd, NULL,0); -+} -+ -+static int -+ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate) -+{ -+ u_char cmd[12]; -+ -+ dprintk("move: 0x%x => 0x%x\n",src,dest); -+ if (0 == trans) -+ trans = ch->firsts[CHET_MT]; -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = MOVE_MEDIUM; -+ cmd[1] = ch->device->lun << 5; -+ cmd[2] = (trans >> 8) & 0xff; -+ cmd[3] = trans & 0xff; -+ cmd[4] = (src >> 8) & 0xff; -+ cmd[5] = src & 0xff; -+ cmd[6] = (dest >> 8) & 0xff; -+ cmd[7] = dest & 0xff; -+ cmd[10] = rotate ? 1 : 0; -+ return ch_do_scsi(ch, cmd, NULL,0); -+} -+ -+static int -+ch_exchange(scsi_changer *ch, u_int trans, u_int src, -+ u_int dest1, u_int dest2, int rotate1, int rotate2) -+{ -+ u_char cmd[12]; -+ -+ dprintk("exchange: 0x%x => 0x%x => 0x%x\n", -+ src,dest1,dest2); -+ if (0 == trans) -+ trans = ch->firsts[CHET_MT]; -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = EXCHANGE_MEDIUM; -+ cmd[1] = ch->device->lun << 5; -+ cmd[2] = (trans >> 8) & 0xff; -+ cmd[3] = trans & 0xff; -+ cmd[4] = (src >> 8) & 0xff; -+ cmd[5] = src & 0xff; -+ cmd[6] = (dest1 >> 8) & 0xff; -+ cmd[7] = dest1 & 0xff; -+ cmd[8] = (dest2 >> 8) & 0xff; -+ cmd[9] = dest2 & 0xff; -+ cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0); -+ -+ return ch_do_scsi(ch, cmd, NULL,0); -+} -+ -+static void -+ch_check_voltag(char *tag) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ /* restrict to ascii */ -+ if (tag[i] >= 0x7f || tag[i] < 0x20) -+ tag[i] = ' '; -+ /* don't allow search wildcards */ -+ if (tag[i] == '?' || -+ tag[i] == '*') -+ tag[i] = ' '; -+ } -+} -+ -+static int -+ch_set_voltag(scsi_changer *ch, u_int elem, -+ int alternate, int clear, u_char *tag) -+{ -+ u_char cmd[12]; -+ u_char *buffer; -+ int result; -+ -+ buffer = kmalloc(512, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ memset(buffer,0,512); -+ -+ dprintk("%s %s voltag: 0x%x => \"%s\"\n", -+ clear ? "clear" : "set", -+ alternate ? "alternate" : "primary", -+ elem, tag); -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = SEND_VOLUME_TAG; -+ cmd[1] = (ch->device->lun << 5) | -+ ch_elem_to_typecode(ch,elem); -+ cmd[2] = (elem >> 8) & 0xff; -+ cmd[3] = elem & 0xff; -+ cmd[5] = clear -+ ? (alternate ? 0x0d : 0x0c) -+ : (alternate ? 0x0b : 0x0a); -+ -+ cmd[9] = 255; -+ -+ memcpy(buffer,tag,32); -+ ch_check_voltag(buffer); -+ -+ result = ch_do_scsi(ch, cmd, buffer, 256); -+ kfree(buffer); -+ return result; -+} -+ -+static int ch_gstatus(scsi_changer *ch, int type, unsigned char *dest) -+{ -+ int retval = 0; -+ u_char data[16]; -+ unsigned int i; -+ -+ down(&ch->lock); -+ for (i = 0; i < ch->counts[type]; i++) { -+ if (0 != ch_read_element_status -+ (ch, ch->firsts[type]+i,data)) { -+ retval = -EIO; -+ break; -+ } -+ put_user(data[2], dest+i); -+ if (data[2] & CESTATUS_EXCEPT) -+ vprintk("element 0x%x: asc=0x%x, ascq=0x%x\n", -+ ch->firsts[type]+i, -+ (int)data[4],(int)data[5]); -+ retval = ch_read_element_status -+ (ch, ch->firsts[type]+i,data); -+ if (0 != retval) -+ break; -+ } -+ up(&ch->lock); -+ return retval; -+} -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int -+ch_release(struct inode *inode, struct file *file) -+{ -+ scsi_changer *ch = file->private_data; -+ -+ scsi_device_put(ch->device); -+ file->private_data = NULL; -+ return 0; -+} -+ -+static int -+ch_open(struct inode *inode, struct file *file) -+{ -+ scsi_changer *tmp, *ch; -+ int minor = iminor(inode); -+ -+ spin_lock(&ch_devlist_lock); -+ ch = NULL; -+ list_for_each_entry(tmp,&ch_devlist,list) { -+ if (tmp->minor == minor) -+ ch = tmp; -+ } -+ if (NULL == ch || scsi_device_get(ch->device)) { -+ spin_unlock(&ch_devlist_lock); -+ return -ENXIO; -+ } -+ spin_unlock(&ch_devlist_lock); -+ -+ file->private_data = ch; -+ return 0; -+} -+ -+static int -+ch_checkrange(scsi_changer *ch, unsigned int type, unsigned int unit) -+{ -+ if (type >= CH_TYPES || unit >= ch->counts[type]) -+ return -1; -+ return 0; -+} -+ -+static int ch_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg) -+{ -+ scsi_changer *ch = file->private_data; -+ int retval; -+ -+ switch (cmd) { -+ case CHIOGPARAMS: -+ { -+ struct changer_params params; -+ -+ params.cp_curpicker = 0; -+ params.cp_npickers = ch->counts[CHET_MT]; -+ params.cp_nslots = ch->counts[CHET_ST]; -+ params.cp_nportals = ch->counts[CHET_IE]; -+ params.cp_ndrives = ch->counts[CHET_DT]; -+ -+ if (copy_to_user((void *) arg, ¶ms, sizeof(params))) -+ return -EFAULT; -+ return 0; -+ } -+ case CHIOGVPARAMS: -+ { -+ struct changer_vendor_params vparams; -+ -+ memset(&vparams,0,sizeof(vparams)); -+ if (ch->counts[CHET_V1]) { -+ vparams.cvp_n1 = ch->counts[CHET_V1]; -+ strncpy(vparams.cvp_label1,vendor_labels[0],16); -+ } -+ if (ch->counts[CHET_V2]) { -+ vparams.cvp_n2 = ch->counts[CHET_V2]; -+ strncpy(vparams.cvp_label2,vendor_labels[1],16); -+ } -+ if (ch->counts[CHET_V3]) { -+ vparams.cvp_n3 = ch->counts[CHET_V3]; -+ strncpy(vparams.cvp_label3,vendor_labels[2],16); -+ } -+ if (ch->counts[CHET_V4]) { -+ vparams.cvp_n4 = ch->counts[CHET_V4]; -+ strncpy(vparams.cvp_label4,vendor_labels[3],16); -+ } -+ if (copy_to_user((void *) arg, &vparams, sizeof(vparams))) -+ return -EFAULT; -+ return 0; -+ } -+ -+ case CHIOPOSITION: -+ { -+ struct changer_position pos; -+ -+ if (copy_from_user(&pos, (void*)arg, sizeof (pos))) -+ return -EFAULT; -+ -+ if (0 != ch_checkrange(ch, pos.cp_type, pos.cp_unit)) { -+ dprintk("CHIOPOSITION: invalid parameter%s\n",""); -+ return -EBADSLT; -+ } -+ down(&ch->lock); -+ retval = ch_position(ch,0, -+ ch->firsts[pos.cp_type] + pos.cp_unit, -+ pos.cp_flags & CP_INVERT); -+ up(&ch->lock); -+ return retval; -+ } -+ -+ case CHIOMOVE: -+ { -+ struct changer_move mv; -+ -+ if (copy_from_user(&mv, (void*)arg, sizeof (mv))) -+ return -EFAULT; -+ -+ if (0 != ch_checkrange(ch, mv.cm_fromtype, mv.cm_fromunit) || -+ 0 != ch_checkrange(ch, mv.cm_totype, mv.cm_tounit )) { -+ dprintk("CHIOMOVE: invalid parameter%s\n",""); -+ return -EBADSLT; -+ } -+ -+ down(&ch->lock); -+ retval = ch_move(ch,0, -+ ch->firsts[mv.cm_fromtype] + mv.cm_fromunit, -+ ch->firsts[mv.cm_totype] + mv.cm_tounit, -+ mv.cm_flags & CM_INVERT); -+ up(&ch->lock); -+ return retval; -+ } -+ -+ case CHIOEXCHANGE: -+ { -+ struct changer_exchange mv; -+ -+ if (copy_from_user(&mv, (void*)arg, sizeof (mv))) -+ return -EFAULT; -+ -+ if (0 != ch_checkrange(ch, mv.ce_srctype, mv.ce_srcunit ) || -+ 0 != ch_checkrange(ch, mv.ce_fdsttype, mv.ce_fdstunit) || -+ 0 != ch_checkrange(ch, mv.ce_sdsttype, mv.ce_sdstunit)) { -+ dprintk("CHIOEXCHANGE: invalid parameter%s\n",""); -+ return -EBADSLT; -+ } -+ -+ down(&ch->lock); -+ retval = ch_exchange -+ (ch,0, -+ ch->firsts[mv.ce_srctype] + mv.ce_srcunit, -+ ch->firsts[mv.ce_fdsttype] + mv.ce_fdstunit, -+ ch->firsts[mv.ce_sdsttype] + mv.ce_sdstunit, -+ mv.ce_flags & CE_INVERT1, mv.ce_flags & CE_INVERT2); -+ up(&ch->lock); -+ return retval; -+ } -+ -+ case CHIOGSTATUS: -+ { -+ struct changer_element_status ces; -+ -+ if (copy_from_user(&ces, (void*)arg, sizeof (ces))) -+ return -EFAULT; -+ if (ces.ces_type < 0 || ces.ces_type >= CH_TYPES) -+ return -EINVAL; -+ -+ return ch_gstatus(ch, ces.ces_type, ces.ces_data); -+ } -+ -+ case CHIOGELEM: -+ { -+ struct changer_get_element cge; -+ u_char cmd[12]; -+ u_char *buffer; -+ unsigned int elem; -+ int result,i; -+ -+ if (copy_from_user(&cge, (void*)arg, sizeof (cge))) -+ return -EFAULT; -+ -+ if (0 != ch_checkrange(ch, cge.cge_type, cge.cge_unit)) -+ return -EINVAL; -+ elem = ch->firsts[cge.cge_type] + cge.cge_unit; -+ -+ buffer = kmalloc(512, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ down(&ch->lock); -+ -+ voltag_retry: -+ memset(cmd,0,sizeof(cmd)); -+ cmd[0] = READ_ELEMENT_STATUS; -+ cmd[1] = (ch->device->lun << 5) | -+ (ch->voltags ? 0x10 : 0) | -+ ch_elem_to_typecode(ch,elem); -+ cmd[2] = (elem >> 8) & 0xff; -+ cmd[3] = elem & 0xff; -+ cmd[5] = 1; -+ cmd[9] = 255; -+ -+ if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256))) { -+ cge.cge_status = buffer[18]; -+ cge.cge_flags = 0; -+ if (buffer[18] & CESTATUS_EXCEPT) { -+ /* FIXME: fill cge_errno */ -+ } -+ if (buffer[25] & 0x80) { -+ cge.cge_flags |= CGE_SRC; -+ if (buffer[25] & 0x40) -+ cge.cge_flags |= CGE_INVERT; -+ elem = (buffer[26]<<8) | buffer[27]; -+ for (i = 0; i < 4; i++) { -+ if (elem >= ch->firsts[i] && -+ elem < ch->firsts[i] + ch->counts[i]) { -+ cge.cge_srctype = i; -+ cge.cge_srcunit = elem-ch->firsts[i]; -+ } -+ } -+ } -+ if ((buffer[22] & 0x30) == 0x30) { -+ cge.cge_flags |= CGE_IDLUN; -+ cge.cge_id = buffer[23]; -+ cge.cge_lun = buffer[22] & 7; -+ } -+ if (buffer[9] & 0x80) { -+ cge.cge_flags |= CGE_PVOLTAG; -+ memcpy(cge.cge_pvoltag,buffer+28,36); -+ } -+ if (buffer[9] & 0x40) { -+ cge.cge_flags |= CGE_AVOLTAG; -+ memcpy(cge.cge_avoltag,buffer+64,36); -+ } -+ } else if (ch->voltags) { -+ ch->voltags = 0; -+ vprintk("device has no volume tag support%s\n",""); -+ goto voltag_retry; -+ } -+ kfree(buffer); -+ up(&ch->lock); -+ -+ if (copy_to_user((void*)arg, &cge, sizeof (cge))) -+ return -EFAULT; -+ return result; -+ } -+ -+ case CHIOINITELEM: -+ { -+ down(&ch->lock); -+ retval = ch_init_elem(ch); -+ up(&ch->lock); -+ return retval; -+ } -+ -+ case CHIOSVOLTAG: -+ { -+ struct changer_set_voltag csv; -+ int elem; -+ -+ if (copy_from_user(&csv, (void*)arg, sizeof(csv))) -+ return -EFAULT; -+ -+ if (0 != ch_checkrange(ch, csv.csv_type, csv.csv_unit)) { -+ dprintk("CHIOSVOLTAG: invalid parameter%s\n",""); -+ return -EBADSLT; -+ } -+ elem = ch->firsts[csv.csv_type] + csv.csv_unit; -+ down(&ch->lock); -+ retval = ch_set_voltag(ch, elem, -+ csv.csv_flags & CSV_AVOLTAG, -+ csv.csv_flags & CSV_CLEARTAG, -+ csv.csv_voltag); -+ up(&ch->lock); -+ return retval; -+ } -+ -+ default: -+ return scsi_ioctl(ch->device, cmd, (void*)arg); -+ -+ } -+} -+ -+#ifdef CONFIG_COMPAT -+ -+struct changer_element_status32 { -+ int ces_type; -+ compat_uptr_t ces_data; -+}; -+#define CHIOGSTATUS32 _IOW('c', 8,struct changer_element_status32) -+ -+static long ch_ioctl_compat(struct file * file, -+ unsigned int cmd, unsigned long arg) -+{ -+ scsi_changer *ch = file->private_data; -+ -+ switch (cmd) { -+ case CHIOGPARAMS: -+ case CHIOGVPARAMS: -+ case CHIOPOSITION: -+ case CHIOMOVE: -+ case CHIOEXCHANGE: -+ case CHIOGELEM: -+ case CHIOINITELEM: -+ case CHIOSVOLTAG: -+ /* compatible */ -+ return ch_ioctl(NULL /* inode, unused */, -+ file, cmd, arg); -+ case CHIOGSTATUS32: -+ { -+ struct changer_element_status32 ces32; -+ unsigned char *data; -+ -+ if (copy_from_user(&ces32, (void*)arg, sizeof (ces32))) -+ return -EFAULT; -+ if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES) -+ return -EINVAL; -+ -+ data = compat_ptr(ces32.ces_data); -+ return ch_gstatus(ch, ces32.ces_type, data); -+ } -+ default: -+ // return scsi_ioctl_compat(ch->device, cmd, (void*)arg); -+ return -ENOIOCTLCMD; -+ -+ } -+} -+#endif -+ -+/* ------------------------------------------------------------------------ */ -+ -+static int ch_probe(struct device *dev) -+{ -+ struct scsi_device *sd = to_scsi_device(dev); -+ scsi_changer *ch; -+ -+ if (sd->type != TYPE_MEDIUM_CHANGER) -+ return -ENODEV; -+ -+ ch = kmalloc(sizeof(*ch), GFP_KERNEL); -+ if (NULL == ch) -+ return -ENOMEM; -+ -+ memset(ch,0,sizeof(*ch)); -+ ch->minor = ch_devcount; -+ sprintf(ch->name,"ch%d",ch->minor); -+ init_MUTEX(&ch->lock); -+ ch->device = sd; -+ ch_readconfig(ch); -+ if (init) -+ ch_init_elem(ch); -+ -+ devfs_mk_cdev(MKDEV(SCSI_CHANGER_MAJOR,ch->minor), -+ S_IFCHR | S_IRUGO | S_IWUGO, ch->name); -+ -+ printk(KERN_INFO "Attached scsi changer %s " -+ "at scsi%d, channel %d, id %d, lun %d\n", -+ ch->name, sd->host->host_no, sd->channel, sd->id, sd->lun); -+ -+ spin_lock(&ch_devlist_lock); -+ list_add_tail(&ch->list,&ch_devlist); -+ ch_devcount++; -+ spin_unlock(&ch_devlist_lock); -+ return 0; -+} -+ -+static int ch_remove(struct device *dev) -+{ -+ struct scsi_device *sd = to_scsi_device(dev); -+ scsi_changer *tmp, *ch; -+ -+ spin_lock(&ch_devlist_lock); -+ ch = NULL; -+ list_for_each_entry(tmp,&ch_devlist,list) { -+ if (tmp->device == sd) -+ ch = tmp; -+ } -+ BUG_ON(NULL == ch); -+ list_del(&ch->list); -+ spin_unlock(&ch_devlist_lock); -+ -+ devfs_remove(ch->name); -+ kfree(ch->dt); -+ kfree(ch); -+ ch_devcount--; -+ return 0; -+} -+ -+static int __init init_ch_module(void) -+{ -+ int rc; -+ -+ printk(KERN_INFO "SCSI Media Changer driver v" VERSION " \n"); -+ rc = register_chrdev(SCSI_CHANGER_MAJOR,"ch",&changer_fops); -+ if (rc < 0) { -+ printk("Unable to get major %d for SCSI-Changer\n", -+ SCSI_CHANGER_MAJOR); -+ return rc; -+ } -+ rc = scsi_register_driver(&ch_template.gendrv); -+ if (rc < 0) -+ goto fail1; -+ return 0; -+ -+ fail1: -+ unregister_chrdev(SCSI_CHANGER_MAJOR, "ch"); -+ return rc; -+} -+ -+static void __exit exit_ch_module(void) -+{ -+ scsi_unregister_driver(&ch_template.gendrv); -+ unregister_chrdev(SCSI_CHANGER_MAJOR, "ch"); -+} -+ -+module_init(init_ch_module); -+module_exit(exit_ch_module); -+ -+/* -+ * Local variables: -+ * c-basic-offset: 8 -+ * End: -+ */ -diff -aurN a/include/linux/chio.h b/include/linux/chio.h ---- a/include/linux/chio.h 1969-12-31 19:00:00.000000000 -0500 -+++ b/include/linux/chio.h 2005-06-15 22:00:21.000000000 -0400 -@@ -0,0 +1,168 @@ -+/* -+ * ioctl interface for the scsi media changer driver -+ */ -+ -+/* changer element types */ -+#define CHET_MT 0 /* media transport element (robot) */ -+#define CHET_ST 1 /* storage element (media slots) */ -+#define CHET_IE 2 /* import/export element */ -+#define CHET_DT 3 /* data transfer element (tape/cdrom/whatever) */ -+#define CHET_V1 4 /* vendor specific #1 */ -+#define CHET_V2 5 /* vendor specific #2 */ -+#define CHET_V3 6 /* vendor specific #3 */ -+#define CHET_V4 7 /* vendor specific #4 */ -+ -+ -+/* -+ * CHIOGPARAMS -+ * query changer properties -+ * -+ * CHIOVGPARAMS -+ * query vendor-specific element types -+ * -+ * accessing elements works by specifing type and unit of the element. -+ * for eample, storage elements are addressed with type = CHET_ST and -+ * unit = 0 .. cp_nslots-1 -+ * -+ */ -+struct changer_params { -+ int cp_curpicker; /* current transport element */ -+ int cp_npickers; /* number of transport elements (CHET_MT) */ -+ int cp_nslots; /* number of storage elements (CHET_ST) */ -+ int cp_nportals; /* number of import/export elements (CHET_IE) */ -+ int cp_ndrives; /* number of data transfer elements (CHET_DT) */ -+}; -+struct changer_vendor_params { -+ int cvp_n1; /* number of vendor specific elems (CHET_V1) */ -+ char cvp_label1[16]; -+ int cvp_n2; /* number of vendor specific elems (CHET_V2) */ -+ char cvp_label2[16]; -+ int cvp_n3; /* number of vendor specific elems (CHET_V3) */ -+ char cvp_label3[16]; -+ int cvp_n4; /* number of vendor specific elems (CHET_V4) */ -+ char cvp_label4[16]; -+ int reserved[8]; -+}; -+ -+ -+/* -+ * CHIOMOVE -+ * move a medium from one element to another -+ */ -+struct changer_move { -+ int cm_fromtype; /* type/unit of source element */ -+ int cm_fromunit; -+ int cm_totype; /* type/unit of destination element */ -+ int cm_tounit; -+ int cm_flags; -+}; -+#define CM_INVERT 1 /* flag: rotate media (for double-sided like MOD) */ -+ -+ -+/* -+ * CHIOEXCHANGE -+ * move one medium from element #1 to element #2, -+ * and another one from element #2 to element #3. -+ * element #1 and #3 are allowed to be identical. -+ */ -+struct changer_exchange { -+ int ce_srctype; /* type/unit of element #1 */ -+ int ce_srcunit; -+ int ce_fdsttype; /* type/unit of element #2 */ -+ int ce_fdstunit; -+ int ce_sdsttype; /* type/unit of element #3 */ -+ int ce_sdstunit; -+ int ce_flags; -+}; -+#define CE_INVERT1 1 -+#define CE_INVERT2 2 -+ -+ -+/* -+ * CHIOPOSITION -+ * move the transport element (robot arm) to a specific element. -+ */ -+struct changer_position { -+ int cp_type; -+ int cp_unit; -+ int cp_flags; -+}; -+#define CP_INVERT 1 -+ -+ -+/* -+ * CHIOGSTATUS -+ * get element status for all elements of a specific type -+ */ -+struct changer_element_status { -+ int ces_type; -+ unsigned char *ces_data; -+}; -+#define CESTATUS_FULL 0x01 /* full */ -+#define CESTATUS_IMPEXP 0x02 /* media was imported (inserted by sysop) */ -+#define CESTATUS_EXCEPT 0x04 /* error condition */ -+#define CESTATUS_ACCESS 0x08 /* access allowed */ -+#define CESTATUS_EXENAB 0x10 /* element can export media */ -+#define CESTATUS_INENAB 0x20 /* element can import media */ -+ -+ -+/* -+ * CHIOGELEM -+ * get more detailed status informtion for a single element -+ */ -+struct changer_get_element { -+ int cge_type; /* type/unit */ -+ int cge_unit; -+ int cge_status; /* status */ -+ int cge_errno; /* errno */ -+ int cge_srctype; /* source element of the last move/exchange */ -+ int cge_srcunit; -+ int cge_id; /* scsi id (for data transfer elements) */ -+ int cge_lun; /* scsi lun (for data transfer elements) */ -+ char cge_pvoltag[36]; /* primary volume tag */ -+ char cge_avoltag[36]; /* alternate volume tag */ -+ int cge_flags; -+}; -+/* flags */ -+#define CGE_ERRNO 0x01 /* errno available */ -+#define CGE_INVERT 0x02 /* media inverted */ -+#define CGE_SRC 0x04 /* media src available */ -+#define CGE_IDLUN 0x08 /* ID+LUN available */ -+#define CGE_PVOLTAG 0x10 /* primary volume tag available */ -+#define CGE_AVOLTAG 0x20 /* alternate volume tag available */ -+ -+ -+/* -+ * CHIOSVOLTAG -+ * set volume tag -+ */ -+struct changer_set_voltag { -+ int csv_type; /* type/unit */ -+ int csv_unit; -+ char csv_voltag[36]; /* volume tag */ -+ int csv_flags; -+}; -+#define CSV_PVOLTAG 0x01 /* primary volume tag */ -+#define CSV_AVOLTAG 0x02 /* alternate volume tag */ -+#define CSV_CLEARTAG 0x04 /* clear volume tag */ -+ -+/* ioctls */ -+#define CHIOMOVE _IOW('c', 1,struct changer_move) -+#define CHIOEXCHANGE _IOW('c', 2,struct changer_exchange) -+#define CHIOPOSITION _IOW('c', 3,struct changer_position) -+#define CHIOGPICKER _IOR('c', 4,int) /* not impl. */ -+#define CHIOSPICKER _IOW('c', 5,int) /* not impl. */ -+#define CHIOGPARAMS _IOR('c', 6,struct changer_params) -+#define CHIOGSTATUS _IOW('c', 8,struct changer_element_status) -+#define CHIOGELEM _IOW('c',16,struct changer_get_element) -+#define CHIOINITELEM _IO('c',17) -+#define CHIOSVOLTAG _IOW('c',18,struct changer_set_voltag) -+#define CHIOGVPARAMS _IOR('c',19,struct changer_vendor_params) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * Local variables: -+ * c-basic-offset: 8 -+ * End: -+ */ -diff -aurN a/include/linux/major.h b/include/linux/major.h ---- a/include/linux/major.h 2005-06-06 11:22:29.000000000 -0400 -+++ b/include/linux/major.h 2005-06-15 22:00:21.000000000 -0400 -@@ -100,6 +100,7 @@ - #define I2O_MAJOR 80 /* 80->87 */ - - #define SHMIQ_MAJOR 85 /* Linux/mips, SGI /dev/shmiq */ -+#define SCSI_CHANGER_MAJOR 86 - - #define IDE6_MAJOR 88 - #define IDE7_MAJOR 89 -diff -aurN a/include/scsi/scsi.h b/include/scsi/scsi.h ---- a/include/scsi/scsi.h 2005-06-06 11:22:29.000000000 -0400 -+++ b/include/scsi/scsi.h 2005-06-15 22:00:21.000000000 -0400 -@@ -41,6 +41,7 @@ - #define FORMAT_UNIT 0x04 - #define READ_BLOCK_LIMITS 0x05 - #define REASSIGN_BLOCKS 0x07 -+#define INITIALIZE_ELEMENT_STATUS 0x07 - #define READ_6 0x08 - #define WRITE_6 0x0a - #define SEEK_6 0x0b -@@ -65,6 +66,7 @@ - #define READ_10 0x28 - #define WRITE_10 0x2a - #define SEEK_10 0x2b -+#define POSITION_TO_ELEMENT 0x2b - #define WRITE_VERIFY 0x2e - #define VERIFY 0x2f - #define SEARCH_HIGH 0x30 -@@ -97,6 +99,7 @@ - #define PERSISTENT_RESERVE_OUT 0x5f - #define REPORT_LUNS 0xa0 - #define MOVE_MEDIUM 0xa5 -+#define EXCHANGE_MEDIUM 0xa6 - #define READ_12 0xa8 - #define WRITE_12 0xaa - #define WRITE_VERIFY_12 0xae diff --git a/debian/patches-debian/drivers-ide-dma-blacklist-toshiba.patch b/debian/patches-debian/drivers-ide-dma-blacklist-toshiba.patch deleted file mode 100644 index 9dbb62229..000000000 --- a/debian/patches-debian/drivers-ide-dma-blacklist-toshiba.patch +++ /dev/null @@ -1,22 +0,0 @@ -#! /bin/sh -e -## .dpatch by -## -## All lines beginning with `## DP:' are a description of the patch. -## DP: Description: blacklist "TOSHIBA CD-ROM XM-1702BC" in drivers/ide/ide-dma.c -## DP: Patch author: Herbert Xu -> #222939 -## see also -> http://lists.debian.org/debian-boot/1999/02/msg00016.html -## DP: Upstream status: submitted - -. $(dirname $0)/DPATCH - -@DPATCH@ ---- kernel-source-2.6.6/drivers/ide/ide-dma.c 2004-04-05 19:49:28.000000000 +1000 -+++ kernel-source-2.6.6-1/drivers/ide/ide-dma.c 2004-04-05 20:54:34.000000000 +1000 -@@ -125,6 +125,7 @@ - { "HITACHI CDR-8335" , "ALL" }, - { "HITACHI CDR-8435" , "ALL" }, - { "Toshiba CD-ROM XM-6202B" , "ALL" }, -+ { "TOSHIBA CD-ROM XM-1702BC" , "ALL" }, - { "CD-532E-A" , "ALL" }, - { "E-IDE CD-ROM CR-840", "ALL" }, - { "CD-ROM Drive/F5A", "ALL" },