X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fscsi%2Fscsi_host.h;fp=include%2Fscsi%2Fscsi_host.h;h=7f1f411d07af04c47f1faf7ce6400b57c197fef2;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=827992949c4bfe2b94635262483a4863aa0b2550;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 827992949..7f1f411d0 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -7,6 +7,7 @@ #include #include +struct request_queue; struct block_device; struct completion; struct module; @@ -16,6 +17,7 @@ struct scsi_target; struct Scsi_Host; struct scsi_host_cmd_pool; struct scsi_transport_template; +struct blk_queue_tags; /* @@ -122,6 +124,39 @@ struct scsi_host_template { int (* queuecommand)(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); + /* + * The transfer functions are used to queue a scsi command to + * the LLD. When the driver is finished processing the command + * the done callback is invoked. + * + * return values: see queuecommand + * + * If the LLD accepts the cmd, it should set the result to an + * appropriate value when completed before calling the done function. + * + * STATUS: REQUIRED FOR TARGET DRIVERS + */ + /* TODO: rename */ + int (* transfer_response)(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); + /* + * This is called to inform the LLD to transfer cmd->request_bufflen + * bytes of the cmd at cmd->offset in the cmd. The cmd->use_sg + * speciefies the number of scatterlist entried in the command + * and cmd->request_buffer contains the scatterlist. + * + * If the command cannot be processed in one transfer_data call + * becuase a scatterlist within the LLD's limits cannot be + * created then transfer_data will be called multiple times. + * It is initially called from process context, and later + * calls are from the interrup context. + */ + int (* transfer_data)(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); + + /* Used as callback for the completion of task management request. */ + int (* tsk_mgmt_response)(u64 mid, int result); + /* * This is an error handling strategy routine. You don't need to * define one of these if you don't want to - there is a default @@ -140,26 +175,11 @@ struct scsi_host_template { * * Status: REQUIRED (at least one of them) */ - int (* eh_strategy_handler)(struct Scsi_Host *); int (* eh_abort_handler)(struct scsi_cmnd *); int (* eh_device_reset_handler)(struct scsi_cmnd *); int (* eh_bus_reset_handler)(struct scsi_cmnd *); int (* eh_host_reset_handler)(struct scsi_cmnd *); - /* - * This is an optional routine to notify the host that the scsi - * timer just fired. The returns tell the timer routine what to - * do about this: - * - * EH_HANDLED: I fixed the error, please complete the command - * EH_RESET_TIMER: I need more time, reset the timer and - * begin counting again - * EH_NOT_HANDLED Begin normal error recovery - * - * Status: OPTIONAL - */ - enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *); - /* * Before the mid layer attempts to scan for a new device where none * currently exists, it will call this entry in your driver. Should @@ -254,6 +274,24 @@ struct scsi_host_template { */ void (* target_destroy)(struct scsi_target *); + /* + * If a host has the ability to discover targets on its own instead + * of scanning the entire bus, it can fill in this function and + * call scsi_scan_host(). This function will be called periodically + * until it returns 1 with the scsi_host and the elapsed time of + * the scan in jiffies. + * + * Status: OPTIONAL + */ + int (* scan_finished)(struct Scsi_Host *, unsigned long); + + /* + * If the host wants to be called before the scan starts, but + * after the midlayer has set up ready for the scan, it can fill + * in this function. + */ + void (* scan_start)(struct Scsi_Host *); + /* * fill in this function to allow the queue depth of this host * to be changeable (on a per device basis). returns either @@ -300,7 +338,7 @@ struct scsi_host_template { * suspend support */ int (*resume)(struct scsi_device *); - int (*suspend)(struct scsi_device *); + int (*suspend)(struct scsi_device *, pm_message_t state); /* * Name of proc directory @@ -480,6 +518,12 @@ struct Scsi_Host { struct scsi_host_template *hostt; struct scsi_transport_template *transportt; + /* + * area to keep a shared tag map (if needed, will be + * NULL if not) + */ + struct blk_queue_tag *bqt; + /* * The following two fields are protected with host_lock; * however, eh routines can safely access during eh processing @@ -487,6 +531,7 @@ struct Scsi_Host { */ unsigned int host_busy; /* commands actually active on low-level */ unsigned int host_failed; /* commands that failed. */ + unsigned int host_eh_scheduled; /* EH scheduled without command */ 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 */ @@ -556,6 +601,12 @@ struct Scsi_Host { */ unsigned ordered_tag:1; + /* task mgmt function in progress */ + unsigned tmf_in_progress:1; + + /* Asynchronous scan in progress */ + unsigned async_scan:1; + /* * Optional work queue to be utilized by the transport */ @@ -572,6 +623,12 @@ struct Scsi_Host { */ unsigned int max_host_blocked; + /* + * q used for scsi_tgt msgs, async events or any other requests that + * need to be processed in userspace + */ + struct request_queue *uspace_req_q; + /* legacy crap */ unsigned long base; unsigned long io_port; @@ -633,7 +690,8 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost) { return shost->shost_state == SHOST_RECOVERY || shost->shost_state == SHOST_CANCEL_RECOVERY || - shost->shost_state == SHOST_DEL_RECOVERY; + shost->shost_state == SHOST_DEL_RECOVERY || + shost->tmf_in_progress; } extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); @@ -651,11 +709,6 @@ extern const char *scsi_host_state_name(enum scsi_host_state); extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *); -static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock) -{ - shost->host_lock = lock; -} - static inline struct device *scsi_get_device(struct Scsi_Host *shost) { return shost->shost_gendev.parent; @@ -674,6 +727,9 @@ extern void scsi_unblock_requests(struct Scsi_Host *); extern void scsi_block_requests(struct Scsi_Host *); struct class_container; + +extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, + void (*) (struct request_queue *)); /* * These two functions are used to allocate and free a pseudo device * which will connect to the host adapter itself rather than any