vserver 1.9.5.x5
[linux-2.6.git] / include / scsi / scsi_device.h
index 3272c6e..53e3d08 100644 (file)
@@ -30,6 +30,9 @@ enum scsi_device_state {
                                 * originate in the mid-layer) */
        SDEV_OFFLINE,           /* Device offlined (by error handling or
                                 * user request */
+       SDEV_BLOCK,             /* Device blocked by scsi lld.  No scsi 
+                                * commands from user or midlayer should be issued
+                                * to the scsi lld. */
 };
 
 struct scsi_device {
@@ -63,6 +66,7 @@ struct scsi_device {
        char devfs_name[256];   /* devfs junk */
        char type;
        char scsi_level;
+       char inq_periph_qual;   /* PQ from INQUIRY data */      
        unsigned char inquiry_len;      /* valid bytes in 'inquiry' */
        unsigned char * inquiry;        /* INQUIRY response data */
        char * vendor;          /* [back_compat] point into 'inquiry' ... */
@@ -105,29 +109,57 @@ struct scsi_device {
        unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
        unsigned no_start_on_add:1;     /* do not issue start on add */
        unsigned allow_restart:1; /* issue START_UNIT in error handler */
+       unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
+       unsigned select_no_atn:1;
+       unsigned fix_capacity:1;        /* READ_CAPACITY is too high by 1 */
 
        unsigned int device_blocked;    /* Device returned QUEUE_FULL. */
 
        unsigned int max_device_blocked; /* what device_blocked counts down from  */
 #define SCSI_DEFAULT_DEVICE_BLOCKED    3
 
+       int timeout;
+
        struct device           sdev_gendev;
        struct class_device     sdev_classdev;
 
-       struct class_device     transport_classdev;
-
        enum scsi_device_state sdev_state;
-       unsigned long           transport_data[0];
+       unsigned long           sdev_data[0];
 } __attribute__((aligned(sizeof(unsigned long))));
 #define        to_scsi_device(d)       \
        container_of(d, struct scsi_device, sdev_gendev)
 #define        class_to_sdev(d)        \
        container_of(d, struct scsi_device, sdev_classdev)
 #define transport_class_to_sdev(class_dev) \
-       container_of(class_dev, struct scsi_device, transport_classdev)
+       to_scsi_device(class_dev->dev)
+
+/*
+ * scsi_target: representation of a scsi target, for now, this is only
+ * used for single_lun devices. If no one has active IO to the target,
+ * starget_sdev_user is NULL, else it points to the active sdev.
+ */
+struct scsi_target {
+       struct scsi_device      *starget_sdev_user;
+       struct device           dev;
+       unsigned int            channel;
+       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];
+} __attribute__((aligned(sizeof(unsigned long))));
 
-extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
-               uint, uint, uint);
+#define to_scsi_target(d)      container_of(d, struct scsi_target, dev)
+static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
+{
+       return to_scsi_target(sdev->sdev_gendev.parent);
+}
+#define transport_class_to_starget(class_dev) \
+       to_scsi_target(class_dev->dev)
+
+extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
+               uint, uint, uint, void *hostdata);
+#define scsi_add_device(host, channel, target, lun) \
+       __scsi_add_device(host, channel, target, lun, NULL)
 extern void scsi_remove_device(struct scsi_device *);
 extern int scsi_device_cancel(struct scsi_device *, int);
 
@@ -137,6 +169,8 @@ extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
                                              uint, uint, uint);
 extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *,
                                                uint, uint, uint);
+extern void starget_for_each_device(struct scsi_target *, void *,
+                    void (*fn)(struct scsi_device *, void *));
 
 /* only exposed to implement shost_for_each_device */
 extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
@@ -180,13 +214,51 @@ extern int scsi_set_medium_removal(struct scsi_device *, char);
 extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
                           unsigned char *buffer, int len, int timeout,
                           int retries, struct scsi_mode_data *data);
+extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
+                               int retries);
 extern int scsi_device_set_state(struct scsi_device *sdev,
                                 enum scsi_device_state state);
 extern int scsi_device_quiesce(struct scsi_device *sdev);
 extern void scsi_device_resume(struct scsi_device *sdev);
+extern void scsi_target_quiesce(struct scsi_target *);
+extern void scsi_target_resume(struct scsi_target *);
 extern const char *scsi_device_state_name(enum scsi_device_state);
-static int inline scsi_device_online(struct scsi_device *sdev)
+extern int scsi_is_sdev_device(const struct device *);
+extern int scsi_is_target_device(const struct device *);
+static inline int scsi_device_online(struct scsi_device *sdev)
 {
        return sdev->sdev_state != SDEV_OFFLINE;
 }
+
+/* accessor functions for the SCSI parameters */
+static inline int scsi_device_sync(struct scsi_device *sdev)
+{
+       return sdev->sdtr;
+}
+static inline int scsi_device_wide(struct scsi_device *sdev)
+{
+       return sdev->wdtr;
+}
+static inline int scsi_device_dt(struct scsi_device *sdev)
+{
+       return sdev->ppr;
+}
+static inline int scsi_device_dt_only(struct scsi_device *sdev)
+{
+       if (sdev->inquiry_len < 57)
+               return 0;
+       return (sdev->inquiry[56] & 0x0c) == 0x04;
+}
+static inline int scsi_device_ius(struct scsi_device *sdev)
+{
+       if (sdev->inquiry_len < 57)
+               return 0;
+       return sdev->inquiry[56] & 0x01;
+}
+static inline int scsi_device_qas(struct scsi_device *sdev)
+{
+       if (sdev->inquiry_len < 57)
+               return 0;
+       return sdev->inquiry[56] & 0x02;
+}
 #endif /* _SCSI_SCSI_DEVICE_H */