diff options
| -rw-r--r-- | drivers/ata/pata_via.c | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index b08e6e0f82b6..45657cacec43 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
| @@ -62,7 +62,7 @@ | |||
| 62 | #include <linux/dmi.h> | 62 | #include <linux/dmi.h> |
| 63 | 63 | ||
| 64 | #define DRV_NAME "pata_via" | 64 | #define DRV_NAME "pata_via" |
| 65 | #define DRV_VERSION "0.3.3" | 65 | #define DRV_VERSION "0.3.4" |
| 66 | 66 | ||
| 67 | /* | 67 | /* |
| 68 | * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx | 68 | * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx |
| @@ -136,6 +136,9 @@ static const struct via_isa_bridge { | |||
| 136 | { NULL } | 136 | { NULL } |
| 137 | }; | 137 | }; |
| 138 | 138 | ||
| 139 | struct via_port { | ||
| 140 | u8 cached_device; | ||
| 141 | }; | ||
| 139 | 142 | ||
| 140 | /* | 143 | /* |
| 141 | * Cable special cases | 144 | * Cable special cases |
| @@ -346,14 +349,70 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
| 346 | */ | 349 | */ |
| 347 | static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | 350 | static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) |
| 348 | { | 351 | { |
| 349 | struct ata_taskfile tmp_tf; | 352 | struct ata_ioports *ioaddr = &ap->ioaddr; |
| 353 | struct via_port *vp = ap->private_data; | ||
| 354 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
| 355 | int newctl = 0; | ||
| 356 | |||
| 357 | if (tf->ctl != ap->last_ctl) { | ||
| 358 | iowrite8(tf->ctl, ioaddr->ctl_addr); | ||
| 359 | ap->last_ctl = tf->ctl; | ||
| 360 | ata_wait_idle(ap); | ||
| 361 | newctl = 1; | ||
| 362 | } | ||
| 363 | |||
| 364 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
| 365 | iowrite8(tf->device, ioaddr->device_addr); | ||
| 366 | vp->cached_device = tf->device; | ||
| 367 | } else if (newctl) | ||
| 368 | iowrite8(vp->cached_device, ioaddr->device_addr); | ||
| 369 | |||
| 370 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
| 371 | WARN_ON_ONCE(!ioaddr->ctl_addr); | ||
| 372 | iowrite8(tf->hob_feature, ioaddr->feature_addr); | ||
| 373 | iowrite8(tf->hob_nsect, ioaddr->nsect_addr); | ||
| 374 | iowrite8(tf->hob_lbal, ioaddr->lbal_addr); | ||
| 375 | iowrite8(tf->hob_lbam, ioaddr->lbam_addr); | ||
| 376 | iowrite8(tf->hob_lbah, ioaddr->lbah_addr); | ||
| 377 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
| 378 | tf->hob_feature, | ||
| 379 | tf->hob_nsect, | ||
| 380 | tf->hob_lbal, | ||
| 381 | tf->hob_lbam, | ||
| 382 | tf->hob_lbah); | ||
| 383 | } | ||
| 350 | 384 | ||
| 351 | if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) { | 385 | if (is_addr) { |
| 352 | tmp_tf = *tf; | 386 | iowrite8(tf->feature, ioaddr->feature_addr); |
| 353 | tmp_tf.flags |= ATA_TFLAG_DEVICE; | 387 | iowrite8(tf->nsect, ioaddr->nsect_addr); |
| 354 | tf = &tmp_tf; | 388 | iowrite8(tf->lbal, ioaddr->lbal_addr); |
| 389 | iowrite8(tf->lbam, ioaddr->lbam_addr); | ||
| 390 | iowrite8(tf->lbah, ioaddr->lbah_addr); | ||
| 391 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
| 392 | tf->feature, | ||
| 393 | tf->nsect, | ||
| 394 | tf->lbal, | ||
| 395 | tf->lbam, | ||
| 396 | tf->lbah); | ||
| 355 | } | 397 | } |
| 356 | ata_sff_tf_load(ap, tf); | 398 | |
| 399 | ata_wait_idle(ap); | ||
| 400 | } | ||
| 401 | |||
| 402 | static int via_port_start(struct ata_port *ap) | ||
| 403 | { | ||
| 404 | struct via_port *vp; | ||
| 405 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
| 406 | |||
| 407 | int ret = ata_sff_port_start(ap); | ||
| 408 | if (ret < 0) | ||
| 409 | return ret; | ||
| 410 | |||
| 411 | vp = devm_kzalloc(&pdev->dev, sizeof(struct via_port), GFP_KERNEL); | ||
| 412 | if (vp == NULL) | ||
| 413 | return -ENOMEM; | ||
| 414 | ap->private_data = vp; | ||
| 415 | return 0; | ||
| 357 | } | 416 | } |
| 358 | 417 | ||
| 359 | static struct scsi_host_template via_sht = { | 418 | static struct scsi_host_template via_sht = { |
| @@ -367,6 +426,7 @@ static struct ata_port_operations via_port_ops = { | |||
| 367 | .set_dmamode = via_set_dmamode, | 426 | .set_dmamode = via_set_dmamode, |
| 368 | .prereset = via_pre_reset, | 427 | .prereset = via_pre_reset, |
| 369 | .sff_tf_load = via_tf_load, | 428 | .sff_tf_load = via_tf_load, |
| 429 | .port_start = via_port_start, | ||
| 370 | }; | 430 | }; |
| 371 | 431 | ||
| 372 | static struct ata_port_operations via_port_ops_noirq = { | 432 | static struct ata_port_operations via_port_ops_noirq = { |
