Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (73 commits) [SCSI] aic79xx: Add ASC-29320LPE ids to driver [SCSI] stex: version update [SCSI] stex: change wait loop code [SCSI] stex: add new device type support [SCSI] stex: update device id info [SCSI] stex: adjust default queue length [SCSI] stex: add value check in hard reset routine [SCSI] stex: fix controller_info command handling [SCSI] stex: fix biosparam calculation [SCSI] megaraid: fix MMIO casts [SCSI] tgt: fix undefined flush_dcache_page() problem [SCSI] libsas: better error handling in sas_expander.c [SCSI] lpfc 8.1.11 : Change version number to 8.1.11 [SCSI] lpfc 8.1.11 : Misc Fixes [SCSI] lpfc 8.1.11 : Add soft_wwnn sysfs attribute, rename soft_wwn_enable [SCSI] lpfc 8.1.11 : Removed decoding of PCI Subsystem Id [SCSI] lpfc 8.1.11 : Add MSI (Message Signalled Interrupts) support [SCSI] lpfc 8.1.11 : Adjust LOG_FCP logging [SCSI] lpfc 8.1.11 : Fix Memory leaks [SCSI] lpfc 8.1.11 : Fix lpfc_multi_ring_support ...
This commit is contained in:
+11
-3
@@ -339,6 +339,8 @@ struct sas_ha_struct {
|
||||
void (*notify_phy_event)(struct asd_sas_phy *, enum phy_event);
|
||||
|
||||
void *lldd_ha; /* not touched by sas class code */
|
||||
|
||||
struct list_head eh_done_q;
|
||||
};
|
||||
|
||||
#define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
|
||||
@@ -527,13 +529,16 @@ struct sas_task {
|
||||
|
||||
void *lldd_task; /* for use by LLDDs */
|
||||
void *uldd_task;
|
||||
|
||||
struct work_struct abort_work;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define SAS_TASK_STATE_PENDING 1
|
||||
#define SAS_TASK_STATE_DONE 2
|
||||
#define SAS_TASK_STATE_ABORTED 4
|
||||
#define SAS_TASK_STATE_PENDING 1
|
||||
#define SAS_TASK_STATE_DONE 2
|
||||
#define SAS_TASK_STATE_ABORTED 4
|
||||
#define SAS_TASK_INITIATOR_ABORTED 8
|
||||
|
||||
static inline struct sas_task *sas_alloc_task(gfp_t flags)
|
||||
{
|
||||
@@ -593,6 +598,7 @@ struct sas_domain_function_template {
|
||||
extern int sas_register_ha(struct sas_ha_struct *);
|
||||
extern int sas_unregister_ha(struct sas_ha_struct *);
|
||||
|
||||
int sas_phy_reset(struct sas_phy *phy, int hard_reset);
|
||||
extern int sas_queuecommand(struct scsi_cmnd *,
|
||||
void (*scsi_done)(struct scsi_cmnd *));
|
||||
extern int sas_target_alloc(struct scsi_target *);
|
||||
@@ -625,4 +631,6 @@ void sas_unregister_dev(struct domain_device *);
|
||||
|
||||
void sas_init_dev(struct domain_device *);
|
||||
|
||||
void sas_task_abort(struct sas_task *task);
|
||||
|
||||
#endif /* _SASLIB_H_ */
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef __LIBSRP_H__
|
||||
#define __LIBSRP_H__
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/srp.h>
|
||||
|
||||
enum iue_flags {
|
||||
V_DIOVER,
|
||||
V_WRITE,
|
||||
V_LINKED,
|
||||
V_FLYING,
|
||||
};
|
||||
|
||||
struct srp_buf {
|
||||
dma_addr_t dma;
|
||||
void *buf;
|
||||
};
|
||||
|
||||
struct srp_queue {
|
||||
void *pool;
|
||||
void *items;
|
||||
struct kfifo *queue;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct srp_target {
|
||||
struct Scsi_Host *shost;
|
||||
struct device *dev;
|
||||
|
||||
spinlock_t lock;
|
||||
struct list_head cmd_queue;
|
||||
|
||||
size_t srp_iu_size;
|
||||
struct srp_queue iu_queue;
|
||||
size_t rx_ring_size;
|
||||
struct srp_buf **rx_ring;
|
||||
|
||||
void *ldata;
|
||||
};
|
||||
|
||||
struct iu_entry {
|
||||
struct srp_target *target;
|
||||
|
||||
struct list_head ilist;
|
||||
dma_addr_t remote_token;
|
||||
unsigned long flags;
|
||||
|
||||
struct srp_buf *sbuf;
|
||||
};
|
||||
|
||||
typedef int (srp_rdma_t)(struct scsi_cmnd *, struct scatterlist *, int,
|
||||
struct srp_direct_buf *, int,
|
||||
enum dma_data_direction, unsigned int);
|
||||
extern int srp_target_alloc(struct srp_target *, struct device *, size_t, size_t);
|
||||
extern void srp_target_free(struct srp_target *);
|
||||
|
||||
extern struct iu_entry *srp_iu_get(struct srp_target *);
|
||||
extern void srp_iu_put(struct iu_entry *);
|
||||
|
||||
extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64);
|
||||
extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *,
|
||||
srp_rdma_t, int, int);
|
||||
|
||||
|
||||
static inline struct srp_target *host_to_srp_target(struct Scsi_Host *host)
|
||||
{
|
||||
return (struct srp_target *) host->hostdata;
|
||||
}
|
||||
|
||||
static inline int srp_cmd_direction(struct srp_cmd *cmd)
|
||||
{
|
||||
return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
struct request;
|
||||
struct scatterlist;
|
||||
struct Scsi_Host;
|
||||
struct scsi_device;
|
||||
|
||||
|
||||
@@ -72,6 +73,9 @@ struct scsi_cmnd {
|
||||
unsigned short use_sg; /* Number of pieces of scatter-gather */
|
||||
unsigned short sglist_len; /* size of malloc'd scatter-gather list */
|
||||
|
||||
/* offset in cmd we are at (for multi-transfer tgt cmds) */
|
||||
unsigned offset;
|
||||
|
||||
unsigned underflow; /* Return error if less than
|
||||
this amount is transferred */
|
||||
|
||||
@@ -119,7 +123,10 @@ struct scsi_cmnd {
|
||||
};
|
||||
|
||||
extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
|
||||
extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t);
|
||||
extern void scsi_put_command(struct scsi_cmnd *);
|
||||
extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *,
|
||||
struct device *);
|
||||
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int);
|
||||
extern void scsi_finish_command(struct scsi_cmnd *cmd);
|
||||
extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd);
|
||||
@@ -128,4 +135,7 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
|
||||
size_t *offset, size_t *len);
|
||||
extern void scsi_kunmap_atomic_sg(void *virt);
|
||||
|
||||
extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
|
||||
extern void scsi_free_sgtable(struct scatterlist *, int);
|
||||
|
||||
#endif /* _SCSI_SCSI_CMND_H */
|
||||
|
||||
+15
-15
@@ -223,13 +223,13 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
|
||||
struct scsi_device *);
|
||||
|
||||
/**
|
||||
* shost_for_each_device - iterate over all devices of a host
|
||||
* @sdev: iterator
|
||||
* @host: host whiches devices we want to iterate over
|
||||
* shost_for_each_device - iterate over all devices of a host
|
||||
* @sdev: the &struct scsi_device to use as a cursor
|
||||
* @shost: the &struct scsi_host to iterate over
|
||||
*
|
||||
* This traverses over each devices of @shost. The devices have
|
||||
* a reference that must be released by scsi_host_put when breaking
|
||||
* out of the loop.
|
||||
* Iterator that returns each device attached to @shost. This loop
|
||||
* takes a reference on each device and releases it at the end. If
|
||||
* you break out of the loop, you must call scsi_device_put(sdev).
|
||||
*/
|
||||
#define shost_for_each_device(sdev, shost) \
|
||||
for ((sdev) = __scsi_iterate_devices((shost), NULL); \
|
||||
@@ -237,17 +237,17 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
|
||||
(sdev) = __scsi_iterate_devices((shost), (sdev)))
|
||||
|
||||
/**
|
||||
* __shost_for_each_device - iterate over all devices of a host (UNLOCKED)
|
||||
* @sdev: iterator
|
||||
* @host: host whiches devices we want to iterate over
|
||||
* __shost_for_each_device - iterate over all devices of a host (UNLOCKED)
|
||||
* @sdev: the &struct scsi_device to use as a cursor
|
||||
* @shost: the &struct scsi_host to iterate over
|
||||
*
|
||||
* This traverses over each devices of @shost. It does _not_ take a
|
||||
* reference on the scsi_device, thus it the whole loop must be protected
|
||||
* by shost->host_lock.
|
||||
* Iterator that returns each device attached to @shost. It does _not_
|
||||
* take a reference on the scsi_device, so the whole loop must be
|
||||
* protected by shost->host_lock.
|
||||
*
|
||||
* Note: The only reason why drivers would want to use this is because
|
||||
* they're need to access the device list in irq context. Otherwise you
|
||||
* really want to use shost_for_each_device instead.
|
||||
* Note: The only reason to use this is because you need to access the
|
||||
* device list in interrupt context. Otherwise you really want to use
|
||||
* shost_for_each_device instead.
|
||||
*/
|
||||
#define __shost_for_each_device(sdev, shost) \
|
||||
list_for_each_entry((sdev), &((shost)->__devices), siblings)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
struct request_queue;
|
||||
struct block_device;
|
||||
struct completion;
|
||||
struct module;
|
||||
@@ -123,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
|
||||
@@ -240,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
|
||||
@@ -552,6 +604,9 @@ struct Scsi_Host {
|
||||
/* 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
|
||||
*/
|
||||
@@ -568,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;
|
||||
@@ -648,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;
|
||||
@@ -671,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
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SCSI target definitions
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
struct Scsi_Host;
|
||||
struct scsi_cmnd;
|
||||
struct scsi_lun;
|
||||
|
||||
extern struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *);
|
||||
extern int scsi_tgt_alloc_queue(struct Scsi_Host *);
|
||||
extern void scsi_tgt_free_queue(struct Scsi_Host *);
|
||||
extern int scsi_tgt_queue_command(struct scsi_cmnd *, struct scsi_lun *, u64);
|
||||
extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, int, u64, struct scsi_lun *,
|
||||
void *);
|
||||
extern struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *,
|
||||
enum dma_data_direction, gfp_t);
|
||||
extern void scsi_host_put_command(struct Scsi_Host *, struct scsi_cmnd *);
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SCSI target kernel/user interface
|
||||
*
|
||||
* Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
|
||||
* Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#ifndef __SCSI_TARGET_IF_H
|
||||
#define __SCSI_TARGET_IF_H
|
||||
|
||||
/* user -> kernel */
|
||||
#define TGT_UEVENT_CMD_RSP 0x0001
|
||||
#define TGT_UEVENT_TSK_MGMT_RSP 0x0002
|
||||
|
||||
/* kernel -> user */
|
||||
#define TGT_KEVENT_CMD_REQ 0x1001
|
||||
#define TGT_KEVENT_CMD_DONE 0x1002
|
||||
#define TGT_KEVENT_TSK_MGMT_REQ 0x1003
|
||||
|
||||
struct tgt_event_hdr {
|
||||
uint16_t version;
|
||||
uint16_t status;
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
} __attribute__ ((aligned (sizeof(uint64_t))));
|
||||
|
||||
struct tgt_event {
|
||||
struct tgt_event_hdr hdr;
|
||||
|
||||
union {
|
||||
/* user-> kernel */
|
||||
struct {
|
||||
int host_no;
|
||||
uint32_t len;
|
||||
int result;
|
||||
aligned_u64 uaddr;
|
||||
uint8_t rw;
|
||||
aligned_u64 tag;
|
||||
} cmd_rsp;
|
||||
struct {
|
||||
int host_no;
|
||||
aligned_u64 mid;
|
||||
int result;
|
||||
} tsk_mgmt_rsp;
|
||||
|
||||
|
||||
/* kernel -> user */
|
||||
struct {
|
||||
int host_no;
|
||||
uint32_t data_len;
|
||||
uint8_t scb[16];
|
||||
uint8_t lun[8];
|
||||
int attribute;
|
||||
aligned_u64 tag;
|
||||
} cmd_req;
|
||||
struct {
|
||||
int host_no;
|
||||
aligned_u64 tag;
|
||||
int result;
|
||||
} cmd_done;
|
||||
struct {
|
||||
int host_no;
|
||||
int function;
|
||||
aligned_u64 tag;
|
||||
uint8_t lun[8];
|
||||
aligned_u64 mid;
|
||||
} tsk_mgmt_req;
|
||||
} p;
|
||||
} __attribute__ ((aligned (sizeof(uint64_t))));
|
||||
|
||||
#define TGT_RING_SIZE (1UL << 16)
|
||||
#define TGT_RING_PAGES (TGT_RING_SIZE >> PAGE_SHIFT)
|
||||
#define TGT_EVENT_PER_PAGE (PAGE_SIZE / sizeof(struct tgt_event))
|
||||
#define TGT_MAX_EVENTS (TGT_EVENT_PER_PAGE * TGT_RING_PAGES)
|
||||
|
||||
#endif
|
||||
@@ -73,6 +73,8 @@ struct sas_phy {
|
||||
|
||||
/* for the list of phys belonging to a port */
|
||||
struct list_head port_siblings;
|
||||
|
||||
struct work_struct reset_work;
|
||||
};
|
||||
|
||||
#define dev_to_phy(d) \
|
||||
|
||||
Reference in New Issue
Block a user