Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 29439
b: refs/heads/master
c: aee10a0
h: refs/heads/master
i:
  29437: ecebdce
  29435: cf62441
  29431: e32b97c
  29423: cd0e86f
  29407: e198076
  29375: 53a0d58
  29311: cd7e93a
  29183: abd2282
v: v3
  • Loading branch information
Tejun Heo committed May 15, 2006
1 parent a21088e commit d7a8cd6
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 22 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: 12fad3f965830d71f6454f02b2af002a64cec4d3
refs/heads/master: aee10a03eb3e240bfd1a6f91e06ce82df47c5c58
68 changes: 47 additions & 21 deletions trunk/drivers/scsi/sata_sil24.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,17 @@ enum {
SGE_DRD = (1 << 29), /* discard data read (/dev/null)
data address ignored */

SIL24_MAX_CMDS = 31,

/* board id */
BID_SIL3124 = 0,
BID_SIL3132 = 1,
BID_SIL3131 = 2,

/* host flags */
SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_NCQ,
SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */

IRQ_STAT_4PORTS = 0xf,
Expand Down Expand Up @@ -355,7 +358,8 @@ static struct scsi_host_template sil24_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.change_queue_depth = ata_scsi_change_queue_depth,
.can_queue = SIL24_MAX_CMDS,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
Expand Down Expand Up @@ -437,6 +441,13 @@ static struct ata_port_info sil24_port_info[] = {
},
};

static int sil24_tag(int tag)
{
if (unlikely(ata_tag_internal(tag)))
return 0;
return tag;
}

static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
{
void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
Expand Down Expand Up @@ -649,14 +660,17 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct sil24_port_priv *pp = ap->private_data;
union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
union sil24_cmd_block *cb;
struct sil24_prb *prb;
struct sil24_sge *sge;
u16 ctrl = 0;

cb = &pp->cmd_block[sil24_tag(qc->tag)];

switch (qc->tf.protocol) {
case ATA_PROT_PIO:
case ATA_PROT_DMA:
case ATA_PROT_NCQ:
case ATA_PROT_NODATA:
prb = &cb->ata.prb;
sge = cb->ata.sge;
Expand Down Expand Up @@ -694,12 +708,17 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);
void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
unsigned int tag = sil24_tag(qc->tag);
dma_addr_t paddr;
void __iomem *activate;

writel((u32)paddr, port + PORT_CMD_ACTIVATE);
writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
paddr = pp->cmd_block_dma + tag * sizeof(*pp->cmd_block);
activate = port + PORT_CMD_ACTIVATE + tag * 8;

writel((u32)paddr, activate);
writel((u64)paddr >> 32, activate + 4);

return 0;
}
Expand Down Expand Up @@ -791,9 +810,6 @@ static void sil24_error_intr(struct ata_port *ap)
/* record error info */
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc) {
int tag = qc->tag;
if (unlikely(ata_tag_internal(tag)))
tag = 0;
sil24_update_tf(ap);
qc->err_mask |= err_mask;
} else
Expand All @@ -809,11 +825,17 @@ static void sil24_error_intr(struct ata_port *ap)
ata_port_abort(ap);
}

static void sil24_finish_qc(struct ata_queued_cmd *qc)
{
if (qc->flags & ATA_QCFLAG_RESULT_TF)
sil24_update_tf(qc->ap);
}

static inline void sil24_host_intr(struct ata_port *ap)
{
void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
struct ata_queued_cmd *qc;
u32 slot_stat;
u32 slot_stat, qc_active;
int rc;

slot_stat = readl(port + PORT_SLOT_STAT);

Expand All @@ -825,18 +847,22 @@ static inline void sil24_host_intr(struct ata_port *ap)
if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT);

qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc) {
if (qc->flags & ATA_QCFLAG_RESULT_TF)
sil24_update_tf(ap);
ata_qc_complete(qc);
qc_active = slot_stat & ~HOST_SSTAT_ATTN;
rc = ata_qc_complete_multiple(ap, qc_active, sil24_finish_qc);
if (rc > 0)
return;
if (rc < 0) {
struct ata_eh_info *ehi = &ap->eh_info;
ehi->err_mask |= AC_ERR_HSM;
ehi->action |= ATA_EH_SOFTRESET;
ata_port_freeze(ap);
return;
}

if (ata_ratelimit())
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
"(slot_stat 0x%x active_tag %d)\n",
slot_stat, ap->active_tag);
"(slot_stat 0x%x active_tag %d sactive 0x%x)\n",
slot_stat, ap->active_tag, ap->sactive);
}

static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
Expand Down Expand Up @@ -903,7 +929,7 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)

static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev)
{
const size_t cb_size = sizeof(*pp->cmd_block);
const size_t cb_size = sizeof(*pp->cmd_block) * SIL24_MAX_CMDS;

dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
}
Expand All @@ -913,7 +939,7 @@ static int sil24_port_start(struct ata_port *ap)
struct device *dev = ap->host_set->dev;
struct sil24_port_priv *pp;
union sil24_cmd_block *cb;
size_t cb_size = sizeof(*cb);
size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
dma_addr_t cb_dma;
int rc = -ENOMEM;

Expand Down

0 comments on commit d7a8cd6

Please sign in to comment.