#include <linux/device.h>
#include <linux/list.h>
#include <linux/types.h>
+#include <linux/workqueue.h>
struct block_device;
struct module;
*/
unsigned skip_settle_delay:1;
+ /*
+ * ordered write support
+ */
+ unsigned ordered_flush:1;
+ unsigned ordered_tag:1;
+
/*
* Countdown for host blocking with no commands outstanding
*/
* access this list directly from a driver.
*/
struct list_head __devices;
+ struct list_head __targets;
struct scsi_host_cmd_pool *cmd_pool;
spinlock_t free_list_lock;
wait_queue_head_t host_wait;
struct scsi_host_template *hostt;
struct scsi_transport_template *transportt;
- volatile unsigned short host_busy; /* commands actually active on low-level */
- volatile unsigned short host_failed; /* commands that failed. */
+
+ /*
+ * The following two fields are protected with host_lock;
+ * however, eh routines can safely access during eh processing
+ * without acquiring the lock.
+ */
+ unsigned int host_busy; /* commands actually active on low-level */
+ unsigned int host_failed; /* commands that failed. */
unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
int resetting; /* if set, it means that last_reset is a valid value */
short unsigned int sg_tablesize;
short unsigned int max_sectors;
unsigned long dma_boundary;
-
+ /*
+ * Used to assign serial numbers to the cmds.
+ * Protected by the host lock.
+ */
+ unsigned long cmd_serial_number, cmd_pid;
+
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
unsigned use_blk_tcq:1;
*/
unsigned reverse_ordering:1;
+ /*
+ * ordered write support
+ */
+ unsigned ordered_flush:1;
+ unsigned ordered_tag:1;
+
+ /*
+ * Optional work queue to be utilized by the transport
+ */
+ char work_q_name[KOBJ_NAME_LEN];
+ struct workqueue_struct *work_q;
+
/*
* Host has rejected a command because it was busy.
*/
unsigned long hostdata[0] /* Used for storage of host specific stuff */
__attribute__ ((aligned (sizeof(unsigned long))));
};
-#define dev_to_shost(d) \
- container_of(d, struct Scsi_Host, shost_gendev)
+
#define class_to_shost(d) \
container_of(d, struct Scsi_Host, shost_classdev)
+int scsi_is_host_device(const struct device *);
+
+static inline struct Scsi_Host *dev_to_shost(struct device *dev)
+{
+ while (!scsi_is_host_device(dev)) {
+ if (!dev->parent)
+ return NULL;
+ dev = dev->parent;
+ }
+ return container_of(dev, struct Scsi_Host, shost_gendev);
+}
+
+extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
+extern void scsi_flush_work(struct Scsi_Host *);
extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
*/
extern void scsi_free_host_dev(struct scsi_device *);
extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
-int scsi_is_host_device(const struct device *);
-
/* legacy interfaces */
extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);