aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/aic94xx/aic94xx_hwi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic94xx/aic94xx_hwi.c')
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.c77
1 files changed, 46 insertions, 31 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index 1d8c5e5f442..4df867e07b2 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -25,8 +25,10 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/firmware.h>
#include "aic94xx.h"
#include "aic94xx_reg.h"
@@ -38,16 +40,14 @@ u32 MBAR0_SWB_SIZE;
/* ---------- Initialization ---------- */
-static void asd_get_user_sas_addr(struct asd_ha_struct *asd_ha)
+static int asd_get_user_sas_addr(struct asd_ha_struct *asd_ha)
{
- extern char sas_addr_str[];
- /* If the user has specified a WWN it overrides other settings
- */
- if (sas_addr_str[0] != '\0')
- asd_destringify_sas_addr(asd_ha->hw_prof.sas_addr,
- sas_addr_str);
- else if (asd_ha->hw_prof.sas_addr[0] != 0)
- asd_stringify_sas_addr(sas_addr_str, asd_ha->hw_prof.sas_addr);
+ /* adapter came with a sas address */
+ if (asd_ha->hw_prof.sas_addr[0])
+ return 0;
+
+ return sas_request_addr(asd_ha->sas_ha.core.shost,
+ asd_ha->hw_prof.sas_addr);
}
static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha)
@@ -74,7 +74,7 @@ static void asd_init_phy_identify(struct asd_phy *phy)
memset(phy->identify_frame, 0, sizeof(*phy->identify_frame));
- phy->identify_frame->dev_type = SAS_END_DEV;
+ phy->identify_frame->dev_type = SAS_END_DEVICE;
if (phy->sas_phy.role & PHY_ROLE_INITIATOR)
phy->identify_frame->initiator_bits = phy->sas_phy.iproto;
if (phy->sas_phy.role & PHY_ROLE_TARGET)
@@ -91,7 +91,7 @@ static int asd_init_phy(struct asd_phy *phy)
sas_phy->enabled = 1;
sas_phy->class = SAS;
- sas_phy->iproto = SAS_PROTO_ALL;
+ sas_phy->iproto = SAS_PROTOCOL_ALL;
sas_phy->tproto = 0;
sas_phy->type = PHY_TYPE_PHYSICAL;
sas_phy->role = PHY_ROLE_INITIATOR;
@@ -112,6 +112,21 @@ static int asd_init_phy(struct asd_phy *phy)
return 0;
}
+static void asd_init_ports(struct asd_ha_struct *asd_ha)
+{
+ int i;
+
+ spin_lock_init(&asd_ha->asd_ports_lock);
+ for (i = 0; i < ASD_MAX_PHYS; i++) {
+ struct asd_port *asd_port = &asd_ha->asd_ports[i];
+
+ memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE);
+ memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE);
+ asd_port->phy_mask = 0;
+ asd_port->num_phys = 0;
+ }
+}
+
static int asd_init_phys(struct asd_ha_struct *asd_ha)
{
u8 i;
@@ -121,6 +136,7 @@ static int asd_init_phys(struct asd_ha_struct *asd_ha)
struct asd_phy *phy = &asd_ha->phys[i];
phy->phy_desc = &asd_ha->hw_prof.phy_desc[i];
+ phy->asd_port = NULL;
phy->sas_phy.enabled = 0;
phy->sas_phy.id = i;
@@ -235,7 +251,7 @@ static int asd_init_scbs(struct asd_ha_struct *asd_ha)
return 0;
}
-static inline void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
+static void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
{
asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE;
asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE;
@@ -641,8 +657,7 @@ int asd_init_hw(struct asd_ha_struct *asd_ha)
asd_init_ctxmem(asd_ha);
- asd_get_user_sas_addr(asd_ha);
- if (!asd_ha->hw_prof.sas_addr[0]) {
+ if (asd_get_user_sas_addr(asd_ha)) {
asd_printk("No SAS Address provided for %s\n",
pci_name(asd_ha->pcidev));
err = -ENODEV;
@@ -658,6 +673,8 @@ int asd_init_hw(struct asd_ha_struct *asd_ha)
goto Out;
}
+ asd_init_ports(asd_ha);
+
err = asd_init_scbs(asd_ha);
if (err) {
asd_printk("couldn't initialize scbs for %s\n",
@@ -755,7 +772,7 @@ static void asd_dl_tasklet_handler(unsigned long data)
* asd_process_donelist_isr -- schedule processing of done list entries
* @asd_ha: pointer to host adapter structure
*/
-static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
+static void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
{
tasklet_schedule(&asd_ha->seq.dl_tasklet);
}
@@ -764,7 +781,7 @@ static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
* asd_com_sas_isr -- process device communication interrupt (COMINT)
* @asd_ha: pointer to host adapter structure
*/
-static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
+static void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
{
u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT);
@@ -803,7 +820,7 @@ static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
asd_chip_reset(asd_ha);
}
-static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
+static void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
{
static const char *halt_code[256] = {
"UNEXPECTED_INTERRUPT0",
@@ -890,7 +907,7 @@ static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
* asd_dch_sas_isr -- process device channel interrupt (DEVINT)
* @asd_ha: pointer to host adapter structure
*/
-static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
+static void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
{
u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS);
@@ -905,7 +922,7 @@ static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
* ads_rbi_exsi_isr -- process external system interface interrupt (INITERR)
* @asd_ha: pointer to host adapter structure
*/
-static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
+static void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
{
u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R);
@@ -953,7 +970,7 @@ static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
*
* Asserted on PCIX errors: target abort, etc.
*/
-static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
+static void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
{
u16 status;
u32 pcix_status;
@@ -996,11 +1013,10 @@ static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
* asd_hw_isr -- host adapter interrupt service routine
* @irq: ignored
* @dev_id: pointer to host adapter structure
- * @regs: ignored
*
* The ISR processes done list entries and level 3 error handling.
*/
-irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t asd_hw_isr(int irq, void *dev_id)
{
struct asd_ha_struct *asd_ha = dev_id;
u32 chimint = asd_read_reg_dword(asd_ha, CHIMINT);
@@ -1027,18 +1043,17 @@ irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs)
/* ---------- SCB handling ---------- */
-static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
- gfp_t gfp_flags)
+static struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
+ gfp_t gfp_flags)
{
- extern kmem_cache_t *asd_ascb_cache;
+ extern struct kmem_cache *asd_ascb_cache;
struct asd_seq_data *seq = &asd_ha->seq;
struct asd_ascb *ascb;
unsigned long flags;
- ascb = kmem_cache_alloc(asd_ascb_cache, gfp_flags);
+ ascb = kmem_cache_zalloc(asd_ascb_cache, gfp_flags);
if (ascb) {
- memset(ascb, 0, sizeof(*ascb));
ascb->dma_scb.size = sizeof(struct scb);
ascb->dma_scb.vaddr = dma_pool_alloc(asd_ha->scb_pool,
gfp_flags,
@@ -1128,8 +1143,8 @@ struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct
*
* LOCKING: called with the pending list lock held.
*/
-static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
- struct asd_ascb *ascb)
+static void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
+ struct asd_ascb *ascb)
{
struct asd_seq_data *seq = &asd_ha->seq;
struct asd_ascb *last = list_entry(ascb->list.prev,
@@ -1155,7 +1170,7 @@ static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
* intended to be called from asd_post_ascb_list(), just prior to
* posting the SCBs to the sequencer.
*/
-static inline void asd_start_scb_timers(struct list_head *list)
+static void asd_start_scb_timers(struct list_head *list)
{
struct asd_ascb *ascb;
list_for_each_entry(ascb, list, list) {
@@ -1345,7 +1360,7 @@ int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask)
struct asd_ascb *ascb_list;
if (!phy_mask) {
- asd_printk("%s called with phy_mask of 0!?\n", __FUNCTION__);
+ asd_printk("%s called with phy_mask of 0!?\n", __func__);
return 0;
}