Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 9704
b: refs/heads/master
c: 6a575fa
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Oct 6, 2005
1 parent fabe082 commit 4493c4f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 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: 46b93e7bce80a08ea07e250d03b0b596cbd32595
refs/heads/master: 6a575fa969beeddd0859f9e9d26ab16c6a0d8d6a
50 changes: 45 additions & 5 deletions trunk/drivers/scsi/sata_sil24.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#include <asm/io.h>

#define DRV_NAME "sata_sil24"
#define DRV_VERSION "0.21" /* Silicon Image's preview driver was 0.10 */
#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */

#define NR_PORTS 4

Expand Down Expand Up @@ -216,6 +216,7 @@ struct sil24_cmd_block {
struct sil24_port_priv {
struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */
dma_addr_t cmd_block_dma; /* DMA base addr for them */
struct ata_taskfile tf; /* Cached taskfile registers */
};

/* ap->host_set->private_data */
Expand Down Expand Up @@ -322,14 +323,25 @@ static struct ata_port_info sil24_port_info[] = {
},
};

static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
void *port = (void *)ap->ioaddr.cmd_addr;
struct sil24_prb *prb = port;

ata_tf_from_fis(prb->fis, &pp->tf);
}

static u8 sil24_check_status(struct ata_port *ap)
{
return ATA_DRDY;
struct sil24_port_priv *pp = ap->private_data;
return pp->tf.command;
}

static u8 sil24_check_err(struct ata_port *ap)
{
return 0;
struct sil24_port_priv *pp = ap->private_data;
return pp->tf.feature;
}

static int sil24_scr_map[] = {
Expand Down Expand Up @@ -485,6 +497,7 @@ static void sil24_eng_timeout(struct ata_port *ap)
static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
struct sil24_port_priv *pp = ap->private_data;
void *port = (void *)ap->ioaddr.cmd_addr;
u32 irq_stat, cmd_err, sstatus, serror;

Expand All @@ -509,8 +522,22 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
" stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);

if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
/*
* Device is reporting error, tf registers are valid.
*/
sil24_update_tf(ap);
} else {
/*
* Other errors. libata currently doesn't have any
* mechanism to report these errors. Just turn on
* ATA_ERR.
*/
pp->tf.command = ATA_ERR;
}

if (qc)
ata_qc_complete(qc, ATA_ERR);
ata_qc_complete(qc, pp->tf.command);

sil24_reset_controller(ap);
}
Expand All @@ -523,8 +550,19 @@ static inline void sil24_host_intr(struct ata_port *ap)

slot_stat = readl(port + PORT_SLOT_STAT);
if (!(slot_stat & HOST_SSTAT_ATTN)) {
struct sil24_port_priv *pp = ap->private_data;
/*
* !HOST_SSAT_ATTN guarantees successful completion,
* so reading back tf registers is unnecessary for
* most commands. TODO: read tf registers for
* commands which require these values on successful
* completion (EXECUTE DEVICE DIAGNOSTIC, CHECK POWER,
* DEVICE RESET and READ PORT MULTIPLIER (any more?).
*/
sil24_update_tf(ap);

if (qc)
ata_qc_complete(qc, 0);
ata_qc_complete(qc, pp->tf.command);
} else
sil24_error_intr(ap, slot_stat);
}
Expand Down Expand Up @@ -579,6 +617,8 @@ static int sil24_port_start(struct ata_port *ap)
return -ENOMEM;
memset(pp, 0, sizeof(*pp));

pp->tf.command = ATA_DRDY;

cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
if (!cb) {
kfree(pp);
Expand Down

0 comments on commit 4493c4f

Please sign in to comment.