提交 4e52fc0a 编写于 作者: K Ke Wei 提交者: James Bottomley

[SCSI] mvsas: check hd whether unplugged

if unplugged, driver's queuecommand function will return SAS_PHY_DOWN.
task->lldd_task is used for saving its slot info.
Signed-off-by: NKe Wei <kewei@marvell.com>
Signed-off-by: NJames Bottomley <James.Bottomley@HansenPartnership.com>
上级 1fce5e5d
...@@ -1784,15 +1784,19 @@ static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port) ...@@ -1784,15 +1784,19 @@ static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port)
return MVS_ID_NOT_MAPPED; return MVS_ID_NOT_MAPPED;
} }
static u32 mvs_get_ncq_tag(struct sas_task *task) static u32 mvs_get_ncq_tag(struct sas_task *task, u32 *tag)
{ {
u32 tag = 0;
struct ata_queued_cmd *qc = task->uldd_task; struct ata_queued_cmd *qc = task->uldd_task;
if (qc) if (qc) {
tag = qc->tag; if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
qc->tf.command == ATA_CMD_FPDMA_READ) {
*tag = qc->tag;
return 1;
}
}
return tag; return 0;
} }
static int mvs_task_prep_ata(struct mvs_info *mvi, static int mvs_task_prep_ata(struct mvs_info *mvi,
...@@ -1836,11 +1840,9 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, ...@@ -1836,11 +1840,9 @@ static int mvs_task_prep_ata(struct mvs_info *mvi,
hdr->flags = cpu_to_le32(flags); hdr->flags = cpu_to_le32(flags);
/* FIXME: the low order order 5 bits for the TAG if enable NCQ */ /* FIXME: the low order order 5 bits for the TAG if enable NCQ */
if (task->ata_task.use_ncq) { if (task->ata_task.use_ncq && mvs_get_ncq_tag(task, &hdr->tags))
hdr->tags = cpu_to_le32(mvs_get_ncq_tag(task)); task->ata_task.fis.sector_count |= hdr->tags << 3;
/*Fill in task file */ else
task->ata_task.fis.sector_count = hdr->tags << 3;
} else
hdr->tags = cpu_to_le32(tag); hdr->tags = cpu_to_le32(tag);
hdr->data_len = cpu_to_le32(task->total_xfer_len); hdr->data_len = cpu_to_le32(task->total_xfer_len);
...@@ -1933,13 +1935,16 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, ...@@ -1933,13 +1935,16 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi,
u32 flags; u32 flags;
u32 resp_len, req_len, i, tag = tei->tag; u32 resp_len, req_len, i, tag = tei->tag;
const u32 max_resp_len = SB_RFB_MAX; const u32 max_resp_len = SB_RFB_MAX;
u8 phy_mask;
slot = &mvi->slot_info[tag]; slot = &mvi->slot_info[tag];
phy_mask = (port->wide_port_phymap) ? port->wide_port_phymap :
task->dev->port->phy_mask;
slot->tx = mvi->tx_prod; slot->tx = mvi->tx_prod;
mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag | mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag |
(TXQ_CMD_SSP << TXQ_CMD_SHIFT) | (TXQ_CMD_SSP << TXQ_CMD_SHIFT) |
(port->wide_port_phymap << TXQ_PHY_SHIFT)); (phy_mask << TXQ_PHY_SHIFT));
flags = MCH_RETRY; flags = MCH_RETRY;
if (task->ssp_task.enable_first_burst) { if (task->ssp_task.enable_first_burst) {
...@@ -2040,22 +2045,32 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) ...@@ -2040,22 +2045,32 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
void __iomem *regs = mvi->regs; void __iomem *regs = mvi->regs;
struct mvs_task_exec_info tei; struct mvs_task_exec_info tei;
struct sas_task *t = task; struct sas_task *t = task;
struct mvs_slot_info *slot;
u32 tag = 0xdeadbeef, rc, n_elem = 0; u32 tag = 0xdeadbeef, rc, n_elem = 0;
unsigned long flags; unsigned long flags;
u32 n = num, pass = 0; u32 n = num, pass = 0;
spin_lock_irqsave(&mvi->lock, flags); spin_lock_irqsave(&mvi->lock, flags);
do { do {
dev = t->dev;
tei.port = &mvi->port[dev->port->id]; tei.port = &mvi->port[dev->port->id];
if (!tei.port->port_attached) { if (!tei.port->port_attached) {
struct task_status_struct *ts = &t->task_status; if (sas_protocol_ata(t->task_proto)) {
ts->stat = SAS_PHY_DOWN; rc = SAS_PHY_DOWN;
t->task_done(t); goto out_done;
rc = 0; } else {
goto exec_exit; struct task_status_struct *ts = &t->task_status;
ts->resp = SAS_TASK_UNDELIVERED;
ts->stat = SAS_PHY_DOWN;
t->task_done(t);
if (n > 1)
t = list_entry(t->list.next,
struct sas_task, list);
continue;
}
} }
if (!sas_protocol_ata(t->task_proto)) { if (!sas_protocol_ata(t->task_proto)) {
if (t->num_scatter) { if (t->num_scatter) {
n_elem = pci_map_sg(mvi->pdev, t->scatter, n_elem = pci_map_sg(mvi->pdev, t->scatter,
...@@ -2074,9 +2089,10 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) ...@@ -2074,9 +2089,10 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
if (rc) if (rc)
goto err_out; goto err_out;
mvi->slot_info[tag].task = t; slot = &mvi->slot_info[tag];
mvi->slot_info[tag].n_elem = n_elem; t->lldd_task = NULL;
memset(mvi->slot_info[tag].buf, 0, MVS_SLOT_BUF_SZ); slot->n_elem = n_elem;
memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
tei.task = t; tei.task = t;
tei.hdr = &mvi->slot[tag]; tei.hdr = &mvi->slot[tag];
tei.tag = tag; tei.tag = tag;
...@@ -2105,28 +2121,26 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) ...@@ -2105,28 +2121,26 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
if (rc) if (rc)
goto err_out_tag; goto err_out_tag;
slot->task = t;
slot->port = tei.port;
t->lldd_task = (void *) slot;
list_add_tail(&slot->list, &slot->port->list);
/* TODO: select normal or high priority */ /* TODO: select normal or high priority */
spin_lock(&t->task_state_lock); spin_lock(&t->task_state_lock);
t->task_state_flags |= SAS_TASK_AT_INITIATOR; t->task_state_flags |= SAS_TASK_AT_INITIATOR;
spin_unlock(&t->task_state_lock); spin_unlock(&t->task_state_lock);
if (n == 1) {
spin_unlock_irqrestore(&mvi->lock, flags);
mw32(TX_PROD_IDX, mvi->tx_prod);
}
mvs_hba_memory_dump(mvi, tag, t->task_proto); mvs_hba_memory_dump(mvi, tag, t->task_proto);
++pass; ++pass;
mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1); mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
if (n > 1)
if (n == 1) t = list_entry(t->list.next, struct sas_task, list);
break;
t = list_entry(t->list.next, struct sas_task, list);
} while (--n); } while (--n);
return 0; rc = 0;
goto out_done;
err_out_tag: err_out_tag:
mvs_tag_free(mvi, tag); mvs_tag_free(mvi, tag);
...@@ -2136,7 +2150,7 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) ...@@ -2136,7 +2150,7 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
if (n_elem) if (n_elem)
pci_unmap_sg(mvi->pdev, t->scatter, n_elem, pci_unmap_sg(mvi->pdev, t->scatter, n_elem,
t->data_dir); t->data_dir);
exec_exit: out_done:
if (pass) if (pass)
mw32(TX_PROD_IDX, (mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1)); mw32(TX_PROD_IDX, (mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
spin_unlock_irqrestore(&mvi->lock, flags); spin_unlock_irqrestore(&mvi->lock, flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册