diff options
author | Tejun Heo <htejun@gmail.com> | 2007-09-23 00:19:54 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-12 14:55:44 -0400 |
commit | 633273a3ed1cf37ced90475b0f95cf81deab04f1 (patch) | |
tree | 5cd42191d1ea8d5ee84fb2f7c7660f124787d9e8 | |
parent | 3af9a77af9e2b72366363864bfcd3d51465ff98a (diff) |
libata-pmp: hook PMP support and enable it
Hook PMP support into libata and enable it. Connect SCR and probing
functions, and update ata_dev_classify() to detect PMP.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/ata/libata-core.c | 111 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 18 | ||||
-rw-r--r-- | drivers/ata/libata.h | 2 |
3 files changed, 96 insertions, 35 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 9e7f55b71044..d3e78d97529d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -670,29 +670,49 @@ static unsigned int ata_devchk(struct ata_port *ap, unsigned int device) | |||
670 | * None. | 670 | * None. |
671 | * | 671 | * |
672 | * RETURNS: | 672 | * RETURNS: |
673 | * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, or %ATA_DEV_UNKNOWN | 673 | * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP or |
674 | * the event of failure. | 674 | * %ATA_DEV_UNKNOWN the event of failure. |
675 | */ | 675 | */ |
676 | |||
677 | unsigned int ata_dev_classify(const struct ata_taskfile *tf) | 676 | unsigned int ata_dev_classify(const struct ata_taskfile *tf) |
678 | { | 677 | { |
679 | /* Apple's open source Darwin code hints that some devices only | 678 | /* Apple's open source Darwin code hints that some devices only |
680 | * put a proper signature into the LBA mid/high registers, | 679 | * put a proper signature into the LBA mid/high registers, |
681 | * So, we only check those. It's sufficient for uniqueness. | 680 | * So, we only check those. It's sufficient for uniqueness. |
681 | * | ||
682 | * ATA/ATAPI-7 (d1532v1r1: Feb. 19, 2003) specified separate | ||
683 | * signatures for ATA and ATAPI devices attached on SerialATA, | ||
684 | * 0x3c/0xc3 and 0x69/0x96 respectively. However, SerialATA | ||
685 | * spec has never mentioned about using different signatures | ||
686 | * for ATA/ATAPI devices. Then, Serial ATA II: Port | ||
687 | * Multiplier specification began to use 0x69/0x96 to identify | ||
688 | * port multpliers and 0x3c/0xc3 to identify SEMB device. | ||
689 | * ATA/ATAPI-7 dropped descriptions about 0x3c/0xc3 and | ||
690 | * 0x69/0x96 shortly and described them as reserved for | ||
691 | * SerialATA. | ||
692 | * | ||
693 | * We follow the current spec and consider that 0x69/0x96 | ||
694 | * identifies a port multiplier and 0x3c/0xc3 a SEMB device. | ||
682 | */ | 695 | */ |
683 | 696 | if ((tf->lbam == 0) && (tf->lbah == 0)) { | |
684 | if (((tf->lbam == 0) && (tf->lbah == 0)) || | ||
685 | ((tf->lbam == 0x3c) && (tf->lbah == 0xc3))) { | ||
686 | DPRINTK("found ATA device by sig\n"); | 697 | DPRINTK("found ATA device by sig\n"); |
687 | return ATA_DEV_ATA; | 698 | return ATA_DEV_ATA; |
688 | } | 699 | } |
689 | 700 | ||
690 | if (((tf->lbam == 0x14) && (tf->lbah == 0xeb)) || | 701 | if ((tf->lbam == 0x14) && (tf->lbah == 0xeb)) { |
691 | ((tf->lbam == 0x69) && (tf->lbah == 0x96))) { | ||
692 | DPRINTK("found ATAPI device by sig\n"); | 702 | DPRINTK("found ATAPI device by sig\n"); |
693 | return ATA_DEV_ATAPI; | 703 | return ATA_DEV_ATAPI; |
694 | } | 704 | } |
695 | 705 | ||
706 | if ((tf->lbam == 0x69) && (tf->lbah == 0x96)) { | ||
707 | DPRINTK("found PMP device by sig\n"); | ||
708 | return ATA_DEV_PMP; | ||
709 | } | ||
710 | |||
711 | if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { | ||
712 | printk("ata: SEMB device ignored\n"); | ||
713 | return ATA_DEV_SEMB_UNSUP; /* not yet */ | ||
714 | } | ||
715 | |||
696 | DPRINTK("unknown device\n"); | 716 | DPRINTK("unknown device\n"); |
697 | return ATA_DEV_UNKNOWN; | 717 | return ATA_DEV_UNKNOWN; |
698 | } | 718 | } |
@@ -3426,6 +3446,12 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) | |||
3426 | (link->flags & ATA_LFLAG_HRST_TO_RESUME)) | 3446 | (link->flags & ATA_LFLAG_HRST_TO_RESUME)) |
3427 | ehc->i.action |= ATA_EH_HARDRESET; | 3447 | ehc->i.action |= ATA_EH_HARDRESET; |
3428 | 3448 | ||
3449 | /* Some PMPs don't work with only SRST, force hardreset if PMP | ||
3450 | * is supported. | ||
3451 | */ | ||
3452 | if (ap->flags & ATA_FLAG_PMP) | ||
3453 | ehc->i.action |= ATA_EH_HARDRESET; | ||
3454 | |||
3429 | /* if we're about to do hardreset, nothing more to do */ | 3455 | /* if we're about to do hardreset, nothing more to do */ |
3430 | if (ehc->i.action & ATA_EH_HARDRESET) | 3456 | if (ehc->i.action & ATA_EH_HARDRESET) |
3431 | return 0; | 3457 | return 0; |
@@ -3616,6 +3642,16 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class, | |||
3616 | /* wait a while before checking status, see SRST for more info */ | 3642 | /* wait a while before checking status, see SRST for more info */ |
3617 | msleep(150); | 3643 | msleep(150); |
3618 | 3644 | ||
3645 | /* If PMP is supported, we have to do follow-up SRST. Note | ||
3646 | * that some PMPs don't send D2H Reg FIS after hardreset at | ||
3647 | * all if the first port is empty. Wait for it just for a | ||
3648 | * second and request follow-up SRST. | ||
3649 | */ | ||
3650 | if (ap->flags & ATA_FLAG_PMP) { | ||
3651 | ata_wait_ready(ap, jiffies + HZ); | ||
3652 | return -EAGAIN; | ||
3653 | } | ||
3654 | |||
3619 | rc = ata_wait_ready(ap, deadline); | 3655 | rc = ata_wait_ready(ap, deadline); |
3620 | /* link occupied, -ENODEV too is an error */ | 3656 | /* link occupied, -ENODEV too is an error */ |
3621 | if (rc) { | 3657 | if (rc) { |
@@ -5966,22 +6002,26 @@ int sata_scr_valid(struct ata_link *link) | |||
5966 | * @val: Place to store read value | 6002 | * @val: Place to store read value |
5967 | * | 6003 | * |
5968 | * Read SCR register @reg of @link into *@val. This function is | 6004 | * Read SCR register @reg of @link into *@val. This function is |
5969 | * guaranteed to succeed if the cable type of the port is SATA | 6005 | * guaranteed to succeed if @link is ap->link, the cable type of |
5970 | * and the port implements ->scr_read. | 6006 | * the port is SATA and the port implements ->scr_read. |
5971 | * | 6007 | * |
5972 | * LOCKING: | 6008 | * LOCKING: |
5973 | * None. | 6009 | * None if @link is ap->link. Kernel thread context otherwise. |
5974 | * | 6010 | * |
5975 | * RETURNS: | 6011 | * RETURNS: |
5976 | * 0 on success, negative errno on failure. | 6012 | * 0 on success, negative errno on failure. |
5977 | */ | 6013 | */ |
5978 | int sata_scr_read(struct ata_link *link, int reg, u32 *val) | 6014 | int sata_scr_read(struct ata_link *link, int reg, u32 *val) |
5979 | { | 6015 | { |
5980 | struct ata_port *ap = link->ap; | 6016 | if (ata_is_host_link(link)) { |
6017 | struct ata_port *ap = link->ap; | ||
5981 | 6018 | ||
5982 | if (sata_scr_valid(link)) | 6019 | if (sata_scr_valid(link)) |
5983 | return ap->ops->scr_read(ap, reg, val); | 6020 | return ap->ops->scr_read(ap, reg, val); |
5984 | return -EOPNOTSUPP; | 6021 | return -EOPNOTSUPP; |
6022 | } | ||
6023 | |||
6024 | return sata_pmp_scr_read(link, reg, val); | ||
5985 | } | 6025 | } |
5986 | 6026 | ||
5987 | /** | 6027 | /** |
@@ -5991,22 +6031,26 @@ int sata_scr_read(struct ata_link *link, int reg, u32 *val) | |||
5991 | * @val: value to write | 6031 | * @val: value to write |
5992 | * | 6032 | * |
5993 | * Write @val to SCR register @reg of @link. This function is | 6033 | * Write @val to SCR register @reg of @link. This function is |
5994 | * guaranteed to succeed if the cable type of the port is SATA | 6034 | * guaranteed to succeed if @link is ap->link, the cable type of |
5995 | * and the port implements ->scr_read. | 6035 | * the port is SATA and the port implements ->scr_read. |
5996 | * | 6036 | * |
5997 | * LOCKING: | 6037 | * LOCKING: |
5998 | * None. | 6038 | * None if @link is ap->link. Kernel thread context otherwise. |
5999 | * | 6039 | * |
6000 | * RETURNS: | 6040 | * RETURNS: |
6001 | * 0 on success, negative errno on failure. | 6041 | * 0 on success, negative errno on failure. |
6002 | */ | 6042 | */ |
6003 | int sata_scr_write(struct ata_link *link, int reg, u32 val) | 6043 | int sata_scr_write(struct ata_link *link, int reg, u32 val) |
6004 | { | 6044 | { |
6005 | struct ata_port *ap = link->ap; | 6045 | if (ata_is_host_link(link)) { |
6046 | struct ata_port *ap = link->ap; | ||
6006 | 6047 | ||
6007 | if (sata_scr_valid(link)) | 6048 | if (sata_scr_valid(link)) |
6008 | return ap->ops->scr_write(ap, reg, val); | 6049 | return ap->ops->scr_write(ap, reg, val); |
6009 | return -EOPNOTSUPP; | 6050 | return -EOPNOTSUPP; |
6051 | } | ||
6052 | |||
6053 | return sata_pmp_scr_write(link, reg, val); | ||
6010 | } | 6054 | } |
6011 | 6055 | ||
6012 | /** | 6056 | /** |
@@ -6019,23 +6063,27 @@ int sata_scr_write(struct ata_link *link, int reg, u32 val) | |||
6019 | * function performs flush after writing to the register. | 6063 | * function performs flush after writing to the register. |
6020 | * | 6064 | * |
6021 | * LOCKING: | 6065 | * LOCKING: |
6022 | * None. | 6066 | * None if @link is ap->link. Kernel thread context otherwise. |
6023 | * | 6067 | * |
6024 | * RETURNS: | 6068 | * RETURNS: |
6025 | * 0 on success, negative errno on failure. | 6069 | * 0 on success, negative errno on failure. |
6026 | */ | 6070 | */ |
6027 | int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) | 6071 | int sata_scr_write_flush(struct ata_link *link, int reg, u32 val) |
6028 | { | 6072 | { |
6029 | struct ata_port *ap = link->ap; | 6073 | if (ata_is_host_link(link)) { |
6030 | int rc; | 6074 | struct ata_port *ap = link->ap; |
6075 | int rc; | ||
6031 | 6076 | ||
6032 | if (sata_scr_valid(link)) { | 6077 | if (sata_scr_valid(link)) { |
6033 | rc = ap->ops->scr_write(ap, reg, val); | 6078 | rc = ap->ops->scr_write(ap, reg, val); |
6034 | if (rc == 0) | 6079 | if (rc == 0) |
6035 | rc = ap->ops->scr_read(ap, reg, &val); | 6080 | rc = ap->ops->scr_read(ap, reg, &val); |
6036 | return rc; | 6081 | return rc; |
6082 | } | ||
6083 | return -EOPNOTSUPP; | ||
6037 | } | 6084 | } |
6038 | return -EOPNOTSUPP; | 6085 | |
6086 | return sata_pmp_scr_write(link, reg, val); | ||
6039 | } | 6087 | } |
6040 | 6088 | ||
6041 | /** | 6089 | /** |
@@ -6424,6 +6472,7 @@ static void ata_host_release(struct device *gendev, void *res) | |||
6424 | if (ap->scsi_host) | 6472 | if (ap->scsi_host) |
6425 | scsi_host_put(ap->scsi_host); | 6473 | scsi_host_put(ap->scsi_host); |
6426 | 6474 | ||
6475 | kfree(ap->pmp_link); | ||
6427 | kfree(ap); | 6476 | kfree(ap); |
6428 | host->ports[i] = NULL; | 6477 | host->ports[i] = NULL; |
6429 | } | 6478 | } |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 687419b66708..5f2c0f376f74 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2209,6 +2209,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, | |||
2209 | readid_flags |= ATA_READID_POSTRESET; | 2209 | readid_flags |= ATA_READID_POSTRESET; |
2210 | 2210 | ||
2211 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { | 2211 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { |
2212 | WARN_ON(dev->class == ATA_DEV_PMP); | ||
2213 | |||
2212 | if (ata_link_offline(link)) { | 2214 | if (ata_link_offline(link)) { |
2213 | rc = -EIO; | 2215 | rc = -EIO; |
2214 | goto err; | 2216 | goto err; |
@@ -2234,8 +2236,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, | |||
2234 | ata_class_enabled(ehc->classes[dev->devno])) { | 2236 | ata_class_enabled(ehc->classes[dev->devno])) { |
2235 | dev->class = ehc->classes[dev->devno]; | 2237 | dev->class = ehc->classes[dev->devno]; |
2236 | 2238 | ||
2237 | rc = ata_dev_read_id(dev, &dev->class, readid_flags, | 2239 | if (dev->class == ATA_DEV_PMP) |
2238 | dev->id); | 2240 | rc = sata_pmp_attach(dev); |
2241 | else | ||
2242 | rc = ata_dev_read_id(dev, &dev->class, | ||
2243 | readid_flags, dev->id); | ||
2239 | switch (rc) { | 2244 | switch (rc) { |
2240 | case 0: | 2245 | case 0: |
2241 | new_mask |= 1 << dev->devno; | 2246 | new_mask |= 1 << dev->devno; |
@@ -2264,7 +2269,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, | |||
2264 | * device detection messages backwards. | 2269 | * device detection messages backwards. |
2265 | */ | 2270 | */ |
2266 | ata_link_for_each_dev(dev, link) { | 2271 | ata_link_for_each_dev(dev, link) { |
2267 | if (!(new_mask & (1 << dev->devno))) | 2272 | if (!(new_mask & (1 << dev->devno)) || |
2273 | dev->class == ATA_DEV_PMP) | ||
2268 | continue; | 2274 | continue; |
2269 | 2275 | ||
2270 | ehc->i.flags |= ATA_EHI_PRINTINFO; | 2276 | ehc->i.flags |= ATA_EHI_PRINTINFO; |
@@ -2521,6 +2527,12 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2521 | if (rc) | 2527 | if (rc) |
2522 | goto dev_fail; | 2528 | goto dev_fail; |
2523 | 2529 | ||
2530 | /* if PMP got attached, return, pmp EH will take care of it */ | ||
2531 | if (link->device->class == ATA_DEV_PMP) { | ||
2532 | ehc->i.action = 0; | ||
2533 | return 0; | ||
2534 | } | ||
2535 | |||
2524 | /* configure transfer mode if necessary */ | 2536 | /* configure transfer mode if necessary */ |
2525 | if (ehc->i.flags & ATA_EHI_SETMODE) { | 2537 | if (ehc->i.flags & ATA_EHI_SETMODE) { |
2526 | rc = ata_set_mode(link, &dev); | 2538 | rc = ata_set_mode(link, &dev); |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index a9b9c9e1e105..a44172fd1f5c 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -29,7 +29,7 @@ | |||
29 | #define __LIBATA_H__ | 29 | #define __LIBATA_H__ |
30 | 30 | ||
31 | #define DRV_NAME "libata" | 31 | #define DRV_NAME "libata" |
32 | #define DRV_VERSION "2.21" /* must be exactly four chars */ | 32 | #define DRV_VERSION "3.00" /* must be exactly four chars */ |
33 | 33 | ||
34 | struct ata_scsi_args { | 34 | struct ata_scsi_args { |
35 | struct ata_device *dev; | 35 | struct ata_device *dev; |