Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 29365
b: refs/heads/master
c: 8dd2e3b
h: refs/heads/master
i:
  29363: 9b6882b
v: v3
  • Loading branch information
Jeff Garzik committed Jan 27, 2006
1 parent 0449913 commit 3106357
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 94 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: 2af5920b81a4cd0a22d40b6b2c38356d3df03e13
refs/heads/master: 8dd2e3bd57c3b389febba1de6b10372ef507f985
82 changes: 55 additions & 27 deletions trunk/drivers/scsi/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,61 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}

static void ahci_phy_reset(struct ata_port *ap)
static int ahci_stop_engine(struct ata_port *ap)
{
void __iomem *mmio = ap->host_set->mmio_base;
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
int work;
u32 tmp;

tmp = readl(port_mmio + PORT_CMD);
tmp &= ~PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);

/* wait for engine to stop. TODO: this could be
* as long as 500 msec
*/
work = 1000;
while (work-- > 0) {
tmp = readl(port_mmio + PORT_CMD);
if ((tmp & PORT_CMD_LIST_ON) == 0)
return 0;
udelay(10);
}

return -EIO;
}

static void ahci_start_engine(struct ata_port *ap)
{
void __iomem *mmio = ap->host_set->mmio_base;
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
u32 tmp;

tmp = readl(port_mmio + PORT_CMD);
tmp |= PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
readl(port_mmio + PORT_CMD); /* flush */
}

static unsigned int ahci_dev_classify(struct ata_port *ap)
{
void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
struct ata_taskfile tf;
u32 tmp;

tmp = readl(port_mmio + PORT_SIG);
tf.lbah = (tmp >> 24) & 0xff;
tf.lbam = (tmp >> 16) & 0xff;
tf.lbal = (tmp >> 8) & 0xff;
tf.nsect = (tmp) & 0xff;

return ata_dev_classify(&tf);
}

static void ahci_phy_reset(struct ata_port *ap)
{
void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
struct ata_device *dev = &ap->device[0];
u32 new_tmp, tmp;

Expand All @@ -458,13 +509,7 @@ static void ahci_phy_reset(struct ata_port *ap)
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;

tmp = readl(port_mmio + PORT_SIG);
tf.lbah = (tmp >> 24) & 0xff;
tf.lbam = (tmp >> 16) & 0xff;
tf.lbal = (tmp >> 8) & 0xff;
tf.nsect = (tmp) & 0xff;

dev->class = ata_dev_classify(&tf);
dev->class = ahci_dev_classify(ap);
if (!ata_dev_present(dev)) {
ata_port_disable(ap);
return;
Expand Down Expand Up @@ -572,7 +617,6 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
void __iomem *mmio = ap->host_set->mmio_base;
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
u32 tmp;
int work;

if ((ap->device[0].class != ATA_DEV_ATAPI) ||
((irq_stat & PORT_IRQ_TF_ERR) == 0))
Expand All @@ -588,20 +632,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
readl(port_mmio + PORT_SCR_ERR));

/* stop DMA */
tmp = readl(port_mmio + PORT_CMD);
tmp &= ~PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);

/* wait for engine to stop. TODO: this could be
* as long as 500 msec
*/
work = 1000;
while (work-- > 0) {
tmp = readl(port_mmio + PORT_CMD);
if ((tmp & PORT_CMD_LIST_ON) == 0)
break;
udelay(10);
}
ahci_stop_engine(ap);

/* clear SATA phy error, if any */
tmp = readl(port_mmio + PORT_SCR_ERR);
Expand All @@ -620,10 +651,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
}

/* re-start DMA */
tmp = readl(port_mmio + PORT_CMD);
tmp |= PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
readl(port_mmio + PORT_CMD); /* flush */
ahci_start_engine(ap);
}

