diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 12:55:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 12:55:29 -0700 |
commit | 424a6f6ef990b7e9f56f6627bfc6c46b493faeb4 (patch) | |
tree | 0028356ed8003495fbbe1f716f359e3c8ebc35b6 /drivers/scsi/libsas/sas_internal.h | |
parent | 1ab142d499294b844ecc81e8004db4ce029b0b61 (diff) | |
parent | cd8df932d894f3128c884e3ae1b2b484540513db (diff) | |
download | linux-rt-424a6f6ef990b7e9f56f6627bfc6c46b493faeb4.tar.gz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
SCSI updates from James Bottomley:
"The update includes the usual assortment of driver updates (lpfc,
qla2xxx, qla4xxx, bfa, bnx2fc, bnx2i, isci, fcoe, hpsa) plus a huge
amount of infrastructure work in the SAS library and transport class
as well as an iSCSI update. There's also a new SCSI based virtio
driver."
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (177 commits)
[SCSI] qla4xxx: Update driver version to 5.02.00-k15
[SCSI] qla4xxx: trivial cleanup
[SCSI] qla4xxx: Fix sparse warning
[SCSI] qla4xxx: Add support for multiple session per host.
[SCSI] qla4xxx: Export CHAP index as sysfs attribute
[SCSI] scsi_transport: Export CHAP index as sysfs attribute
[SCSI] qla4xxx: Add support to display CHAP list and delete CHAP entry
[SCSI] iscsi_transport: Add support to display CHAP list and delete CHAP entry
[SCSI] pm8001: fix endian issue with code optimization.
[SCSI] pm8001: Fix possible racing condition.
[SCSI] pm8001: Fix bogus interrupt state flag issue.
[SCSI] ipr: update PCI ID definitions for new adapters
[SCSI] qla2xxx: handle default case in qla2x00_request_firmware()
[SCSI] isci: improvements in driver unloading routine
[SCSI] isci: improve phy event warnings
[SCSI] isci: debug, provide state-enum-to-string conversions
[SCSI] scsi_transport_sas: 'enable' phys on reset
[SCSI] libsas: don't recover end devices attached to disabled phys
[SCSI] libsas: fixup target_port_protocols for expanders that don't report sata
[SCSI] libsas: set attached device type and target protocols for local phys
...
Diffstat (limited to 'drivers/scsi/libsas/sas_internal.h')
-rw-r--r-- | drivers/scsi/libsas/sas_internal.h | 97 |
1 files changed, 67 insertions, 30 deletions
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 14e21b5fb8ba..f05c63879949 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -30,6 +30,7 @@ #include <scsi/scsi_host.h> #include <scsi/scsi_transport_sas.h> #include <scsi/libsas.h> +#include <scsi/sas_ata.h> #define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__) @@ -38,6 +39,18 @@ #define TO_SAS_TASK(_scsi_cmd) ((void *)(_scsi_cmd)->host_scribble) #define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0) +struct sas_phy_data { + /* let reset be performed in sas_queue_work() context */ + struct sas_phy *phy; + struct mutex event_lock; + int hard_reset; + int reset_result; + struct work_struct reset_work; + int enable; + int enable_result; + struct work_struct enable_work; +}; + void sas_scsi_recover_host(struct Scsi_Host *shost); int sas_show_class(enum sas_class class, char *buf); @@ -56,6 +69,9 @@ enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *); int sas_init_queue(struct sas_ha_struct *sas_ha); int sas_init_events(struct sas_ha_struct *sas_ha); void sas_shutdown_queue(struct sas_ha_struct *sas_ha); +void sas_disable_revalidation(struct sas_ha_struct *ha); +void sas_enable_revalidation(struct sas_ha_struct *ha); +void __sas_drain_work(struct sas_ha_struct *ha); void sas_deform_port(struct asd_sas_phy *phy, int gone); @@ -64,6 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work); void sas_porte_link_reset_err(struct work_struct *work); void sas_porte_timer_event(struct work_struct *work); void sas_porte_hard_reset(struct work_struct *work); +void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work); int sas_notify_lldd_dev_found(struct domain_device *); void sas_notify_lldd_dev_gone(struct domain_device *); @@ -72,10 +89,17 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id, enum phy_func phy_func, struct sas_phy_linkrates *); int sas_smp_get_phy_events(struct sas_phy *phy); +void sas_device_set_phy(struct domain_device *dev, struct sas_port *port); struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); - +struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id); +int sas_ex_phy_discover(struct domain_device *dev, int single); +int sas_get_report_phy_sata(struct domain_device *dev, int phy_id, + struct smp_resp *rps_resp); +int sas_try_ata_reset(struct asd_sas_phy *phy); void sas_hae_reset(struct work_struct *work); +void sas_free_device(struct kref *kref); + #ifdef CONFIG_SCSI_SAS_HOST_SMP extern int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req, struct request *rsp); @@ -90,36 +114,13 @@ static inline int sas_smp_host_handler(struct Scsi_Host *shost, } #endif -static inline void sas_queue_event(int event, spinlock_t *lock, - unsigned long *pending, - struct work_struct *work, - struct sas_ha_struct *sas_ha) +static inline void sas_fail_probe(struct domain_device *dev, const char *func, int err) { - unsigned long flags; - - spin_lock_irqsave(lock, flags); - if (test_bit(event, pending)) { - spin_unlock_irqrestore(lock, flags); - return; - } - __set_bit(event, pending); - spin_unlock_irqrestore(lock, flags); - - spin_lock_irqsave(&sas_ha->state_lock, flags); - if (sas_ha->state != SAS_HA_UNREGISTERED) { - scsi_queue_work(sas_ha->core.shost, work); - } - spin_unlock_irqrestore(&sas_ha->state_lock, flags); -} - -static inline void sas_begin_event(int event, spinlock_t *lock, - unsigned long *pending) -{ - unsigned long flags; - - spin_lock_irqsave(lock, flags); - __clear_bit(event, pending); - spin_unlock_irqrestore(lock, flags); + SAS_DPRINTK("%s: for %s device %16llx returned %d\n", + func, dev->parent ? "exp-attached" : + "direct-attached", + SAS_ADDR(dev->sas_addr), err); + sas_unregister_dev(dev->port, dev); } static inline void sas_fill_in_rphy(struct domain_device *dev, @@ -132,6 +133,7 @@ static inline void sas_fill_in_rphy(struct domain_device *dev, case SATA_DEV: /* FIXME: need sata device type */ case SAS_END_DEV: + case SATA_PENDING: rphy->identify.device_type = SAS_END_DEVICE; break; case EDGE_DEV: @@ -146,6 +148,22 @@ static inline void sas_fill_in_rphy(struct domain_device *dev, } } +static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_device *dev) +{ + struct sas_phy *phy = p->phy; + + if (dev) { + if (dev_is_sata(dev)) + phy->identify.device_type = SAS_END_DEVICE; + else + phy->identify.device_type = dev->dev_type; + phy->identify.target_port_protocols = dev->tproto; + } else { + phy->identify.device_type = SAS_PHY_UNUSED; + phy->identify.target_port_protocols = 0; + } +} + static inline void sas_add_parent_port(struct domain_device *dev, int phy_id) { struct expander_device *ex = &dev->ex_dev; @@ -161,4 +179,23 @@ static inline void sas_add_parent_port(struct domain_device *dev, int phy_id) sas_port_add_phy(ex->parent_port, ex_phy->phy); } +static inline struct domain_device *sas_alloc_device(void) +{ + struct domain_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + + if (dev) { + INIT_LIST_HEAD(&dev->siblings); + INIT_LIST_HEAD(&dev->dev_list_node); + INIT_LIST_HEAD(&dev->disco_list_node); + kref_init(&dev->kref); + spin_lock_init(&dev->done_lock); + } + return dev; +} + +static inline void sas_put_device(struct domain_device *dev) +{ + kref_put(&dev->kref, sas_free_device); +} + #endif /* _SAS_INTERNAL_H_ */ |