Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 42078
b: refs/heads/master
c: fc08515
h: refs/heads/master
v: v3
  • Loading branch information
Alan Cox authored and Jeff Garzik committed Dec 2, 2006
1 parent 9ccac7c commit 66b814f
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 5 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: 2f27ce03628acdb81ead4abe914c713e04a3229e
refs/heads/master: fc085150b491bfc186efbca90a14cf907a3060a9
31 changes: 30 additions & 1 deletion trunk/drivers/ata/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
#include <linux/libata.h>

#define DRV_NAME "ata_piix"
#define DRV_VERSION "2.00ac6"
#define DRV_VERSION "2.00ac7"

enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
Expand Down Expand Up @@ -571,6 +571,23 @@ module_param(force_pcs, int, 0444);
MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
"device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)");

struct ich_laptop {
u16 device;
u16 subvendor;
u16 subdevice;
};

/*
* List of laptops that use short cables rather than 80 wire
*/

static const struct ich_laptop ich_laptop[] = {
/* devid, subvendor, subdev */
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
/* end marker */
{ 0, }
};

/**
* piix_pata_cbl_detect - Probe host controller cable detect info
* @ap: Port for which cable detect info is desired
Expand All @@ -585,12 +602,24 @@ MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
static void ich_pata_cbl_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
const struct ich_laptop *lap = &ich_laptop[0];
u8 tmp, mask;

/* no 80c support in host controller? */
if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0)
goto cbl40;

/* Check for specials - Acer Aspire 5602WLMi */
while (lap->device) {
if (lap->device == pdev->device &&
lap->subvendor == pdev->subsystem_vendor &&
lap->subdevice == pdev->subsystem_device) {
ap->cbl = ATA_CBL_PATA40_SHORT;
return;
}
lap++;
}

/* check BIOS cable detect results */
mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3119,6 +3119,13 @@ static void ata_dev_xfermask(struct ata_device *dev)
*/
if (ap->cbl == ATA_CBL_PATA40)
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
/* Apply drive side cable rule. Unknown or 80 pin cables reported
* host side are checked drive side as well. Cases where we know a
* 40wire cable is used safely for 80 are not checked here.
*/
if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);


xfer_mask &= ata_pack_xfermask(dev->pio_mask,
dev->mwdma_mask, dev->udma_mask);
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/ata/pata_ali.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static int ali_c2_cable_detect(struct ata_port *ap)
implement the detect logic */

if (ali_cable_override(pdev))
return ATA_CBL_PATA80;
return ATA_CBL_PATA40_SHORT;

/* Host view cable detect 0x4A bit 0 primary bit 1 secondary
Bit set for 40 pin */
Expand Down
14 changes: 12 additions & 2 deletions trunk/include/linux/ata.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,9 @@ enum {
ATA_CBL_NONE = 0,
ATA_CBL_PATA40 = 1,
ATA_CBL_PATA80 = 2,
ATA_CBL_PATA_UNK = 3,
ATA_CBL_SATA = 4,
ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */
ATA_CBL_PATA_UNK = 4,
ATA_CBL_SATA = 5,

/* SATA Status and Control Registers */
SCR_STATUS = 0,
Expand Down Expand Up @@ -342,6 +343,15 @@ static inline int ata_id_is_cfa(const u16 *id)
return 0;
}

static inline int ata_drive_40wire(const u16 *dev_id)
{
if (ata_id_major_version(dev_id) >= 5 && ata_id_is_sata(dev_id))
return 0; /* SATA */
if (dev_id[93] & 0x4000)
return 0; /* 80 wire */
return 1;
}

static inline int atapi_cdb_len(const u16 *dev_id)
{
u16 tmp = dev_id[0] & 0x3;
Expand Down

0 comments on commit 66b814f

Please sign in to comment.