static void ahci_eng_timeout(struct ata_port *ap)
Expand Down
53 changes: 39 additions & 14 deletions trunk/drivers/scsi/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,11 @@ enum {
ICH5_PCS = 0x92, /* port control and status */
PIIX_SCC = 0x0A, /* sub-class code register */

PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */
PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */
PIIX_FLAG_COMBINED = (1 << 30), /* combined mode possible */
PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
PIIX_FLAG_COMBINED = (1 << 29), /* combined mode possible */
/* ICH6/7 use different scheme for map value */
PIIX_FLAG_COMBINED_ICH6 = PIIX_FLAG_COMBINED | (1 << 30),

/* combined mode. if set, PATA is channel 0.
* if clear, PATA is channel 1.
Expand Down Expand Up @@ -297,8 +299,8 @@ static struct ata_port_info piix_port_info[] = {
{
.sht = &piix_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
ATA_FLAG_SLAVE_POSS,
PIIX_FLAG_COMBINED_ICH6 |
PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
Expand All @@ -309,8 +311,9 @@ static struct ata_port_info piix_port_info[] = {
{
.sht = &piix_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
PIIX_FLAG_COMBINED_ICH6 |
PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS |
PIIX_FLAG_AHCI,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 */
Expand Down Expand Up @@ -680,6 +683,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port_info *port_info[2];
unsigned int combined = 0;
unsigned int pata_chan = 0, sata_chan = 0;
unsigned long host_flags;

if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
Expand All @@ -692,7 +696,9 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
port_info[0] = &piix_port_info[ent->driver_data];
port_info[1] = &piix_port_info[ent->driver_data];

if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
host_flags = port_info[0]->host_flags;

if (host_flags & PIIX_FLAG_AHCI) {
u8 tmp;
pci_read_config_byte(pdev, PIIX_SCC, &tmp);
if (tmp == PIIX_AHCI_DEVICE) {
Expand All @@ -702,16 +708,35 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
}
}

if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {
if (host_flags & PIIX_FLAG_COMBINED) {
u8 tmp;
pci_read_config_byte(pdev, ICH5_PMR, &tmp);

if (tmp & PIIX_COMB) {
combined = 1;
if (tmp & PIIX_COMB_PATA_P0)
if (host_flags & PIIX_FLAG_COMBINED_ICH6) {
switch (tmp) {
case 0:
break;
case 1:
combined = 1;
sata_chan = 1;
else
break;
case 2:
combined = 1;
pata_chan = 1;
break;
case 3:
dev_printk(KERN_WARNING, &pdev->dev,
"invalid MAP value %u\n", tmp);
break;
}
} else {
if (tmp & PIIX_COMB) {
combined = 1;
if (tmp & PIIX_COMB_PATA_P0)
sata_chan = 1;
else
pata_chan = 1;
}
}
}

Expand All @@ -721,7 +746,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
* MSI is disabled (and it is disabled, as we don't use
* message-signalled interrupts currently).
*/
if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR)
if (host_flags & PIIX_FLAG_CHECKINTR)
pci_intx(pdev, 1);

if (combined) {
Expand Down
58 changes: 40 additions & 18 deletions trunk/drivers/scsi/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,41 @@ void ata_port_probe(struct ata_port *ap)
ap->flags &= ~ATA_FLAG_PORT_DISABLED;
}

/**
* sata_print_link_status - Print SATA link status
* @ap: SATA port to printk link status about
*
* This function prints link speed and status of a SATA link.
*
* LOCKING:
* None.
*/
static void sata_print_link_status(struct ata_port *ap)
{
u32 sstatus, tmp;
const char *speed;

if (!ap->ops->scr_read)
return;

sstatus = scr_read(ap, SCR_STATUS);

if (sata_dev_present(ap)) {
tmp = (sstatus >> 4) & 0xf;
if (tmp & (1 << 0))
speed = "1.5";
else if (tmp & (1 << 1))
speed = "3.0";
else
speed = "<unknown>";
printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
ap->id, speed, sstatus);
} else {
printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
ap->id, sstatus);
}
}

