aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSrinivas <satyasrinivasp@hcl.in>2010-02-15 01:00:00 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 15:44:01 -0400
commit9dc9fd9484c5168d23fe855e6c56543d96b6695b (patch)
tree514bbe305138f21af247441f535e20430c3829b6 /drivers
parentc8032216c9607ee8c62a39484711750c1445c6a4 (diff)
[SCSI] mvsas: fix hot plug handling and IO issues
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/mvsas/mv_64xx.c25
-rw-r--r--drivers/scsi/mvsas/mv_94xx.c10
-rw-r--r--drivers/scsi/mvsas/mv_init.c19
-rw-r--r--drivers/scsi/mvsas/mv_sas.c201
-rw-r--r--drivers/scsi/mvsas/mv_sas.h11
5 files changed, 186 insertions, 80 deletions
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c
index 10a5077b6aed..afc7f6f3a13e 100644
--- a/drivers/scsi/mvsas/mv_64xx.c
+++ b/drivers/scsi/mvsas/mv_64xx.c
@@ -132,9 +132,9 @@ static void mvs_64xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
132 tmp &= ~PHYEV_RDY_CH; 132 tmp &= ~PHYEV_RDY_CH;
133 mvs_write_port_irq_stat(mvi, phy_id, tmp); 133 mvs_write_port_irq_stat(mvi, phy_id, tmp);
134 tmp = mvs_read_phy_ctl(mvi, phy_id); 134 tmp = mvs_read_phy_ctl(mvi, phy_id);
135 if (hard) 135 if (hard == 1)
136 tmp |= PHY_RST_HARD; 136 tmp |= PHY_RST_HARD;
137 else 137 else if (hard == 0)
138 tmp |= PHY_RST; 138 tmp |= PHY_RST;
139 mvs_write_phy_ctl(mvi, phy_id, tmp); 139 mvs_write_phy_ctl(mvi, phy_id, tmp);
140 if (hard) { 140 if (hard) {
@@ -144,6 +144,26 @@ static void mvs_64xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
144 } 144 }
145} 145}
146 146
147void mvs_64xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all)
148{
149 void __iomem *regs = mvi->regs;
150 u32 tmp;
151 if (clear_all) {
152 tmp = mr32(MVS_INT_STAT_SRS_0);
153 if (tmp) {
154 printk(KERN_DEBUG "check SRS 0 %08X.\n", tmp);
155 mw32(MVS_INT_STAT_SRS_0, tmp);
156 }
157 } else {
158 tmp = mr32(MVS_INT_STAT_SRS_0);
159 if (tmp & (1 << (reg_set % 32))) {
160 printk(KERN_DEBUG "register set 0x%x was stopped.\n",
161 reg_set);
162 mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32));
163 }
164 }
165}
166
147static int __devinit mvs_64xx_chip_reset(struct mvs_info *mvi) 167static int __devinit mvs_64xx_chip_reset(struct mvs_info *mvi)
148{ 168{
149 void __iomem *regs = mvi->regs; 169 void __iomem *regs = mvi->regs;
@@ -761,6 +781,7 @@ const struct mvs_dispatch mvs_64xx_dispatch = {
761 mvs_write_port_irq_mask, 781 mvs_write_port_irq_mask,
762 mvs_get_sas_addr, 782 mvs_get_sas_addr,
763 mvs_64xx_command_active, 783 mvs_64xx_command_active,
784 mvs_64xx_clear_srs_irq,
764 mvs_64xx_issue_stop, 785 mvs_64xx_issue_stop,
765 mvs_start_delivery, 786 mvs_start_delivery,
766 mvs_rx_update, 787 mvs_rx_update,
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c
index 0940fae19d20..eed4c5c72013 100644
--- a/drivers/scsi/mvsas/mv_94xx.c
+++ b/drivers/scsi/mvsas/mv_94xx.c
@@ -616,6 +616,15 @@ void mvs_94xx_fix_dma(dma_addr_t buf_dma, int buf_len, int from, void *prd)
616} 616}
617#endif 617#endif
618 618
619/*
620 * FIXME JEJB: temporary nop clear_srs_irq to make 94xx still work
621 * with 64xx fixes
622 */
623static void mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set,
624 u8 clear_all)
625{
626}
627
619const struct mvs_dispatch mvs_94xx_dispatch = { 628const struct mvs_dispatch mvs_94xx_dispatch = {
620 "mv94xx", 629 "mv94xx",
621 mvs_94xx_init, 630 mvs_94xx_init,
@@ -640,6 +649,7 @@ const struct mvs_dispatch mvs_94xx_dispatch = {
640 mvs_write_port_irq_mask, 649 mvs_write_port_irq_mask,
641 mvs_get_sas_addr, 650 mvs_get_sas_addr,
642 mvs_94xx_command_active, 651 mvs_94xx_command_active,
652 mvs_94xx_clear_srs_irq,
643 mvs_94xx_issue_stop, 653 mvs_94xx_issue_stop,
644 mvs_start_delivery, 654 mvs_start_delivery,
645 mvs_rx_update, 655 mvs_rx_update,
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index cae6b2cf492f..19ad34f381a5 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -37,6 +37,7 @@ static const struct mvs_chip_info mvs_chips[] = {
37}; 37};
38 38
39#define SOC_SAS_NUM 2 39#define SOC_SAS_NUM 2
40#define SG_MX 64
40 41
41static struct scsi_host_template mvs_sht = { 42static struct scsi_host_template mvs_sht = {
42 .module = THIS_MODULE, 43 .module = THIS_MODULE,
@@ -53,10 +54,10 @@ static struct scsi_host_template mvs_sht = {
53 .can_queue = 1, 54 .can_queue = 1,
54 .cmd_per_lun = 1, 55 .cmd_per_lun = 1,
55 .this_id = -1, 56 .this_id = -1,
56 .sg_tablesize = SG_ALL, 57 .sg_tablesize = SG_MX,
57 .max_sectors = SCSI_DEFAULT_MAX_SECTORS, 58 .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
58 .use_clustering = ENABLE_CLUSTERING, 59 .use_clustering = ENABLE_CLUSTERING,
59 .eh_device_reset_handler = sas_eh_device_reset_handler, 60 .eh_device_reset_handler = sas_eh_device_reset_handler,
60 .eh_bus_reset_handler = sas_eh_bus_reset_handler, 61 .eh_bus_reset_handler = sas_eh_bus_reset_handler,
61 .slave_alloc = mvs_slave_alloc, 62 .slave_alloc = mvs_slave_alloc,
62 .target_destroy = sas_target_destroy, 63 .target_destroy = sas_target_destroy,
@@ -65,19 +66,17 @@ static struct scsi_host_template mvs_sht = {
65 66
66static struct sas_domain_function_template mvs_transport_ops = { 67static struct sas_domain_function_template mvs_transport_ops = {
67 .lldd_dev_found = mvs_dev_found, 68 .lldd_dev_found = mvs_dev_found,
68 .lldd_dev_gone = mvs_dev_gone, 69 .lldd_dev_gone = mvs_dev_gone,
69
70 .lldd_execute_task = mvs_queue_command, 70 .lldd_execute_task = mvs_queue_command,
71 .lldd_control_phy = mvs_phy_control, 71 .lldd_control_phy = mvs_phy_control,
72 72
73 .lldd_abort_task = mvs_abort_task, 73 .lldd_abort_task = mvs_abort_task,
74 .lldd_abort_task_set = mvs_abort_task_set, 74 .lldd_abort_task_set = mvs_abort_task_set,
75 .lldd_clear_aca = mvs_clear_aca, 75 .lldd_clear_aca = mvs_clear_aca,
76 .lldd_clear_task_set = mvs_clear_task_set, 76 .lldd_clear_task_set = mvs_clear_task_set,
77 .lldd_I_T_nexus_reset = mvs_I_T_nexus_reset, 77 .lldd_I_T_nexus_reset = mvs_I_T_nexus_reset,
78 .lldd_lu_reset = mvs_lu_reset, 78 .lldd_lu_reset = mvs_lu_reset,
79 .lldd_query_task = mvs_query_task, 79 .lldd_query_task = mvs_query_task,
80
81 .lldd_port_formed = mvs_port_formed, 80 .lldd_port_formed = mvs_port_formed,
82 .lldd_port_deformed = mvs_port_deformed, 81 .lldd_port_deformed = mvs_port_deformed,
83 82
@@ -213,7 +212,7 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque)
213 212
214static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) 213static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
215{ 214{
216 int i, slot_nr; 215 int i = 0, slot_nr;
217 216
218 if (mvi->flags & MVF_FLAG_SOC) 217 if (mvi->flags & MVF_FLAG_SOC)
219 slot_nr = MVS_SOC_SLOTS; 218 slot_nr = MVS_SOC_SLOTS;
@@ -232,6 +231,7 @@ static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
232 mvi->devices[i].dev_type = NO_DEVICE; 231 mvi->devices[i].dev_type = NO_DEVICE;
233 mvi->devices[i].device_id = i; 232 mvi->devices[i].device_id = i;
234 mvi->devices[i].dev_status = MVS_DEV_NORMAL; 233 mvi->devices[i].dev_status = MVS_DEV_NORMAL;
234 init_timer(&mvi->devices[i].timer);
235 } 235 }
236 236
237 /* 237 /*
@@ -437,6 +437,7 @@ static int __devinit mvs_prep_sas_ha_init(struct Scsi_Host *shost,
437 437
438 sha->sas_phy = arr_phy; 438 sha->sas_phy = arr_phy;
439 sha->sas_port = arr_port; 439 sha->sas_port = arr_port;
440 sha->core.shost = shost;
440 441
441 sha->lldd_ha = kzalloc(sizeof(struct mvs_prv_info), GFP_KERNEL); 442 sha->lldd_ha = kzalloc(sizeof(struct mvs_prv_info), GFP_KERNEL);
442 if (!sha->lldd_ha) 443 if (!sha->lldd_ha)
@@ -574,6 +575,10 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
574 } 575 }
575 nhost++; 576 nhost++;
576 } while (nhost < chip->n_host); 577 } while (nhost < chip->n_host);
578#ifdef MVS_USE_TASKLET
579 tasklet_init(&mv_tasklet, mvs_tasklet,
580 (unsigned long)SHOST_TO_SAS_HA(shost));
581#endif
577 582
578 mvs_post_sas_ha_init(shost, chip); 583 mvs_post_sas_ha_init(shost, chip);
579 584
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 0d2138641214..f5e321791903 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -259,8 +259,6 @@ static inline void mvs_free_reg_set(struct mvs_info *mvi,
259 mv_printk("device has been free.\n"); 259 mv_printk("device has been free.\n");
260 return; 260 return;
261 } 261 }
262 if (dev->runing_req != 0)
263 return;
264 if (dev->taskfileset == MVS_ID_NOT_MAPPED) 262 if (dev->taskfileset == MVS_ID_NOT_MAPPED)
265 return; 263 return;
266 MVS_CHIP_DISP->free_reg_set(mvi, &dev->taskfileset); 264 MVS_CHIP_DISP->free_reg_set(mvi, &dev->taskfileset);
@@ -762,8 +760,6 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi,
762 } 760 }
763 if (is_tmf) 761 if (is_tmf)
764 flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT); 762 flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT);
765 else
766 flags |= (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT);
767 hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT)); 763 hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT));
768 hdr->tags = cpu_to_le32(tag); 764 hdr->tags = cpu_to_le32(tag);
769 hdr->data_len = cpu_to_le32(task->total_xfer_len); 765 hdr->data_len = cpu_to_le32(task->total_xfer_len);
@@ -878,14 +874,15 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
878 struct mvs_slot_info *slot; 874 struct mvs_slot_info *slot;
879 u32 tag = 0xdeadbeef, rc, n_elem = 0; 875 u32 tag = 0xdeadbeef, rc, n_elem = 0;
880 u32 n = num, pass = 0; 876 u32 n = num, pass = 0;
881 unsigned long flags = 0; 877 unsigned long flags = 0, flags_libsas = 0;
882 878
883 if (!dev->port) { 879 if (!dev->port) {
884 struct task_status_struct *tsm = &t->task_status; 880 struct task_status_struct *tsm = &t->task_status;
885 881
886 tsm->resp = SAS_TASK_UNDELIVERED; 882 tsm->resp = SAS_TASK_UNDELIVERED;
887 tsm->stat = SAS_PHY_DOWN; 883 tsm->stat = SAS_PHY_DOWN;
888 t->task_done(t); 884 if (dev->dev_type != SATA_DEV)
885 t->task_done(t);
889 return 0; 886 return 0;
890 } 887 }
891 888
@@ -910,12 +907,25 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
910 else 907 else
911 tei.port = &mvi->port[dev->port->id]; 908 tei.port = &mvi->port[dev->port->id];
912 909
913 if (!tei.port->port_attached) { 910 if (tei.port && !tei.port->port_attached) {
914 if (sas_protocol_ata(t->task_proto)) { 911 if (sas_protocol_ata(t->task_proto)) {
912 struct task_status_struct *ts = &t->task_status;
913
915 mv_dprintk("port %d does not" 914 mv_dprintk("port %d does not"
916 "attached device.\n", dev->port->id); 915 "attached device.\n", dev->port->id);
917 rc = SAS_PHY_DOWN; 916 ts->stat = SAS_PROTO_RESPONSE;
918 goto out_done; 917 ts->stat = SAS_PHY_DOWN;
918 spin_unlock_irqrestore(dev->sata_dev.ap->lock,
919 flags_libsas);
920 spin_unlock_irqrestore(&mvi->lock, flags);
921 t->task_done(t);
922 spin_lock_irqsave(&mvi->lock, flags);
923 spin_lock_irqsave(dev->sata_dev.ap->lock,
924 flags_libsas);
925 if (n > 1)
926 t = list_entry(t->list.next,
927 struct sas_task, list);
928 continue;
919 } else { 929 } else {
920 struct task_status_struct *ts = &t->task_status; 930 struct task_status_struct *ts = &t->task_status;
921 ts->resp = SAS_TASK_UNDELIVERED; 931 ts->resp = SAS_TASK_UNDELIVERED;
@@ -973,8 +983,8 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
973 break; 983 break;
974 default: 984 default:
975 dev_printk(KERN_ERR, mvi->dev, 985 dev_printk(KERN_ERR, mvi->dev,
976 "unknown sas_task proto: 0x%x\n", 986 "unknown sas_task proto: 0x%x\n",
977 t->task_proto); 987 t->task_proto);
978 rc = -EINVAL; 988 rc = -EINVAL;
979 break; 989 break;
980 } 990 }
@@ -993,11 +1003,15 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
993 spin_unlock(&t->task_state_lock); 1003 spin_unlock(&t->task_state_lock);
994 1004
995 mvs_hba_memory_dump(mvi, tag, t->task_proto); 1005 mvs_hba_memory_dump(mvi, tag, t->task_proto);
996 mvi_dev->runing_req++; 1006 mvi_dev->running_req++;
997 ++pass; 1007 ++pass;
998 mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1); 1008 mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
999 if (n > 1) 1009 if (n > 1)
1000 t = list_entry(t->list.next, struct sas_task, list); 1010 t = list_entry(t->list.next, struct sas_task, list);
1011 if (likely(pass))
1012 MVS_CHIP_DISP->start_delivery(mvi, (mvi->tx_prod - 1) &
1013 (MVS_CHIP_SLOT_SZ - 1));
1014
1001 } while (--n); 1015 } while (--n);
1002 rc = 0; 1016 rc = 0;
1003 goto out_done; 1017 goto out_done;
@@ -1012,10 +1026,6 @@ err_out:
1012 dma_unmap_sg(mvi->dev, t->scatter, n_elem, 1026 dma_unmap_sg(mvi->dev, t->scatter, n_elem,
1013 t->data_dir); 1027 t->data_dir);
1014out_done: 1028out_done:
1015 if (likely(pass)) {
1016 MVS_CHIP_DISP->start_delivery(mvi,
1017 (mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
1018 }
1019 spin_unlock_irqrestore(&mvi->lock, flags); 1029 spin_unlock_irqrestore(&mvi->lock, flags);
1020 return rc; 1030 return rc;
1021} 1031}
@@ -1187,7 +1197,7 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st)
1187 MVS_CHIP_DISP->phy_reset(mvi, i, 0); 1197 MVS_CHIP_DISP->phy_reset(mvi, i, 0);
1188 goto out_done; 1198 goto out_done;
1189 } 1199 }
1190 } else if (phy->phy_type & PORT_TYPE_SAS 1200 } else if (phy->phy_type & PORT_TYPE_SAS
1191 || phy->att_dev_info & PORT_SSP_INIT_MASK) { 1201 || phy->att_dev_info & PORT_SSP_INIT_MASK) {
1192 phy->phy_attached = 1; 1202 phy->phy_attached = 1;
1193 phy->identify.device_type = 1203 phy->identify.device_type =
@@ -1256,7 +1266,20 @@ static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock)
1256 1266
1257static void mvs_port_notify_deformed(struct asd_sas_phy *sas_phy, int lock) 1267static void mvs_port_notify_deformed(struct asd_sas_phy *sas_phy, int lock)
1258{ 1268{
1259 /*Nothing*/ 1269 struct domain_device *dev;
1270 struct mvs_phy *phy = sas_phy->lldd_phy;
1271 struct mvs_info *mvi = phy->mvi;
1272 struct asd_sas_port *port = sas_phy->port;
1273 int phy_no = 0;
1274
1275 while (phy != &mvi->phy[phy_no]) {
1276 phy_no++;
1277 if (phy_no >= MVS_MAX_PHYS)
1278 return;
1279 }
1280 list_for_each_entry(dev, &port->dev_list, dev_list_node)
1281 mvs_do_release_task(phy->mvi, phy_no, NULL);
1282
1260} 1283}
1261 1284
1262 1285
@@ -1316,6 +1339,7 @@ int mvs_dev_found_notify(struct domain_device *dev, int lock)
1316 goto found_out; 1339 goto found_out;
1317 } 1340 }
1318 dev->lldd_dev = mvi_device; 1341 dev->lldd_dev = mvi_device;
1342 mvi_device->dev_status = MVS_DEV_NORMAL;
1319 mvi_device->dev_type = dev->dev_type; 1343 mvi_device->dev_type = dev->dev_type;
1320 mvi_device->mvi_info = mvi; 1344 mvi_device->mvi_info = mvi;
1321 if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) { 1345 if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) {
@@ -1351,18 +1375,18 @@ int mvs_dev_found(struct domain_device *dev)
1351 return mvs_dev_found_notify(dev, 1); 1375 return mvs_dev_found_notify(dev, 1);
1352} 1376}
1353 1377
1354void mvs_dev_gone_notify(struct domain_device *dev, int lock) 1378void mvs_dev_gone_notify(struct domain_device *dev)
1355{ 1379{
1356 unsigned long flags = 0; 1380 unsigned long flags = 0;
1357 struct mvs_device *mvi_dev = dev->lldd_dev; 1381 struct mvs_device *mvi_dev = dev->lldd_dev;
1358 struct mvs_info *mvi = mvi_dev->mvi_info; 1382 struct mvs_info *mvi = mvi_dev->mvi_info;
1359 1383
1360 if (lock) 1384 spin_lock_irqsave(&mvi->lock, flags);
1361 spin_lock_irqsave(&mvi->lock, flags);
1362 1385
1363 if (mvi_dev) { 1386 if (mvi_dev) {
1364 mv_dprintk("found dev[%d:%x] is gone.\n", 1387 mv_dprintk("found dev[%d:%x] is gone.\n",
1365 mvi_dev->device_id, mvi_dev->dev_type); 1388 mvi_dev->device_id, mvi_dev->dev_type);
1389 mvs_release_task(mvi, dev);
1366 mvs_free_reg_set(mvi, mvi_dev); 1390 mvs_free_reg_set(mvi, mvi_dev);
1367 mvs_free_dev(mvi_dev); 1391 mvs_free_dev(mvi_dev);
1368 } else { 1392 } else {
@@ -1370,14 +1394,13 @@ void mvs_dev_gone_notify(struct domain_device *dev, int lock)
1370 } 1394 }
1371 dev->lldd_dev = NULL; 1395 dev->lldd_dev = NULL;
1372 1396
1373 if (lock) 1397 spin_unlock_irqrestore(&mvi->lock, flags);
1374 spin_unlock_irqrestore(&mvi->lock, flags);
1375} 1398}
1376 1399
1377 1400
1378void mvs_dev_gone(struct domain_device *dev) 1401void mvs_dev_gone(struct domain_device *dev)
1379{ 1402{
1380 mvs_dev_gone_notify(dev, 1); 1403 mvs_dev_gone_notify(dev);
1381} 1404}
1382 1405
1383static struct sas_task *mvs_alloc_task(void) 1406static struct sas_task *mvs_alloc_task(void)
@@ -1540,7 +1563,7 @@ int mvs_lu_reset(struct domain_device *dev, u8 *lun)
1540 num = mvs_find_dev_phyno(dev, phyno); 1563 num = mvs_find_dev_phyno(dev, phyno);
1541 spin_lock_irqsave(&mvi->lock, flags); 1564 spin_lock_irqsave(&mvi->lock, flags);
1542 for (i = 0; i < num; i++) 1565 for (i = 0; i < num; i++)
1543 mvs_release_task(mvi, phyno[i], dev); 1566 mvs_release_task(mvi, dev);
1544 spin_unlock_irqrestore(&mvi->lock, flags); 1567 spin_unlock_irqrestore(&mvi->lock, flags);
1545 } 1568 }
1546 /* If failed, fall-through I_T_Nexus reset */ 1569 /* If failed, fall-through I_T_Nexus reset */
@@ -1552,8 +1575,8 @@ int mvs_lu_reset(struct domain_device *dev, u8 *lun)
1552int mvs_I_T_nexus_reset(struct domain_device *dev) 1575int mvs_I_T_nexus_reset(struct domain_device *dev)
1553{ 1576{
1554 unsigned long flags; 1577 unsigned long flags;
1555 int i, phyno[WIDE_PORT_MAX_PHY], num , rc = TMF_RESP_FUNC_FAILED; 1578 int rc = TMF_RESP_FUNC_FAILED;
1556 struct mvs_device * mvi_dev = (struct mvs_device *)dev->lldd_dev; 1579 struct mvs_device * mvi_dev = (struct mvs_device *)dev->lldd_dev;
1557 struct mvs_info *mvi = mvi_dev->mvi_info; 1580 struct mvs_info *mvi = mvi_dev->mvi_info;
1558 1581
1559 if (mvi_dev->dev_status != MVS_DEV_EH) 1582 if (mvi_dev->dev_status != MVS_DEV_EH)
@@ -1563,10 +1586,8 @@ int mvs_I_T_nexus_reset(struct domain_device *dev)
1563 __func__, mvi_dev->device_id, rc); 1586 __func__, mvi_dev->device_id, rc);
1564 1587
1565 /* housekeeper */ 1588 /* housekeeper */
1566 num = mvs_find_dev_phyno(dev, phyno);
1567 spin_lock_irqsave(&mvi->lock, flags); 1589 spin_lock_irqsave(&mvi->lock, flags);
1568 for (i = 0; i < num; i++) 1590 mvs_release_task(mvi, dev);
1569 mvs_release_task(mvi, phyno[i], dev);
1570 spin_unlock_irqrestore(&mvi->lock, flags); 1591 spin_unlock_irqrestore(&mvi->lock, flags);
1571 1592
1572 return rc; 1593 return rc;
@@ -1603,6 +1624,9 @@ int mvs_query_task(struct sas_task *task)
1603 case TMF_RESP_FUNC_FAILED: 1624 case TMF_RESP_FUNC_FAILED:
1604 case TMF_RESP_FUNC_COMPLETE: 1625 case TMF_RESP_FUNC_COMPLETE:
1605 break; 1626 break;
1627 default:
1628 rc = TMF_RESP_FUNC_COMPLETE;
1629 break;
1606 } 1630 }
1607 } 1631 }
1608 mv_printk("%s:rc= %d\n", __func__, rc); 1632 mv_printk("%s:rc= %d\n", __func__, rc);
@@ -1621,8 +1645,11 @@ int mvs_abort_task(struct sas_task *task)
1621 unsigned long flags; 1645 unsigned long flags;
1622 u32 tag; 1646 u32 tag;
1623 1647
1624 if (mvi->exp_req) 1648 if (!mvi_dev) {
1625 mvi->exp_req--; 1649 mv_printk("%s:%d TMF_RESP_FUNC_FAILED\n", __func__, __LINE__);
1650 rc = TMF_RESP_FUNC_FAILED;
1651 }
1652
1626 spin_lock_irqsave(&task->task_state_lock, flags); 1653 spin_lock_irqsave(&task->task_state_lock, flags);
1627 if (task->task_state_flags & SAS_TASK_STATE_DONE) { 1654 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
1628 spin_unlock_irqrestore(&task->task_state_lock, flags); 1655 spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -1630,6 +1657,7 @@ int mvs_abort_task(struct sas_task *task)
1630 goto out; 1657 goto out;
1631 } 1658 }
1632 spin_unlock_irqrestore(&task->task_state_lock, flags); 1659 spin_unlock_irqrestore(&task->task_state_lock, flags);
1660 mvi_dev->dev_status = MVS_DEV_EH;
1633 if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { 1661 if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
1634 struct scsi_cmnd * cmnd = (struct scsi_cmnd *)task->uldd_task; 1662 struct scsi_cmnd * cmnd = (struct scsi_cmnd *)task->uldd_task;
1635 1663
@@ -1654,12 +1682,31 @@ int mvs_abort_task(struct sas_task *task)
1654 if (task->lldd_task) { 1682 if (task->lldd_task) {
1655 slot = task->lldd_task; 1683 slot = task->lldd_task;
1656 slot_no = (u32) (slot - mvi->slot_info); 1684 slot_no = (u32) (slot - mvi->slot_info);
1685 spin_lock_irqsave(&mvi->lock, flags);
1657 mvs_slot_complete(mvi, slot_no, 1); 1686 mvs_slot_complete(mvi, slot_no, 1);
1687 spin_unlock_irqrestore(&mvi->lock, flags);
1658 } 1688 }
1659 } 1689 }
1690
1660 } else if (task->task_proto & SAS_PROTOCOL_SATA || 1691 } else if (task->task_proto & SAS_PROTOCOL_SATA ||
1661 task->task_proto & SAS_PROTOCOL_STP) { 1692 task->task_proto & SAS_PROTOCOL_STP) {
1662 /* to do free register_set */ 1693 /* to do free register_set */
1694 if (SATA_DEV == dev->dev_type) {
1695 struct mvs_slot_info *slot = task->lldd_task;
1696 struct task_status_struct *tstat;
1697 u32 slot_idx = (u32)(slot - mvi->slot_info);
1698 tstat = &task->task_status;
1699 mv_dprintk(KERN_DEBUG "mv_abort_task() mvi=%p task=%p "
1700 "slot=%p slot_idx=x%x\n",
1701 mvi, task, slot, slot_idx);
1702 tstat->stat = SAS_ABORTED_TASK;
1703 if (mvi_dev && mvi_dev->running_req)
1704 mvi_dev->running_req--;
1705 if (sas_protocol_ata(task->task_proto))
1706 mvs_free_reg_set(mvi, mvi_dev);
1707 mvs_slot_task_free(mvi, task, slot, slot_idx);
1708 return -1;
1709 }
1663 } else { 1710 } else {
1664 /* SMP */ 1711 /* SMP */
1665 1712
@@ -1717,8 +1764,13 @@ static int mvs_sata_done(struct mvs_info *mvi, struct sas_task *task,
1717 SATA_RECEIVED_D2H_FIS(mvi_dev->taskfileset), 1764 SATA_RECEIVED_D2H_FIS(mvi_dev->taskfileset),
1718 sizeof(struct dev_to_host_fis)); 1765 sizeof(struct dev_to_host_fis));
1719 tstat->buf_valid_size = sizeof(*resp); 1766 tstat->buf_valid_size = sizeof(*resp);
1720 if (unlikely(err)) 1767 if (unlikely(err)) {
1721 stat = SAS_PROTO_RESPONSE; 1768 if (unlikely(err & CMD_ISS_STPD))
1769 stat = SAS_OPEN_REJECT;
1770 else
1771 stat = SAS_PROTO_RESPONSE;
1772 }
1773
1722 return stat; 1774 return stat;
1723} 1775}
1724 1776
@@ -1753,9 +1805,7 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
1753 mv_printk("find reserved error, why?\n"); 1805 mv_printk("find reserved error, why?\n");
1754 1806
1755 task->ata_task.use_ncq = 0; 1807 task->ata_task.use_ncq = 0;
1756 stat = SAS_PROTO_RESPONSE; 1808 mvs_sata_done(mvi, task, slot_idx, err_dw0);
1757 mvs_sata_done(mvi, task, slot_idx, 1);
1758
1759 } 1809 }
1760 break; 1810 break;
1761 default: 1811 default:
@@ -1772,18 +1822,20 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
1772 struct sas_task *task = slot->task; 1822 struct sas_task *task = slot->task;
1773 struct mvs_device *mvi_dev = NULL; 1823 struct mvs_device *mvi_dev = NULL;
1774 struct task_status_struct *tstat; 1824 struct task_status_struct *tstat;
1825 struct domain_device *dev;
1826 u32 aborted;
1775 1827
1776 bool aborted;
1777 void *to; 1828 void *to;
1778 enum exec_status sts; 1829 enum exec_status sts;
1779 1830
1780 if (mvi->exp_req) 1831 if (mvi->exp_req)
1781 mvi->exp_req--; 1832 mvi->exp_req--;
1782 if (unlikely(!task || !task->lldd_task)) 1833 if (unlikely(!task || !task->lldd_task || !task->dev))
1783 return -1; 1834 return -1;
1784 1835
1785 tstat = &task->task_status; 1836 tstat = &task->task_status;
1786 mvi_dev = task->dev->lldd_dev; 1837 dev = task->dev;
1838 mvi_dev = dev->lldd_dev;
1787 1839
1788 mvs_hba_cq_dump(mvi); 1840 mvs_hba_cq_dump(mvi);
1789 1841
@@ -1800,8 +1852,8 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
1800 1852
1801 if (unlikely(aborted)) { 1853 if (unlikely(aborted)) {
1802 tstat->stat = SAS_ABORTED_TASK; 1854 tstat->stat = SAS_ABORTED_TASK;
1803 if (mvi_dev) 1855 if (mvi_dev && mvi_dev->running_req)
1804 mvi_dev->runing_req--; 1856 mvi_dev->running_req--;
1805 if (sas_protocol_ata(task->task_proto)) 1857 if (sas_protocol_ata(task->task_proto))
1806 mvs_free_reg_set(mvi, mvi_dev); 1858 mvs_free_reg_set(mvi, mvi_dev);
1807 1859
@@ -1809,24 +1861,17 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
1809 return -1; 1861 return -1;
1810 } 1862 }
1811 1863
1812 if (unlikely(!mvi_dev || !slot->port->port_attached || flags)) { 1864 if (unlikely(!mvi_dev || flags)) {
1813 mv_dprintk("port has not device.\n"); 1865 if (!mvi_dev)
1866 mv_dprintk("port has not device.\n");
1814 tstat->stat = SAS_PHY_DOWN; 1867 tstat->stat = SAS_PHY_DOWN;
1815 goto out; 1868 goto out;
1816 } 1869 }
1817 1870
1818 /*
1819 if (unlikely((rx_desc & RXQ_ERR) || (*(u64 *) slot->response))) {
1820 mv_dprintk("Find device[%016llx] RXQ_ERR %X,
1821 err info:%016llx\n",
1822 SAS_ADDR(task->dev->sas_addr),
1823 rx_desc, (u64)(*(u64 *) slot->response));
1824 }
1825 */
1826
1827 /* error info record present */ 1871 /* error info record present */
1828 if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) { 1872 if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) {
1829 tstat->stat = mvs_slot_err(mvi, task, slot_idx); 1873 tstat->stat = mvs_slot_err(mvi, task, slot_idx);
1874 tstat->resp = SAS_TASK_COMPLETE;
1830 goto out; 1875 goto out;
1831 } 1876 }
1832 1877
@@ -1868,11 +1913,16 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
1868 tstat->stat = SAM_CHECK_COND; 1913 tstat->stat = SAM_CHECK_COND;
1869 break; 1914 break;
1870 } 1915 }
1916 if (!slot->port->port_attached) {
1917 mv_dprintk("port %d has removed.\n", slot->port->sas_port.id);
1918 tstat->stat = SAS_PHY_DOWN;
1919 }
1920
1871 1921
1872out: 1922out:
1873 if (mvi_dev) { 1923 if (mvi_dev && mvi_dev->running_req) {
1874 mvi_dev->runing_req--; 1924 mvi_dev->running_req--;
1875 if (sas_protocol_ata(task->task_proto)) 1925 if (sas_protocol_ata(task->task_proto) && !mvi_dev->running_req)
1876 mvs_free_reg_set(mvi, mvi_dev); 1926 mvs_free_reg_set(mvi, mvi_dev);
1877 } 1927 }
1878 mvs_slot_task_free(mvi, task, slot, slot_idx); 1928 mvs_slot_task_free(mvi, task, slot, slot_idx);
@@ -1888,10 +1938,10 @@ out:
1888 return sts; 1938 return sts;
1889} 1939}
1890 1940
1891void mvs_release_task(struct mvs_info *mvi, 1941void mvs_do_release_task(struct mvs_info *mvi,
1892 int phy_no, struct domain_device *dev) 1942 int phy_no, struct domain_device *dev)
1893{ 1943{
1894 int i = 0; u32 slot_idx; 1944 u32 slot_idx;
1895 struct mvs_phy *phy; 1945 struct mvs_phy *phy;
1896 struct mvs_port *port; 1946 struct mvs_port *port;
1897 struct mvs_slot_info *slot, *slot2; 1947 struct mvs_slot_info *slot, *slot2;
@@ -1900,6 +1950,10 @@ void mvs_release_task(struct mvs_info *mvi,
1900 port = phy->port; 1950 port = phy->port;
1901 if (!port) 1951 if (!port)
1902 return; 1952 return;
1953 /* clean cmpl queue in case request is already finished */
1954 mvs_int_rx(mvi, false);
1955
1956
1903 1957
1904 list_for_each_entry_safe(slot, slot2, &port->list, entry) { 1958 list_for_each_entry_safe(slot, slot2, &port->list, entry) {
1905 struct sas_task *task; 1959 struct sas_task *task;
@@ -1911,18 +1965,22 @@ void mvs_release_task(struct mvs_info *mvi,
1911 1965
1912 mv_printk("Release slot [%x] tag[%x], task [%p]:\n", 1966 mv_printk("Release slot [%x] tag[%x], task [%p]:\n",
1913 slot_idx, slot->slot_tag, task); 1967 slot_idx, slot->slot_tag, task);
1914 1968 MVS_CHIP_DISP->command_active(mvi, slot_idx);
1915 if (task->task_proto & SAS_PROTOCOL_SSP) {
1916 mv_printk("attached with SSP task CDB[");
1917 for (i = 0; i < 16; i++)
1918 mv_printk(" %02x", task->ssp_task.cdb[i]);
1919 mv_printk(" ]\n");
1920 }
1921 1969
1922 mvs_slot_complete(mvi, slot_idx, 1); 1970 mvs_slot_complete(mvi, slot_idx, 1);
1923 } 1971 }
1924} 1972}
1925 1973
1974void mvs_release_task(struct mvs_info *mvi,
1975 struct domain_device *dev)
1976{
1977 int i, phyno[WIDE_PORT_MAX_PHY], num;
1978 /* housekeeper */
1979 num = mvs_find_dev_phyno(dev, phyno);
1980 for (i = 0; i < num; i++)
1981 mvs_do_release_task(mvi, phyno[i], dev);
1982}
1983
1926static void mvs_phy_disconnected(struct mvs_phy *phy) 1984static void mvs_phy_disconnected(struct mvs_phy *phy)
1927{ 1985{
1928 phy->phy_attached = 0; 1986 phy->phy_attached = 0;
@@ -2029,16 +2087,18 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
2029 * we need check the interrupt status which belongs to per port. 2087 * we need check the interrupt status which belongs to per port.
2030 */ 2088 */
2031 2089
2032 if (phy->irq_status & PHYEV_DCDR_ERR) 2090 if (phy->irq_status & PHYEV_DCDR_ERR) {
2033 mv_dprintk("port %d STP decoding error.\n", 2091 mv_dprintk("port %d STP decoding error.\n",
2034 phy_no+mvi->id*mvi->chip->n_phy); 2092 phy_no + mvi->id*mvi->chip->n_phy);
2093 }
2035 2094
2036 if (phy->irq_status & PHYEV_POOF) { 2095 if (phy->irq_status & PHYEV_POOF) {
2037 if (!(phy->phy_event & PHY_PLUG_OUT)) { 2096 if (!(phy->phy_event & PHY_PLUG_OUT)) {
2038 int dev_sata = phy->phy_type & PORT_TYPE_SATA; 2097 int dev_sata = phy->phy_type & PORT_TYPE_SATA;
2039 int ready; 2098 int ready;
2040 mvs_release_task(mvi, phy_no, NULL); 2099 mvs_do_release_task(mvi, phy_no, NULL);
2041 phy->phy_event |= PHY_PLUG_OUT; 2100 phy->phy_event |= PHY_PLUG_OUT;
2101 MVS_CHIP_DISP->clear_srs_irq(mvi, 0, 1);
2042 mvs_handle_event(mvi, 2102 mvs_handle_event(mvi,
2043 (void *)(unsigned long)phy_no, 2103 (void *)(unsigned long)phy_no,
2044 PHY_PLUG_EVENT); 2104 PHY_PLUG_EVENT);
@@ -2085,6 +2145,11 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
2085 phy_no, tmp); 2145 phy_no, tmp);
2086 } 2146 }
2087 mvs_update_phyinfo(mvi, phy_no, 0); 2147 mvs_update_phyinfo(mvi, phy_no, 0);
2148 if (phy->phy_type & PORT_TYPE_SAS) {
2149 MVS_CHIP_DISP->phy_reset(mvi, phy_no, 2);
2150 mdelay(10);
2151 }
2152
2088 mvs_bytes_dmaed(mvi, phy_no); 2153 mvs_bytes_dmaed(mvi, phy_no);
2089 /* whether driver is going to handle hot plug */ 2154 /* whether driver is going to handle hot plug */
2090 if (phy->phy_event & PHY_PLUG_OUT) { 2155 if (phy->phy_event & PHY_PLUG_OUT) {
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
index 885858bcc403..77ddc7c1e5f2 100644
--- a/drivers/scsi/mvsas/mv_sas.h
+++ b/drivers/scsi/mvsas/mv_sas.h
@@ -39,6 +39,7 @@
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/vmalloc.h> 40#include <linux/vmalloc.h>
41#include <scsi/libsas.h> 41#include <scsi/libsas.h>
42#include <scsi/scsi.h>
42#include <scsi/scsi_tcq.h> 43#include <scsi/scsi_tcq.h>
43#include <scsi/sas_ata.h> 44#include <scsi/sas_ata.h>
44#include <linux/version.h> 45#include <linux/version.h>
@@ -49,7 +50,7 @@
49#define _MV_DUMP 0 50#define _MV_DUMP 0
50#define MVS_ID_NOT_MAPPED 0x7f 51#define MVS_ID_NOT_MAPPED 0x7f
51/* #define DISABLE_HOTPLUG_DMA_FIX */ 52/* #define DISABLE_HOTPLUG_DMA_FIX */
52#define MAX_EXP_RUNNING_REQ 2 53// #define MAX_EXP_RUNNING_REQ 2
53#define WIDE_PORT_MAX_PHY 4 54#define WIDE_PORT_MAX_PHY 4
54#define MV_DISABLE_NCQ 0 55#define MV_DISABLE_NCQ 0
55#define mv_printk(fmt, arg ...) \ 56#define mv_printk(fmt, arg ...) \
@@ -129,6 +130,7 @@ struct mvs_dispatch {
129 130
130 void (*get_sas_addr)(void *buf, u32 buflen); 131 void (*get_sas_addr)(void *buf, u32 buflen);
131 void (*command_active)(struct mvs_info *mvi, u32 slot_idx); 132 void (*command_active)(struct mvs_info *mvi, u32 slot_idx);
133 void (*clear_srs_irq)(struct mvs_info *mvi, u8 reg_set, u8 clear_all);
132 void (*issue_stop)(struct mvs_info *mvi, enum mvs_port_type type, 134 void (*issue_stop)(struct mvs_info *mvi, enum mvs_port_type type,
133 u32 tfs); 135 u32 tfs);
134 void (*start_delivery)(struct mvs_info *mvi, u32 tx); 136 void (*start_delivery)(struct mvs_info *mvi, u32 tx);
@@ -236,9 +238,10 @@ struct mvs_device {
236 enum sas_dev_type dev_type; 238 enum sas_dev_type dev_type;
237 struct mvs_info *mvi_info; 239 struct mvs_info *mvi_info;
238 struct domain_device *sas_device; 240 struct domain_device *sas_device;
241 struct timer_list timer;
239 u32 attached_phy; 242 u32 attached_phy;
240 u32 device_id; 243 u32 device_id;
241 u32 runing_req; 244 u32 running_req;
242 u8 taskfileset; 245 u8 taskfileset;
243 u8 dev_status; 246 u8 dev_status;
244 u16 reserved; 247 u16 reserved;
@@ -397,7 +400,9 @@ int mvs_lu_reset(struct domain_device *dev, u8 *lun);
397int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags); 400int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags);
398int mvs_I_T_nexus_reset(struct domain_device *dev); 401int mvs_I_T_nexus_reset(struct domain_device *dev);
399int mvs_query_task(struct sas_task *task); 402int mvs_query_task(struct sas_task *task);
400void mvs_release_task(struct mvs_info *mvi, int phy_no, 403void mvs_release_task(struct mvs_info *mvi,
404 struct domain_device *dev);
405void mvs_do_release_task(struct mvs_info *mvi, int phy_no,
401 struct domain_device *dev); 406 struct domain_device *dev);
402void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events); 407void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events);
403void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); 408void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st);