Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 19119
b: refs/heads/master
c: 1341c93
h: refs/heads/master
i:
  19117: 9a25ea1
  19115: c44c9ce
  19111: 3f17165
  19103: 7f8b7bb
v: v3
  • Loading branch information
Sumant Patro authored and James Bottomley committed Jan 29, 2006
1 parent e6d331a commit 5e3846e
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cb59aa6a7ca1ae40fd436c45dff568a83f3fab2f
refs/heads/master: 1341c939222f4d1cc8d9eb2b794f26f089fe0a61
9 changes: 9 additions & 0 deletions trunk/Documentation/scsi/ChangeLog.megaraid_sas
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
1 Release Date : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
2 Current Version : 00.00.02.02
3 Older Version : 00.00.02.01

i. New template defined to represent each family of controllers (identified by processor used).
The template will have defintions that will be initialised to appropritae values for a specific family of controllers. The template definition has four function pointers. During driver initialisation the function pointers will be set based on the controller family type. This change is done to support new controllers that has different processors and thus different register set.

-Sumant Patro <Sumant.Patro@lsil.com>

1 Release Date : Mon Dec 19 14:36:26 PST 2005 - Sumant Patro <Sumant.Patro@lsil.com>
2 Current Version : 00.00.02.00-rc4
3 Older Version : 00.00.02.01
Expand Down
133 changes: 94 additions & 39 deletions trunk/drivers/scsi/megaraid/megaraid_sas.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* 2 of the License, or (at your option) any later version.
*
* FILE : megaraid_sas.c
* Version : v00.00.02.01
* Version : v00.00.02.02
*
* Authors:
* Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
Expand Down Expand Up @@ -55,13 +55,13 @@ static struct pci_device_id megasas_pci_table[] = {

{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_LSI_SAS1064R,
PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP
PCI_ANY_ID,
PCI_ANY_ID,
},
{
PCI_VENDOR_ID_DELL,
PCI_DEVICE_ID_DELL_PERC5,
PCI_DEVICE_ID_DELL_PERC5, // xscale IOP
PCI_ANY_ID,
PCI_ANY_ID,
},
Expand Down Expand Up @@ -119,27 +119,93 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
}


/**
* The following functions are defined for xscale
* (deviceid : 1064R, PERC5) controllers
*/

/**
* megasas_enable_intr - Enables interrupts
* megasas_enable_intr_xscale - Enables interrupts
* @regs: MFI register set
*/
static inline void
megasas_enable_intr(struct megasas_register_set __iomem * regs)
megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
{
writel(1, &(regs)->outbound_intr_mask);

/* Dummy readl to force pci flush */
readl(&regs->outbound_intr_mask);
}

/**
* megasas_read_fw_status_reg_xscale - returns the current FW status value
* @regs: MFI register set
*/
static u32
megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
{
return readl(&(regs)->outbound_msg_0);
}
/**
* megasas_clear_interrupt_xscale - Check & clear interrupt
* @regs: MFI register set
*/
static int
megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
{
u32 status;
/*
* Check if it is our interrupt
*/
status = readl(&regs->outbound_intr_status);

if (!(status & MFI_OB_INTR_STATUS_MASK)) {
return 1;
}

/*
* Clear the interrupt by writing back the same value
*/
writel(status, &regs->outbound_intr_status);

return 0;
}

/**
* megasas_fire_cmd_xscale - Sends command to the FW
* @frame_phys_addr : Physical address of cmd
* @frame_count : Number of frames for the command
* @regs : MFI register set
*/
static inline void
megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
{
writel((frame_phys_addr >> 3)|(frame_count),
&(regs)->inbound_queue_port);
}

static struct megasas_instance_template megasas_instance_template_xscale = {

.fire_cmd = megasas_fire_cmd_xscale,
.enable_intr = megasas_enable_intr_xscale,
.clear_intr = megasas_clear_intr_xscale,
.read_fw_status_reg = megasas_read_fw_status_reg_xscale,
};

/**
* This is the end of set of functions & definitions specific
* to xscale (deviceid : 1064R, PERC5) controllers
*/

/**
* megasas_disable_intr - Disables interrupts
* @regs: MFI register set
*/
static inline void
megasas_disable_intr(struct megasas_register_set __iomem * regs)
{
u32 mask = readl(&regs->outbound_intr_mask) & (~0x00000001);
u32 mask = 0x1f;
writel(mask, &regs->outbound_intr_mask);

/* Dummy readl to force pci flush */
Expand Down Expand Up @@ -167,8 +233,7 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
/*
* Issue the frame using inbound queue port
*/
writel(cmd->frame_phys_addr >> 3,
&instance->reg_set->inbound_queue_port);
instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);

/*
* Wait for cmd_status to change
Expand Down Expand Up @@ -198,8 +263,7 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
{
cmd->cmd_status = ENODATA;

writel(cmd->frame_phys_addr >> 3,
&instance->reg_set->inbound_queue_port);
instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);

wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA));

Expand Down Expand Up @@ -242,8 +306,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
cmd->sync_cmd = 1;
cmd->cmd_status = 0xFF;

writel(cmd->frame_phys_addr >> 3,
&instance->reg_set->inbound_queue_port);
instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);

/*
* Wait for this cmd to complete
Expand Down Expand Up @@ -633,8 +696,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
instance->fw_outstanding++;
spin_unlock_irqrestore(&instance->instance_lock, flags);

writel(((cmd->frame_phys_addr >> 3) | (cmd->frame_count - 1)),
&instance->reg_set->inbound_queue_port);
instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);

return 0;

Expand Down Expand Up @@ -1045,25 +1107,17 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
static int
megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
{
u32 status;
u32 producer;
u32 consumer;
u32 context;
struct megasas_cmd *cmd;

/*
* Check if it is our interrupt
* Clear the interrupt
*/
status = readl(&instance->reg_set->outbound_intr_status);