/**
* __sata_phy_reset - Wake/reset a low-level SATA PHY
* @ap: SATA port associated with target SATA PHY.
Expand Down Expand Up @@ -1569,27 +1604,14 @@ void __sata_phy_reset(struct ata_port *ap)
break;
} while (time_before(jiffies, timeout));

/* TODO: phy layer with polling, timeouts, etc. */
sstatus = scr_read(ap, SCR_STATUS);
if (sata_dev_present(ap)) {
const char *speed;
u32 tmp;
/* print link status */
sata_print_link_status(ap);

tmp = (sstatus >> 4) & 0xf;
if (tmp & (1 << 0))
speed = "1.5";
else if (tmp & (1 << 1))
speed = "3.0";
else
speed = "<unknown>";
printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
ap->id, speed, sstatus);
/* TODO: phy layer with polling, timeouts, etc. */
if (sata_dev_present(ap))
ata_port_probe(ap);
} else {
printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
ap->id, sstatus);
else
ata_port_disable(ap);
}

if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
Expand Down
48 changes: 21 additions & 27 deletions trunk/drivers/scsi/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -985,9 +985,13 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
if (dev->flags & ATA_DFLAG_LBA) {
tf->flags |= ATA_TFLAG_LBA;

if (dev->flags & ATA_DFLAG_LBA48) {
if (n_block > (64 * 1024))
goto invalid_fld;
if (lba_28_ok(block, n_block)) {
/* use LBA28 */
tf->command = ATA_CMD_VERIFY;
tf->device |= (block >> 24) & 0xf;
} else if (lba_48_ok(block, n_block)) {
if (!(dev->flags & ATA_DFLAG_LBA48))
goto out_of_range;

/* use LBA48 */
tf->flags |= ATA_TFLAG_LBA48;
Expand All @@ -998,15 +1002,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
tf->hob_lbah = (block >> 40) & 0xff;
tf->hob_lbam = (block >> 32) & 0xff;
tf->hob_lbal = (block >> 24) & 0xff;
} else {
if (n_block > 256)
goto invalid_fld;

/* use LBA28 */
tf->command = ATA_CMD_VERIFY;

tf->device |= (block >> 24) & 0xf;
}
} else
/* request too large even for LBA48 */
goto out_of_range;

tf->nsect = n_block & 0xff;

Expand All @@ -1019,8 +1017,8 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
/* CHS */
u32 sect, head, cyl, track;

if (n_block > 256)
goto invalid_fld;
if (!lba_28_ok(block, n_block))
goto out_of_range;

/* Convert LBA to CHS */
track = (u32)block / dev->sectors;
Expand Down Expand Up @@ -1139,9 +1137,11 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
if (dev->flags & ATA_DFLAG_LBA) {
tf->flags |= ATA_TFLAG_LBA;

if (dev->flags & ATA_DFLAG_LBA48) {
/* The request -may- be too large for LBA48. */
if ((block >> 48) || (n_block > 65536))
if (lba_28_ok(block, n_block)) {
/* use LBA28 */
tf->device |= (block >> 24) & 0xf;
} else if (lba_48_ok(block, n_block)) {
if (!(dev->flags & ATA_DFLAG_LBA48))
goto out_of_range;

/* use LBA48 */
Expand All @@ -1152,15 +1152,9 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
tf->hob_lbah = (block >> 40) & 0xff;
tf->hob_lbam = (block >> 32) & 0xff;
tf->hob_lbal = (block >> 24) & 0xff;
} else {
/* use LBA28 */

/* The request -may- be too large for LBA28. */
if ((block >> 28) || (n_block > 256))
goto out_of_range;

tf->device |= (block >> 24) & 0xf;
}
} else
/* request too large even for LBA48 */
goto out_of_range;

if (unlikely(ata_rwcmd_protocol(qc) < 0))
goto invalid_fld;
Expand All @@ -1178,7 +1172,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
u32 sect, head, cyl, track;

/* The request -may- be too large for CHS addressing. */
if ((block >> 28) || (n_block > 256))
if (!lba_28_ok(block, n_block))
goto out_of_range;

if (unlikely(ata_rwcmd_protocol(qc) < 0))
Expand Down
Loading

0 comments on commit 3106357

Please sign in to comment.