Skip to content

Commit

Permalink
[SCSI] mvsas: fix hot plug handling and IO issues
Browse files Browse the repository at this point in the history
This patch adds a bunch of fixes

1. Reduce sg table size to 64 (SG_MX) instead of default SG_ALL
2. clear task lists on phy down events
3. release all tasks on port deformation
4. release current task for device gone notification
5. Add sata abort handing
6. Add 10ms delay to each port reset (currently done serially and with
   interrupts disabled)

[jejb: whitespace fixes and clean ups plus added description
       added dummy 94xx_clear_srs_irq function just to prevent the
       mismatch in the mvs_dispatch structure killing 94xx cards]
Signed-off-by: Srinivas <satyasrinivasp@hcl.in>
Cc: Andy Yan <ayan@marvell.com>
Cc: qswang@marvell.com
Cc: jfeng@marvell.com
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Srinivas authored and James Bottomley committed Apr 11, 2010
1 parent c803221 commit 9dc9fd9
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 80 deletions.
25 changes: 23 additions & 2 deletions drivers/scsi/mvsas/mv_64xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ static void mvs_64xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
tmp &= ~PHYEV_RDY_CH;
mvs_write_port_irq_stat(mvi, phy_id, tmp);
tmp = mvs_read_phy_ctl(mvi, phy_id);
if (hard)
if (hard == 1)
tmp |= PHY_RST_HARD;
else
else if (hard == 0)
tmp |= PHY_RST;
mvs_write_phy_ctl(mvi, phy_id, tmp);
if (hard) {
Expand All @@ -144,6 +144,26 @@ static void mvs_64xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
}
}

void mvs_64xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all)
{
void __iomem *regs = mvi->regs;
u32 tmp;
if (clear_all) {
tmp = mr32(MVS_INT_STAT_SRS_0);
if (tmp) {
printk(KERN_DEBUG "check SRS 0 %08X.\n", tmp);
mw32(MVS_INT_STAT_SRS_0, tmp);
}
} else {
tmp = mr32(MVS_INT_STAT_SRS_0);
if (tmp & (1 << (reg_set % 32))) {
printk(KERN_DEBUG "register set 0x%x was stopped.\n",
reg_set);
mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32));
}
}
}

static int __devinit mvs_64xx_chip_reset(struct mvs_info *mvi)
{
void __iomem *regs = mvi->regs;
Expand Down Expand Up @@ -761,6 +781,7 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
mvs_write_port_irq_mask,
mvs_get_sas_addr,
mvs_64xx_command_active,
mvs_64xx_clear_srs_irq,
mvs_64xx_issue_stop,
mvs_start_delivery,
mvs_rx_update,
Expand Down
10 changes: 10 additions & 0 deletions drivers/scsi/mvsas/mv_94xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,15 @@ void mvs_94xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd)
}
#endif

/*
* FIXME JEJB: temporary nop clear_srs_irq to make 94xx still work
* with 64xx fixes
*/
static void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set,
u8 clear_all)
{
}

const struct mvs_dispatch mvs_94xx_dispatch = {
"mv94xx",
mvs_94xx_init,
Expand All @@ -640,6 +649,7 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
mvs_write_port_irq_mask,
mvs_get_sas_addr,
mvs_94xx_command_active,
mvs_94xx_clear_srs_irq,
mvs_94xx_issue_stop,
mvs_start_delivery,
mvs_rx_update,
Expand Down
19 changes: 12 additions & 7 deletions drivers/scsi/mvsas/mv_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ static const struct mvs_chip_info mvs_chips[] = {
};

#define SOC_SAS_NUM 2
#define SG_MX 64

static struct scsi_host_template mvs_sht = {
.module = THIS_MODULE,
Expand All @@ -53,10 +54,10 @@ static struct scsi_host_template mvs_sht = {
.can_queue = 1,
.cmd_per_lun = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.sg_tablesize = SG_MX,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_bus_reset_handler = sas_eh_bus_reset_handler,
.slave_alloc = mvs_slave_alloc,
.target_destroy = sas_target_destroy,
Expand All @@ -65,19 +66,17 @@ static struct scsi_host_template mvs_sht = {

static struct sas_domain_function_template mvs_transport_ops = {
.lldd_dev_found = mvs_dev_found,
.lldd_dev_gone = mvs_dev_gone,

.lldd_dev_gone = mvs_dev_gone,
.lldd_execute_task = mvs_queue_command,
.lldd_control_phy = mvs_phy_control,

.lldd_abort_task = mvs_abort_task,
.lldd_abort_task_set = mvs_abort_task_set,
.lldd_clear_aca = mvs_clear_aca,
.lldd_clear_task_set = mvs_clear_task_set,
.lldd_clear_task_set = mvs_clear_task_set,
.lldd_I_T_nexus_reset = mvs_I_T_nexus_reset,
.lldd_lu_reset = mvs_lu_reset,
.lldd_query_task = mvs_query_task,

.lldd_port_formed = mvs_port_formed,
.lldd_port_deformed = mvs_port_deformed,

Expand Down Expand Up @@ -213,7 +212,7 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque)

static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
{
int i, slot_nr;
int i = 0, slot_nr;

if (mvi->flags & MVF_FLAG_SOC)
slot_nr = MVS_SOC_SLOTS;
Expand All @@ -232,6 +231,7 @@ static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
mvi->devices[i].dev_type = NO_DEVICE;
mvi->devices[i].device_id = i;
mvi->devices[i].dev_status = MVS_DEV_NORMAL;
init_timer(&mvi->devices[i].timer);
}

/*
Expand Down Expand Up @@ -437,6 +437,7 @@ static int __devinit mvs_prep_sas_ha_init(struct Scsi_Host *shost,

sha->sas_phy = arr_phy;
sha->sas_port = arr_port;
sha->core.shost = shost;

sha->lldd_ha = kzalloc(sizeof(struct mvs_prv_info), GFP_KERNEL);
if (!sha->lldd_ha)
Expand Down Expand Up @@ -574,6 +575,10 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
}
nhost++;
} while (nhost < chip->n_host);
#ifdef MVS_USE_TASKLET
tasklet_init(&mv_tasklet, mvs_tasklet,
(unsigned long)SHOST_TO_SAS_HA(shost));
#endif

mvs_post_sas_ha_init(shost, chip);

Expand Down
Loading

0 comments on commit 9dc9fd9

Please sign in to comment.