if (!(status & MFI_OB_INTR_STATUS_MASK)) {
if(instance->instancet->clear_intr(instance->reg_set))
return IRQ_NONE;
}

/*
* Clear the interrupt by writing back the same value
*/
writel(status, &instance->reg_set->outbound_intr_status);

producer = *instance->producer;
consumer = *instance->consumer;
Expand Down Expand Up @@ -1097,22 +1151,22 @@ static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs)

/**
* megasas_transition_to_ready - Move the FW to READY state
* @reg_set: MFI register set
* @instance: Adapter soft state
*
* During the initialization, FW passes can potentially be in any one of
* several possible states. If the FW in operational, waiting-for-handshake
* states, driver must take steps to bring it to ready state. Otherwise, it
* has to wait for the ready state.
*/
static int
megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
megasas_transition_to_ready(struct megasas_instance* instance)
{
int i;
u8 max_wait;
u32 fw_state;
u32 cur_state;

fw_state = readl(&reg_set->outbound_msg_0) & MFI_STATE_MASK;
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;

while (fw_state != MFI_STATE_READY) {

Expand All @@ -1130,7 +1184,7 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
* Set the CLR bit in inbound doorbell
*/
writel(MFI_INIT_CLEAR_HANDSHAKE,
&reg_set->inbound_doorbell);
&instance->reg_set->inbound_doorbell);

max_wait = 2;
cur_state = MFI_STATE_WAIT_HANDSHAKE;
Expand All @@ -1140,8 +1194,8 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
/*
* Bring it to READY state; assuming max wait 2 secs
*/
megasas_disable_intr(reg_set);
writel(MFI_INIT_READY, &reg_set->inbound_doorbell);
megasas_disable_intr(instance->reg_set);
writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell);

max_wait = 10;
cur_state = MFI_STATE_OPERATIONAL;
Expand Down Expand Up @@ -1190,8 +1244,8 @@ megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
* The cur_state should not last for more than max_wait secs
*/
for (i = 0; i < (max_wait * 1000); i++) {
fw_state = MFI_STATE_MASK &
readl(&reg_set->outbound_msg_0);
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
MFI_STATE_MASK ;

if (fw_state == cur_state) {
msleep(1);
Expand Down Expand Up @@ -1553,18 +1607,20 @@ static int megasas_init_mfi(struct megasas_instance *instance)

reg_set = instance->reg_set;

instance->instancet = &megasas_instance_template_xscale;

/*
* We expect the FW state to be READY
*/
if (megasas_transition_to_ready(instance->reg_set))
if (megasas_transition_to_ready(instance))
goto fail_ready_state;

/*
* Get various operational parameters from status register
*/
instance->max_fw_cmds = readl(&reg_set->outbound_msg_0) & 0x00FFFF;
instance->max_num_sge = (readl(&reg_set->outbound_msg_0) & 0xFF0000) >>
0x10;
instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
0x10;
/*
* Create a pool of commands
*/
Expand Down Expand Up @@ -1873,8 +1929,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
/*
* Issue the aen registration frame
*/
writel(cmd->frame_phys_addr >> 3,
&instance->reg_set->inbound_queue_port);
instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);

return 0;
}
Expand Down Expand Up @@ -2063,7 +2118,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto fail_irq;
}

megasas_enable_intr(instance->reg_set);
instance->instancet->enable_intr(instance->reg_set);

/*
* Store instance in PCI softstate
Expand Down
18 changes: 15 additions & 3 deletions trunk/drivers/scsi/megaraid/megaraid_sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
/**
* MegaRAID SAS Driver meta data
*/
#define MEGASAS_VERSION "00.00.02.01"
#define MEGASAS_RELDATE "Dec 19, 2005"
#define MEGASAS_EXT_VERSION "Mon Dec 19 14:36:26 PST 2005"
#define MEGASAS_VERSION "00.00.02.02"
#define MEGASAS_RELDATE "Jan 23, 2006"
#define MEGASAS_EXT_VERSION "Mon Jan 23 14:09:01 PST 2006"
/*
* =====================================
* MegaRAID SAS MFI firmware definitions
Expand Down Expand Up @@ -1012,6 +1012,16 @@ struct megasas_evt_detail {

} __attribute__ ((packed));

struct megasas_instance_template {
void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);

void (*enable_intr)(struct megasas_register_set __iomem *) ;

int (*clear_intr)(struct megasas_register_set __iomem *);

u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
};

struct megasas_instance {

u32 *producer;
Expand Down Expand Up @@ -1055,6 +1065,8 @@ struct megasas_instance {
u32 fw_outstanding;
u32 hw_crit_error;
spinlock_t instance_lock;

struct megasas_instance_template *instancet;
};

#define MEGASAS_IS_LOGICAL(scp) \
Expand Down

0 comments on commit 5e3846e

Please sign in to comment.