#include <linux/timer.h>
#include <linux/pci.h>
#include <scsi/sas.h>
+#include <linux/libata.h>
#include <linux/list.h>
-#include <asm/semaphore.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_transport_sas.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
struct block_device;
/* ---------- Expander Devices ---------- */
-#define ETASK 0xFA
-
#define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj)
#define to_dev_attr(_attr) container_of(_attr, struct domain_dev_attribute,\
attr)
u8 attached_sata_dev:1;
u8 attached_sata_ps:1;
- enum sas_proto attached_tproto;
- enum sas_proto attached_iproto;
+ enum sas_protocol attached_tproto;
+ enum sas_protocol attached_iproto;
u8 attached_sas_addr[SAS_ADDR_SIZE];
u8 attached_phy_id;
u8 port_no; /* port number, if this is a PM (Port) */
struct list_head children; /* PM Ports if this is a PM */
+
+ struct ata_port *ap;
+ struct ata_host ata_host;
+ struct ata_taskfile tf;
+ u32 sstatus;
+ u32 serror;
+ u32 scontrol;
};
/* ---------- Domain device ---------- */
struct list_head dev_list_node;
- enum sas_proto iproto;
- enum sas_proto tproto;
+ enum sas_protocol iproto;
+ enum sas_protocol tproto;
struct sas_rphy *rphy;
enum sas_class class;
u8 sas_addr[SAS_ADDR_SIZE];
u8 attached_sas_addr[SAS_ADDR_SIZE];
- enum sas_proto iproto;
- enum sas_proto tproto;
+ enum sas_protocol iproto;
+ enum sas_protocol tproto;
enum sas_oob_mode oob_mode;
int id; /* must be set */
enum sas_class class;
- enum sas_proto iproto;
- enum sas_proto tproto;
+ enum sas_protocol iproto;
+ enum sas_protocol tproto;
enum sas_phy_type type;
enum sas_phy_role role;
struct list_head task_queue;
int task_queue_size;
- struct semaphore queue_thread_sema;
- int queue_thread_kill;
+ struct task_struct *queue_thread;
};
struct sas_ha_event {
struct sas_ha_struct *ha;
};
+enum sas_ha_state {
+ SAS_HA_REGISTERED,
+ SAS_HA_UNREGISTERED
+};
+
struct sas_ha_struct {
/* private: */
spinlock_t event_lock;
struct sas_ha_event ha_events[HA_NUM_EVENTS];
unsigned long pending;
+ enum sas_ha_state state;
+ spinlock_t state_lock;
+
struct scsi_core core;
/* public: */
char *sas_ha_name;
- struct pci_dev *pcidev; /* should be set */
+ struct device *dev; /* should be set */
struct module *lldd_module; /* should be set */
u8 *sas_addr; /* must be set */
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)
spinlock_t task_state_lock;
unsigned task_state_flags;
- enum sas_proto task_proto;
+ enum sas_protocol task_proto;
/* Used by the discovery code. */
struct timer_list timer;
void *lldd_task; /* for use by LLDDs */
void *uldd_task;
-};
+ struct work_struct abort_work;
+};
+extern struct kmem_cache *sas_task_cache;
-#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_NEED_DEV_RESET 8
+#define SAS_TASK_AT_INITIATOR 16
static inline struct sas_task *sas_alloc_task(gfp_t flags)
{
- extern kmem_cache_t *sas_task_cache;
- struct sas_task *task = kmem_cache_alloc(sas_task_cache, flags);
+ struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags);
if (task) {
- memset(task, 0, sizeof(*task));
INIT_LIST_HEAD(&task->list);
spin_lock_init(&task->task_state_lock);
task->task_state_flags = SAS_TASK_STATE_PENDING;
static inline void sas_free_task(struct sas_task *task)
{
if (task) {
- extern kmem_cache_t *sas_task_cache;
BUG_ON(!list_empty(&task->list));
kmem_cache_free(sas_task_cache, task);
}
extern int sas_register_ha(struct sas_ha_struct *);
extern int sas_unregister_ha(struct sas_ha_struct *);
+int sas_set_phy_speed(struct sas_phy *phy,
+ struct sas_phy_linkrates *rates);
+int sas_phy_enable(struct sas_phy *phy, int enabled);
+int sas_phy_reset(struct sas_phy *phy, int hard_reset);
+int sas_queue_up(struct sas_task *task);
extern int sas_queuecommand(struct scsi_cmnd *,
void (*scsi_done)(struct scsi_cmnd *));
extern int sas_target_alloc(struct scsi_target *);
extern int sas_slave_alloc(struct scsi_device *);
extern int sas_slave_configure(struct scsi_device *);
extern void sas_slave_destroy(struct scsi_device *);
-extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
+extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
+ int reason);
extern int sas_change_queue_type(struct scsi_device *, int qt);
extern int sas_bios_param(struct scsi_device *,
struct block_device *,
void sas_init_dev(struct domain_device *);
+void sas_task_abort(struct sas_task *);
+int __sas_task_abort(struct sas_task *);
+int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
+int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd);
+
+extern void sas_target_destroy(struct scsi_target *);
+extern int sas_slave_alloc(struct scsi_device *);
+extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
+
+extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
+ struct request *req);
+
+extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
+ struct ssp_response_iu *iu);
+struct sas_phy *sas_find_local_phy(struct domain_device *dev);
+
+int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
+
#endif /* _SASLIB_H_ */