* 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 {
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. */
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))));
+
+#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);
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 *,
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);
+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;