mirror of https://gitee.com/openkylin/linux.git
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: pata_it821x: Driver updates and reworking libata.h: replace __FUNCTION__ with __func__ ata_piix: subsys 106b:00a3 is apple ich8m too libata-core: make sure that ata_force_tbl is freed in case of an error libata: update atapi disable handling pata_via: add VX800 flag; add function for fixing h/w bugs pata_ali: misplaced pci_dev_put()
This commit is contained in:
commit
3a4b7886ee
|
@ -250,6 +250,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
|
|||
/* Mobile SATA Controller IDE (ICH8M), Apple */
|
||||
{ 0x8086, 0x2828, 0x106b, 0x00a0, 0, 0, ich8m_apple_sata },
|
||||
{ 0x8086, 0x2828, 0x106b, 0x00a1, 0, 0, ich8m_apple_sata },
|
||||
{ 0x8086, 0x2828, 0x106b, 0x00a3, 0, 0, ich8m_apple_sata },
|
||||
/* Mobile SATA Controller IDE (ICH8M) */
|
||||
{ 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
|
||||
/* SATA Controller IDE (ICH9) */
|
||||
|
|
|
@ -120,7 +120,7 @@ static char ata_force_param_buf[PAGE_SIZE] __initdata;
|
|||
module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0);
|
||||
MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)");
|
||||
|
||||
int atapi_enabled = 1;
|
||||
static int atapi_enabled = 1;
|
||||
module_param(atapi_enabled, int, 0444);
|
||||
MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
|
||||
|
||||
|
@ -1132,6 +1132,8 @@ void ata_id_string(const u16 *id, unsigned char *s,
|
|||
{
|
||||
unsigned int c;
|
||||
|
||||
BUG_ON(len & 1);
|
||||
|
||||
while (len > 0) {
|
||||
c = id[ofs] >> 8;
|
||||
*s = c;
|
||||
|
@ -1165,8 +1167,6 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
|
|||
{
|
||||
unsigned char *p;
|
||||
|
||||
WARN_ON(!(len & 1));
|
||||
|
||||
ata_id_string(id, s, ofs, len - 1);
|
||||
|
||||
p = s + strnlen(s, len - 1);
|
||||
|
@ -1885,6 +1885,23 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
|
|||
return 3 << ATA_SHIFT_PIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_do_dev_read_id - default ID read method
|
||||
* @dev: device
|
||||
* @tf: proposed taskfile
|
||||
* @id: data buffer
|
||||
*
|
||||
* Issue the identify taskfile and hand back the buffer containing
|
||||
* identify data. For some RAID controllers and for pre ATA devices
|
||||
* this function is wrapped or replaced by the driver
|
||||
*/
|
||||
unsigned int ata_do_dev_read_id(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, u16 *id)
|
||||
{
|
||||
return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
|
||||
id, sizeof(id[0]) * ATA_ID_WORDS, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_read_id - Read ID data from the specified device
|
||||
* @dev: target device
|
||||
|
@ -1920,7 +1937,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
|||
if (ata_msg_ctl(ap))
|
||||
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__);
|
||||
|
||||
retry:
|
||||
retry:
|
||||
ata_tf_init(dev, &tf);
|
||||
|
||||
switch (class) {
|
||||
|
@ -1948,8 +1965,11 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
|||
*/
|
||||
tf.flags |= ATA_TFLAG_POLLING;
|
||||
|
||||
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
|
||||
id, sizeof(id[0]) * ATA_ID_WORDS, 0);
|
||||
if (ap->ops->read_id)
|
||||
err_mask = ap->ops->read_id(dev, &tf, id);
|
||||
else
|
||||
err_mask = ata_do_dev_read_id(dev, &tf, id);
|
||||
|
||||
if (err_mask) {
|
||||
if (err_mask & AC_ERR_NODEV_HINT) {
|
||||
ata_dev_printk(dev, KERN_DEBUG,
|
||||
|
@ -2142,6 +2162,16 @@ int ata_dev_configure(struct ata_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((!atapi_enabled || (ap->flags & ATA_FLAG_NO_ATAPI)) &&
|
||||
dev->class == ATA_DEV_ATAPI) {
|
||||
ata_dev_printk(dev, KERN_WARNING,
|
||||
"WARNING: ATAPI is %s, device ignored.\n",
|
||||
atapi_enabled ? "not supported with this driver"
|
||||
: "disabled");
|
||||
ata_dev_disable(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* let ACPI work its magic */
|
||||
rc = ata_acpi_on_devcfg(dev);
|
||||
if (rc)
|
||||
|
@ -6088,16 +6118,20 @@ static int __init ata_init(void)
|
|||
|
||||
ata_wq = create_workqueue("ata");
|
||||
if (!ata_wq)
|
||||
return -ENOMEM;
|
||||
goto free_force_tbl;
|
||||
|
||||
ata_aux_wq = create_singlethread_workqueue("ata_aux");
|
||||
if (!ata_aux_wq) {
|
||||
destroy_workqueue(ata_wq);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!ata_aux_wq)
|
||||
goto free_wq;
|
||||
|
||||
printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
|
||||
return 0;
|
||||
|
||||
free_wq:
|
||||
destroy_workqueue(ata_wq);
|
||||
free_force_tbl:
|
||||
kfree(ata_force_tbl);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void __exit ata_exit(void)
|
||||
|
@ -6269,6 +6303,7 @@ EXPORT_SYMBOL_GPL(ata_host_resume);
|
|||
#endif /* CONFIG_PM */
|
||||
EXPORT_SYMBOL_GPL(ata_id_string);
|
||||
EXPORT_SYMBOL_GPL(ata_id_c_string);
|
||||
EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
|
||||
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
|
||||
|
||||
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
|
||||
|
|
|
@ -2550,36 +2550,6 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
|
|||
return ata_find_dev(ap, devno);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_dev_enabled - determine if device is enabled
|
||||
* @dev: ATA device
|
||||
*
|
||||
* Determine if commands should be sent to the specified device.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 if commands are not allowed / 1 if commands are allowed
|
||||
*/
|
||||
|
||||
static int ata_scsi_dev_enabled(struct ata_device *dev)
|
||||
{
|
||||
if (unlikely(!ata_dev_enabled(dev)))
|
||||
return 0;
|
||||
|
||||
if (!atapi_enabled || (dev->link->ap->flags & ATA_FLAG_NO_ATAPI)) {
|
||||
if (unlikely(dev->class == ATA_DEV_ATAPI)) {
|
||||
ata_dev_printk(dev, KERN_WARNING,
|
||||
"WARNING: ATAPI is %s, device ignored.\n",
|
||||
atapi_enabled ? "not supported with this driver" : "disabled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_find_dev - lookup ata_device from scsi_cmnd
|
||||
* @ap: ATA port to which the device is attached
|
||||
|
@ -2601,7 +2571,7 @@ ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
|
|||
{
|
||||
struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev);
|
||||
|
||||
if (unlikely(!dev || !ata_scsi_dev_enabled(dev)))
|
||||
if (unlikely(!dev || !ata_dev_enabled(dev)))
|
||||
return NULL;
|
||||
|
||||
return dev;
|
||||
|
@ -3622,7 +3592,7 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
|
|||
|
||||
ata_scsi_dump_cdb(ap, cmd);
|
||||
|
||||
if (likely(ata_scsi_dev_enabled(ap->link.device)))
|
||||
if (likely(ata_dev_enabled(ap->link.device)))
|
||||
rc = __ata_scsi_queuecmd(cmd, done, ap->link.device);
|
||||
else {
|
||||
cmd->result = (DID_BAD_TARGET << 16);
|
||||
|
|
|
@ -66,7 +66,6 @@ enum {
|
|||
|
||||
extern unsigned int ata_print_id;
|
||||
extern struct workqueue_struct *ata_aux_wq;
|
||||
extern int atapi_enabled;
|
||||
extern int atapi_passthru16;
|
||||
extern int libata_fua;
|
||||
extern int libata_noacpi;
|
||||
|
|
|
@ -550,8 +550,9 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
pci_read_config_byte(isa_bridge, 0x5E, &tmp);
|
||||
if ((tmp & 0x1E) == 0x12)
|
||||
ppi[0] = &info_20_udma;
|
||||
pci_dev_put(isa_bridge);
|
||||
}
|
||||
pci_dev_put(isa_bridge);
|
||||
|
||||
return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
|
||||
|
||||
#define DRV_NAME "pata_it821x"
|
||||
#define DRV_VERSION "0.3.8"
|
||||
#define DRV_VERSION "0.4.0"
|
||||
|
||||
struct it821x_dev
|
||||
{
|
||||
|
@ -425,6 +425,8 @@ static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc)
|
|||
case ATA_CMD_WRITE_MULTI:
|
||||
case ATA_CMD_WRITE_MULTI_EXT:
|
||||
case ATA_CMD_ID_ATA:
|
||||
case ATA_CMD_INIT_DEV_PARAMS:
|
||||
case 0xFC: /* Internal 'report rebuild state' */
|
||||
/* Arguably should just no-op this one */
|
||||
case ATA_CMD_SET_FEATURES:
|
||||
return ata_sff_qc_issue(qc);
|
||||
|
@ -509,7 +511,7 @@ static void it821x_dev_config(struct ata_device *adev)
|
|||
|
||||
if (strstr(model_num, "Integrated Technology Express")) {
|
||||
/* RAID mode */
|
||||
printk(KERN_INFO "IT821x %sRAID%d volume",
|
||||
ata_dev_printk(adev, KERN_INFO, "%sRAID%d volume",
|
||||
adev->id[147]?"Bootable ":"",
|
||||
adev->id[129]);
|
||||
if (adev->id[129] != 1)
|
||||
|
@ -519,36 +521,50 @@ static void it821x_dev_config(struct ata_device *adev)
|
|||
/* This is a controller firmware triggered funny, don't
|
||||
report the drive faulty! */
|
||||
adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC;
|
||||
/* No HPA in 'smart' mode */
|
||||
adev->horkage |= ATA_HORKAGE_BROKEN_HPA;
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_ident_hack - Hack identify data up
|
||||
* @ap: Port
|
||||
* it821x_read_id - Hack identify data up
|
||||
* @adev: device to read
|
||||
* @tf: proposed taskfile
|
||||
* @id: buffer for returned ident data
|
||||
*
|
||||
* Walk the devices on this firmware driven port and slightly
|
||||
* Query the devices on this firmware driven port and slightly
|
||||
* mash the identify data to stop us and common tools trying to
|
||||
* use features not firmware supported. The firmware itself does
|
||||
* some masking (eg SMART) but not enough.
|
||||
*
|
||||
* This is a bit of an abuse of the cable method, but it is the
|
||||
* only method called at the right time. We could modify the libata
|
||||
* core specifically for ident hacking but while we have one offender
|
||||
* it seems better to keep the fallout localised.
|
||||
*/
|
||||
|
||||
static int it821x_ident_hack(struct ata_port *ap)
|
||||
static unsigned int it821x_read_id(struct ata_device *adev,
|
||||
struct ata_taskfile *tf, u16 *id)
|
||||
{
|
||||
struct ata_device *adev;
|
||||
ata_link_for_each_dev(adev, &ap->link) {
|
||||
if (ata_dev_enabled(adev)) {
|
||||
adev->id[84] &= ~(1 << 6); /* No FUA */
|
||||
adev->id[85] &= ~(1 << 10); /* No HPA */
|
||||
adev->id[76] = 0; /* No NCQ/AN etc */
|
||||
}
|
||||
}
|
||||
return ata_cable_unknown(ap);
|
||||
}
|
||||
unsigned int err_mask;
|
||||
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
||||
|
||||
err_mask = ata_do_dev_read_id(adev, tf, id);
|
||||
if (err_mask)
|
||||
return err_mask;
|
||||
ata_id_c_string(id, model_num, ATA_ID_PROD, sizeof(model_num));
|
||||
|
||||
id[83] &= ~(1 << 12); /* Cache flush is firmware handled */
|
||||
id[83] &= ~(1 << 13); /* Ditto for LBA48 flushes */
|
||||
id[84] &= ~(1 << 6); /* No FUA */
|
||||
id[85] &= ~(1 << 10); /* No HPA */
|
||||
id[76] = 0; /* No NCQ/AN etc */
|
||||
|
||||
if (strstr(model_num, "Integrated Technology Express")) {
|
||||
/* Set feature bits the firmware neglects */
|
||||
id[49] |= 0x0300; /* LBA, DMA */
|
||||
id[82] |= 0x0400; /* LBA48 */
|
||||
id[83] &= 0x7FFF;
|
||||
id[83] |= 0x4000; /* Word 83 is valid */
|
||||
id[86] |= 0x0400; /* LBA48 on */
|
||||
id[ATA_ID_MAJOR_VER] |= 0x1F;
|
||||
}
|
||||
return err_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_check_atapi_dma - ATAPI DMA handler
|
||||
|
@ -577,6 +593,136 @@ static int it821x_check_atapi_dma(struct ata_queued_cmd *qc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_display_disk - display disk setup
|
||||
* @n: Device number
|
||||
* @buf: Buffer block from firmware
|
||||
*
|
||||
* Produce a nice informative display of the device setup as provided
|
||||
* by the firmware.
|
||||
*/
|
||||
|
||||
static void it821x_display_disk(int n, u8 *buf)
|
||||
{
|
||||
unsigned char id[41];
|
||||
int mode = 0;
|
||||
char *mtype;
|
||||
char mbuf[8];
|
||||
char *cbl = "(40 wire cable)";
|
||||
|
||||
static const char *types[5] = {
|
||||
"RAID0", "RAID1" "RAID 0+1", "JBOD", "DISK"
|
||||
};
|
||||
|
||||
if (buf[52] > 4) /* No Disk */
|
||||
return;
|
||||
|
||||
ata_id_c_string((u16 *)buf, id, 0, 41);
|
||||
|
||||
if (buf[51]) {
|
||||
mode = ffs(buf[51]);
|
||||
mtype = "UDMA";
|
||||
} else if (buf[49]) {
|
||||
mode = ffs(buf[49]);
|
||||
mtype = "MWDMA";
|
||||
}
|
||||
|
||||
if (buf[76])
|
||||
cbl = "";
|
||||
|
||||
if (mode)
|
||||
snprintf(mbuf, 8, "%5s%d", mtype, mode - 1);
|
||||
else
|
||||
strcpy(mbuf, "PIO");
|
||||
if (buf[52] == 4)
|
||||
printk(KERN_INFO "%d: %-6s %-8s %s %s\n",
|
||||
n, mbuf, types[buf[52]], id, cbl);
|
||||
else
|
||||
printk(KERN_INFO "%d: %-6s %-8s Volume: %1d %s %s\n",
|
||||
n, mbuf, types[buf[52]], buf[53], id, cbl);
|
||||
if (buf[125] < 100)
|
||||
printk(KERN_INFO "%d: Rebuilding: %d%%\n", n, buf[125]);
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_firmware_command - issue firmware command
|
||||
* @ap: IT821x port to interrogate
|
||||
* @cmd: command
|
||||
* @len: length
|
||||
*
|
||||
* Issue firmware commands expecting data back from the controller. We
|
||||
* use this to issue commands that do not go via the normal paths. Other
|
||||
* commands such as 0xFC can be issued normally.
|
||||
*/
|
||||
|
||||
static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len)
|
||||
{
|
||||
u8 status;
|
||||
int n = 0;
|
||||
u16 *buf = kmalloc(len, GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
printk(KERN_ERR "it821x_firmware_command: Out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
/* This isn't quite a normal ATA command as we are talking to the
|
||||
firmware not the drives */
|
||||
ap->ctl |= ATA_NIEN;
|
||||
iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
|
||||
ata_wait_idle(ap);
|
||||
iowrite8(ATA_DEVICE_OBS, ap->ioaddr.device_addr);
|
||||
iowrite8(cmd, ap->ioaddr.command_addr);
|
||||
udelay(1);
|
||||
/* This should be almost immediate but a little paranoia goes a long
|
||||
way. */
|
||||
while(n++ < 10) {
|
||||
status = ioread8(ap->ioaddr.status_addr);
|
||||
if (status & ATA_ERR) {
|
||||
kfree(buf);
|
||||
printk(KERN_ERR "it821x_firmware_command: rejected\n");
|
||||
return NULL;
|
||||
}
|
||||
if (status & ATA_DRQ) {
|
||||
ioread16_rep(ap->ioaddr.data_addr, buf, len/2);
|
||||
return (u8 *)buf;
|
||||
}
|
||||
mdelay(1);
|
||||
}
|
||||
kfree(buf);
|
||||
printk(KERN_ERR "it821x_firmware_command: timeout\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_probe_firmware - firmware reporting/setup
|
||||
* @ap: IT821x port being probed
|
||||
*
|
||||
* Probe the firmware of the controller by issuing firmware command
|
||||
* 0xFA and analysing the returned data.
|
||||
*/
|
||||
|
||||
static void it821x_probe_firmware(struct ata_port *ap)
|
||||
{
|
||||
u8 *buf;
|
||||
int i;
|
||||
|
||||
/* This is a bit ugly as we can't just issue a task file to a device
|
||||
as this is controller magic */
|
||||
|
||||
buf = it821x_firmware_command(ap, 0xFA, 512);
|
||||
|
||||
if (buf != NULL) {
|
||||
printk(KERN_INFO "pata_it821x: Firmware %02X/%02X/%02X%02X\n",
|
||||
buf[505],
|
||||
buf[506],
|
||||
buf[507],
|
||||
buf[508]);
|
||||
for (i = 0; i < 4; i++)
|
||||
it821x_display_disk(i, buf + 128 * i);
|
||||
kfree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* it821x_port_start - port setup
|
||||
|
@ -610,6 +756,8 @@ static int it821x_port_start(struct ata_port *ap)
|
|||
/* Long I/O's although allowed in LBA48 space cause the
|
||||
onboard firmware to enter the twighlight zone */
|
||||
/* No ATAPI DMA in this mode either */
|
||||
if (ap->port_no == 0)
|
||||
it821x_probe_firmware(ap);
|
||||
}
|
||||
/* Pull the current clocks from 0x50 */
|
||||
if (conf & (1 << (1 + ap->port_no)))
|
||||
|
@ -631,6 +779,25 @@ static int it821x_port_start(struct ata_port *ap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_rdc_cable - Cable detect for RDC1010
|
||||
* @ap: port we are checking
|
||||
*
|
||||
* Return the RDC1010 cable type. Unlike the IT821x we know how to do
|
||||
* this and can do host side cable detect
|
||||
*/
|
||||
|
||||
static int it821x_rdc_cable(struct ata_port *ap)
|
||||
{
|
||||
u16 r40;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
pci_read_config_word(pdev, 0x40, &r40);
|
||||
if (r40 & (1 << (2 + ap->port_no)))
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
static struct scsi_host_template it821x_sht = {
|
||||
ATA_BMDMA_SHT(DRV_NAME),
|
||||
};
|
||||
|
@ -641,9 +808,10 @@ static struct ata_port_operations it821x_smart_port_ops = {
|
|||
.check_atapi_dma= it821x_check_atapi_dma,
|
||||
.qc_issue = it821x_smart_qc_issue,
|
||||
|
||||
.cable_detect = it821x_ident_hack,
|
||||
.cable_detect = ata_cable_80wire,
|
||||
.set_mode = it821x_smart_set_mode,
|
||||
.dev_config = it821x_dev_config,
|
||||
.read_id = it821x_read_id,
|
||||
|
||||
.port_start = it821x_port_start,
|
||||
};
|
||||
|
@ -664,8 +832,29 @@ static struct ata_port_operations it821x_passthru_port_ops = {
|
|||
.port_start = it821x_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations it821x_rdc_port_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
|
||||
.check_atapi_dma= it821x_check_atapi_dma,
|
||||
.sff_dev_select = it821x_passthru_dev_select,
|
||||
.bmdma_start = it821x_passthru_bmdma_start,
|
||||
.bmdma_stop = it821x_passthru_bmdma_stop,
|
||||
.qc_issue = it821x_passthru_qc_issue,
|
||||
|
||||
.cable_detect = it821x_rdc_cable,
|
||||
.set_piomode = it821x_passthru_set_piomode,
|
||||
.set_dmamode = it821x_passthru_set_dmamode,
|
||||
|
||||
.port_start = it821x_port_start,
|
||||
};
|
||||
|
||||
static void it821x_disable_raid(struct pci_dev *pdev)
|
||||
{
|
||||
/* Neither the RDC nor the IT8211 */
|
||||
if (pdev->vendor != PCI_VENDOR_ID_ITE ||
|
||||
pdev->device != PCI_DEVICE_ID_ITE_8212)
|
||||
return;
|
||||
|
||||
/* Reset local CPU, and set BIOS not ready */
|
||||
pci_write_config_byte(pdev, 0x5E, 0x01);
|
||||
|
||||
|
@ -690,6 +879,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
.flags = ATA_FLAG_SLAVE_POSS,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &it821x_smart_port_ops
|
||||
};
|
||||
static const struct ata_port_info info_passthru = {
|
||||
|
@ -699,6 +889,13 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &it821x_passthru_port_ops
|
||||
};
|
||||
static const struct ata_port_info info_rdc = {
|
||||
.flags = ATA_FLAG_SLAVE_POSS,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
/* No UDMA */
|
||||
.port_ops = &it821x_rdc_port_ops
|
||||
};
|
||||
|
||||
const struct ata_port_info *ppi[] = { NULL, NULL };
|
||||
static char *mode[2] = { "pass through", "smart" };
|
||||
|
@ -707,21 +904,25 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_RDC) {
|
||||
ppi[0] = &info_rdc;
|
||||
} else {
|
||||
/* Force the card into bypass mode if so requested */
|
||||
if (it8212_noraid) {
|
||||
printk(KERN_INFO DRV_NAME ": forcing bypass mode.\n");
|
||||
it821x_disable_raid(pdev);
|
||||
}
|
||||
pci_read_config_byte(pdev, 0x50, &conf);
|
||||
conf &= 1;
|
||||
|
||||
/* Force the card into bypass mode if so requested */
|
||||
if (it8212_noraid) {
|
||||
printk(KERN_INFO DRV_NAME ": forcing bypass mode.\n");
|
||||
it821x_disable_raid(pdev);
|
||||
printk(KERN_INFO DRV_NAME": controller in %s mode.\n",
|
||||
mode[conf]);
|
||||
if (conf == 0)
|
||||
ppi[0] = &info_passthru;
|
||||
else
|
||||
ppi[0] = &info_smart;
|
||||
}
|
||||
pci_read_config_byte(pdev, 0x50, &conf);
|
||||
conf &= 1;
|
||||
|
||||
printk(KERN_INFO DRV_NAME ": controller in %s mode.\n", mode[conf]);
|
||||
if (conf == 0)
|
||||
ppi[0] = &info_passthru;
|
||||
else
|
||||
ppi[0] = &info_smart;
|
||||
|
||||
return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL);
|
||||
}
|
||||
|
||||
|
@ -745,6 +946,7 @@ static int it821x_reinit_one(struct pci_dev *pdev)
|
|||
static const struct pci_device_id it821x[] = {
|
||||
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
|
||||
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
|
||||
{ PCI_VDEVICE(RDC, 0x1010), },
|
||||
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -98,7 +98,8 @@ static const struct via_isa_bridge {
|
|||
u8 rev_max;
|
||||
u16 flags;
|
||||
} via_isa_bridges[] = {
|
||||
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 |
|
||||
VIA_BAD_AST | VIA_SATA_PATA },
|
||||
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
|
||||
|
@ -322,6 +323,65 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]);
|
||||
}
|
||||
|
||||
/**
|
||||
* via_ata_sff_tf_load - send taskfile registers to host controller
|
||||
* @ap: Port to which output is sent
|
||||
* @tf: ATA taskfile register set
|
||||
*
|
||||
* Outputs ATA taskfile to standard ATA host controller.
|
||||
*
|
||||
* Note: This is to fix the internal bug of via chipsets, which
|
||||
* will reset the device register after changing the IEN bit on
|
||||
* ctl register
|
||||
*/
|
||||
static void via_ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
|
||||
|
||||
if (tf->ctl != ap->last_ctl) {
|
||||
iowrite8(tf->ctl, ioaddr->ctl_addr);
|
||||
iowrite8(tf->device, ioaddr->device_addr);
|
||||
ap->last_ctl = tf->ctl;
|
||||
ata_wait_idle(ap);
|
||||
}
|
||||
|
||||
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
|
||||
iowrite8(tf->hob_feature, ioaddr->feature_addr);
|
||||
iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
|
||||
iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
|
||||
iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
|
||||
iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
|
||||
VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
|
||||
tf->hob_feature,
|
||||
tf->hob_nsect,
|
||||
tf->hob_lbal,
|
||||
tf->hob_lbam,
|
||||
tf->hob_lbah);
|
||||
}
|
||||
|
||||
if (is_addr) {
|
||||
iowrite8(tf->feature, ioaddr->feature_addr);
|
||||
iowrite8(tf->nsect, ioaddr->nsect_addr);
|
||||
iowrite8(tf->lbal, ioaddr->lbal_addr);
|
||||
iowrite8(tf->lbam, ioaddr->lbam_addr);
|
||||
iowrite8(tf->lbah, ioaddr->lbah_addr);
|
||||
VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
|
||||
tf->feature,
|
||||
tf->nsect,
|
||||
tf->lbal,
|
||||
tf->lbam,
|
||||
tf->lbah);
|
||||
}
|
||||
|
||||
if (tf->flags & ATA_TFLAG_DEVICE) {
|
||||
iowrite8(tf->device, ioaddr->device_addr);
|
||||
VPRINTK("device 0x%X\n", tf->device);
|
||||
}
|
||||
|
||||
ata_wait_idle(ap);
|
||||
}
|
||||
|
||||
static struct scsi_host_template via_sht = {
|
||||
ATA_BMDMA_SHT(DRV_NAME),
|
||||
};
|
||||
|
@ -332,11 +392,13 @@ static struct ata_port_operations via_port_ops = {
|
|||
.set_piomode = via_set_piomode,
|
||||
.set_dmamode = via_set_dmamode,
|
||||
.prereset = via_pre_reset,
|
||||
.sff_tf_load = via_ata_tf_load,
|
||||
};
|
||||
|
||||
static struct ata_port_operations via_port_ops_noirq = {
|
||||
.inherits = &via_port_ops,
|
||||
.sff_data_xfer = ata_sff_data_xfer_noirq,
|
||||
.sff_tf_load = via_ata_tf_load,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,9 +60,9 @@
|
|||
|
||||
/* note: prints function name for you */
|
||||
#ifdef ATA_DEBUG
|
||||
#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
|
||||
#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
|
||||
#ifdef ATA_VERBOSE_DEBUG
|
||||
#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
|
||||
#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
|
||||
#else
|
||||
#define VPRINTK(fmt, args...)
|
||||
#endif /* ATA_VERBOSE_DEBUG */
|
||||
|
@ -71,7 +71,7 @@
|
|||
#define VPRINTK(fmt, args...)
|
||||
#endif /* ATA_DEBUG */
|
||||
|
||||
#define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
|
||||
#define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
|
||||
|
||||
/* NEW: debug levels */
|
||||
#define HAVE_LIBATA_MSG 1
|
||||
|
@ -750,6 +750,7 @@ struct ata_port_operations {
|
|||
void (*set_piomode)(struct ata_port *ap, struct ata_device *dev);
|
||||
void (*set_dmamode)(struct ata_port *ap, struct ata_device *dev);
|
||||
int (*set_mode)(struct ata_link *link, struct ata_device **r_failed_dev);
|
||||
unsigned int (*read_id)(struct ata_device *dev, struct ata_taskfile *tf, u16 *id);
|
||||
|
||||
void (*dev_config)(struct ata_device *dev);
|
||||
|
||||
|
@ -951,6 +952,8 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
|
|||
unsigned int ofs, unsigned int len);
|
||||
extern void ata_id_c_string(const u16 *id, unsigned char *s,
|
||||
unsigned int ofs, unsigned int len);
|
||||
extern unsigned int ata_do_dev_read_id(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, u16 *id);
|
||||
extern void ata_qc_complete(struct ata_queued_cmd *qc);
|
||||
extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active);
|
||||
extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
||||
|
|
Loading…
Reference in New Issue