aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/chio.h168
-rw-r--r--include/linux/major.h1
-rw-r--r--include/scsi/scsi.h4
-rw-r--r--include/scsi/scsi_device.h4
-rw-r--r--include/scsi/scsi_host.h25
-rw-r--r--include/scsi/scsi_transport.h38
7 files changed, 240 insertions, 2 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ef1afc178c0..4a99b76c5a3 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -544,7 +544,7 @@ extern void blk_end_sync_rq(struct request *rq);
extern void blk_attempt_remerge(request_queue_t *, struct request *);
extern void __blk_attempt_remerge(request_queue_t *, struct request *);
extern struct request *blk_get_request(request_queue_t *, int, int);
-extern void blk_insert_request(request_queue_t *, struct request *, int, void *, int);
+extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
extern void blk_requeue_request(request_queue_t *, struct request *);
extern void blk_plug_device(request_queue_t *);
extern int blk_remove_plug(request_queue_t *);
diff --git a/include/linux/chio.h b/include/linux/chio.h
new file mode 100644
index 00000000000..63035ae67e6
--- /dev/null
+++ b/include/linux/chio.h
@@ -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 --git a/include/linux/major.h b/include/linux/major.h
index 4b62c42b842..e36a46702d9 100644
--- a/include/linux/major.h
+++ b/include/linux/major.h
@@ -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 --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 659ecf48fb4..1fb23374151 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -41,6 +41,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#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 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#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 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#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
@@ -210,6 +213,7 @@ static inline int scsi_status_is_good(int status)
#define TYPE_COMM 0x09 /* Communications device */
#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
#define TYPE_RAID 0x0c
+#define TYPE_RBC 0x0e
#define TYPE_NO_LUN 0x7f
/*
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index c018020d916..63c91dd85ca 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -154,7 +154,9 @@ struct scsi_target {
unsigned int id; /* target id ... replace
* scsi_device.id eventually */
unsigned long create:1; /* signal that it needs to be added */
- unsigned long starget_data[0];
+ void *hostdata; /* available to low-level driver */
+ unsigned long starget_data[0]; /* for the transport */
+ /* starget_data must be the last element!!!! */
} __attribute__((aligned(sizeof(unsigned long))));
#define to_scsi_target(d) container_of(d, struct scsi_target, dev)
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 1cee1e10094..db9914adeac 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -10,6 +10,7 @@ struct block_device;
struct module;
struct scsi_cmnd;
struct scsi_device;
+struct scsi_target;
struct Scsi_Host;
struct scsi_host_cmd_pool;
struct scsi_transport_template;
@@ -228,6 +229,30 @@ struct scsi_host_template {
void (* slave_destroy)(struct scsi_device *);
/*
+ * Before the mid layer attempts to scan for a new device attached
+ * to a target where no target currently exists, it will call this
+ * entry in your driver. Should your driver need to allocate any
+ * structs or perform any other init items in order to send commands
+ * to a currently unused target, then this is where you can perform
+ * those allocations.
+ *
+ * Return values: 0 on success, non-0 on failure
+ *
+ * Status: OPTIONAL
+ */
+ int (* target_alloc)(struct scsi_target *);
+
+ /*
+ * Immediately prior to deallocating the target structure, and
+ * after all activity to attached scsi devices has ceased, the
+ * midlayer calls this point so that the driver may deallocate
+ * and terminate any references to the target.
+ *
+ * Status: OPTIONAL
+ */
+ void (* target_destroy)(struct scsi_target *);
+
+ /*
* fill in this function to allow the queue depth of this host
* to be changeable (on a per device basis). returns either
* the current queue depth setting (may be different from what
diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
index 2dcee7a8475..a4f1837a33b 100644
--- a/include/scsi/scsi_transport.h
+++ b/include/scsi/scsi_transport.h
@@ -21,6 +21,7 @@
#define SCSI_TRANSPORT_H
#include <linux/transport_class.h>
+#include <scsi/scsi_host.h>
struct scsi_transport_template {
/* the attribute containers */
@@ -32,8 +33,11 @@ struct scsi_transport_template {
* space of this size will be left at the end of the
* scsi_* structure */
int device_size;
+ int device_private_offset;
int target_size;
+ int target_private_offset;
int host_size;
+ /* no private offset for the host; there's an alternative mechanism */
/*
* True if the transport wants to use a host-based work-queue
@@ -45,4 +49,38 @@ struct scsi_transport_template {
dev_to_shost((tc)->dev)
+/* Private area maintenance. The driver requested allocations come
+ * directly after the transport class allocations (if any). The idea
+ * is that you *must* call these only once. The code assumes that the
+ * initial values are the ones the transport specific code requires */
+static inline void
+scsi_transport_reserve_target(struct scsi_transport_template * t, int space)
+{
+ BUG_ON(t->target_private_offset != 0);
+ t->target_private_offset = ALIGN(t->target_size, sizeof(void *));
+ t->target_size = t->target_private_offset + space;
+}
+static inline void
+scsi_transport_reserve_device(struct scsi_transport_template * t, int space)
+{
+ BUG_ON(t->device_private_offset != 0);
+ t->device_private_offset = ALIGN(t->device_size, sizeof(void *));
+ t->device_size = t->device_private_offset + space;
+}
+static inline void *
+scsi_transport_target_data(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+ return (u8 *)starget->starget_data
+ + shost->transportt->target_private_offset;
+
+}
+static inline void *
+scsi_transport_device_data(struct scsi_device *sdev)
+{
+ struct Scsi_Host *shost = sdev->host;
+ return (u8 *)sdev->sdev_data
+ + shost->transportt->device_private_offset;
+}
+
#endif /* SCSI_TRANSPORT_H */