diff options
Diffstat (limited to 'drivers/ata/libata-pmp.c')
-rw-r--r-- | drivers/ata/libata-pmp.c | 209 |
1 files changed, 92 insertions, 117 deletions
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index f6c4b11336e9..c0c4dbcde091 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c | |||
@@ -17,27 +17,35 @@ | |||
17 | * @reg: register to read | 17 | * @reg: register to read |
18 | * @r_val: resulting value | 18 | * @r_val: resulting value |
19 | * | 19 | * |
20 | * Wrapper around ap->ops->pmp_read to make it easier to call and | 20 | * Read PMP register. |
21 | * nomarlize error return value. | ||
22 | * | 21 | * |
23 | * LOCKING: | 22 | * LOCKING: |
24 | * Kernel thread context (may sleep). | 23 | * Kernel thread context (may sleep). |
25 | * | 24 | * |
26 | * RETURNS: | 25 | * RETURNS: |
27 | * 0 on success, -errno on failure. | 26 | * 0 on success, AC_ERR_* mask on failure. |
28 | */ | 27 | */ |
29 | static int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) | 28 | static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) |
30 | { | 29 | { |
31 | struct ata_port *ap = link->ap; | 30 | struct ata_port *ap = link->ap; |
32 | struct ata_device *pmp_dev = ap->link.device; | 31 | struct ata_device *pmp_dev = ap->link.device; |
33 | int rc; | 32 | struct ata_taskfile tf; |
34 | 33 | unsigned int err_mask; | |
35 | might_sleep(); | 34 | |
36 | 35 | ata_tf_init(pmp_dev, &tf); | |
37 | rc = ap->ops->pmp_read(pmp_dev, link->pmp, reg, r_val); | 36 | tf.command = ATA_CMD_PMP_READ; |
38 | if (rc) | 37 | tf.protocol = ATA_PROT_NODATA; |
39 | rc = -EIO; | 38 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
40 | return rc; | 39 | tf.feature = reg; |
40 | tf.device = link->pmp; | ||
41 | |||
42 | err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, | ||
43 | SATA_PMP_SCR_TIMEOUT); | ||
44 | if (err_mask) | ||
45 | return err_mask; | ||
46 | |||
47 | *r_val = tf.nsect | tf.lbal << 8 | tf.lbam << 16 | tf.lbah << 24; | ||
48 | return 0; | ||
41 | } | 49 | } |
42 | 50 | ||
43 | /** | 51 | /** |
@@ -46,27 +54,33 @@ static int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) | |||
46 | * @reg: register to write | 54 | * @reg: register to write |
47 | * @r_val: value to write | 55 | * @r_val: value to write |
48 | * | 56 | * |
49 | * Wrapper around ap->ops->pmp_write to make it easier to call | 57 | * Write PMP register. |
50 | * and nomarlize error return value. | ||
51 | * | 58 | * |
52 | * LOCKING: | 59 | * LOCKING: |
53 | * Kernel thread context (may sleep). | 60 | * Kernel thread context (may sleep). |
54 | * | 61 | * |
55 | * RETURNS: | 62 | * RETURNS: |
56 | * 0 on success, -errno on failure. | 63 | * 0 on success, AC_ERR_* mask on failure. |
57 | */ | 64 | */ |
58 | static int sata_pmp_write(struct ata_link *link, int reg, u32 val) | 65 | static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val) |
59 | { | 66 | { |
60 | struct ata_port *ap = link->ap; | 67 | struct ata_port *ap = link->ap; |
61 | struct ata_device *pmp_dev = ap->link.device; | 68 | struct ata_device *pmp_dev = ap->link.device; |
62 | int rc; | 69 | struct ata_taskfile tf; |
63 | 70 | ||
64 | might_sleep(); | 71 | ata_tf_init(pmp_dev, &tf); |
65 | 72 | tf.command = ATA_CMD_PMP_WRITE; | |
66 | rc = ap->ops->pmp_write(pmp_dev, link->pmp, reg, val); | 73 | tf.protocol = ATA_PROT_NODATA; |
67 | if (rc) | 74 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
68 | rc = -EIO; | 75 | tf.feature = reg; |
69 | return rc; | 76 | tf.device = link->pmp; |
77 | tf.nsect = val & 0xff; | ||
78 | tf.lbal = (val >> 8) & 0xff; | ||
79 | tf.lbam = (val >> 16) & 0xff; | ||
80 | tf.lbah = (val >> 24) & 0xff; | ||
81 | |||
82 | return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, | ||
83 | SATA_PMP_SCR_TIMEOUT); | ||
70 | } | 84 | } |
71 | 85 | ||
72 | /** | 86 | /** |
@@ -100,71 +114,6 @@ int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc) | |||
100 | } | 114 | } |
101 | 115 | ||
102 | /** | 116 | /** |
103 | * sata_pmp_read_init_tf - initialize TF for PMP read | ||
104 | * @tf: taskfile to initialize | ||
105 | * @dev: PMP dev | ||
106 | * @pmp: port multiplier port number | ||
107 | * @reg: register to read | ||
108 | * | ||
109 | * Initialize @tf for PMP read command. | ||
110 | * | ||
111 | * LOCKING: | ||
112 | * None. | ||
113 | */ | ||
114 | void sata_pmp_read_init_tf(struct ata_taskfile *tf, | ||
115 | struct ata_device *dev, int pmp, int reg) | ||
116 | { | ||
117 | ata_tf_init(dev, tf); | ||
118 | tf->command = ATA_CMD_PMP_READ; | ||
119 | tf->protocol = ATA_PROT_NODATA; | ||
120 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
121 | tf->feature = reg; | ||
122 | tf->device = pmp; | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * sata_pmp_read_val - extract PMP read result from TF | ||
127 | * @tf: target TF | ||
128 | * | ||
129 | * Determine PMP read result from @tf. | ||
130 | * | ||
131 | * LOCKING: | ||
132 | * None. | ||
133 | */ | ||
134 | u32 sata_pmp_read_val(const struct ata_taskfile *tf) | ||
135 | { | ||
136 | return tf->nsect | tf->lbal << 8 | tf->lbam << 16 | tf->lbah << 24; | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * sata_pmp_read_init_tf - initialize TF for PMP write | ||
141 | * @tf: taskfile to initialize | ||
142 | * @dev: PMP dev | ||
143 | * @pmp: port multiplier port number | ||
144 | * @reg: register to read | ||
145 | * @val: value to write | ||
146 | * | ||
147 | * Initialize @tf for PMP write command. | ||
148 | * | ||
149 | * LOCKING: | ||
150 | * None. | ||
151 | */ | ||
152 | void sata_pmp_write_init_tf(struct ata_taskfile *tf, | ||
153 | struct ata_device *dev, int pmp, int reg, u32 val) | ||
154 | { | ||
155 | ata_tf_init(dev, tf); | ||
156 | tf->command = ATA_CMD_PMP_WRITE; | ||
157 | tf->protocol = ATA_PROT_NODATA; | ||
158 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
159 | tf->feature = reg; | ||
160 | tf->device = pmp; | ||
161 | tf->nsect = val & 0xff; | ||
162 | tf->lbal = (val >> 8) & 0xff; | ||
163 | tf->lbam = (val >> 16) & 0xff; | ||
164 | tf->lbah = (val >> 24) & 0xff; | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * sata_pmp_scr_read - read PSCR | 117 | * sata_pmp_scr_read - read PSCR |
169 | * @link: ATA link to read PSCR for | 118 | * @link: ATA link to read PSCR for |
170 | * @reg: PSCR to read | 119 | * @reg: PSCR to read |
@@ -181,10 +130,18 @@ void sata_pmp_write_init_tf(struct ata_taskfile *tf, | |||
181 | */ | 130 | */ |
182 | int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *r_val) | 131 | int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *r_val) |
183 | { | 132 | { |
133 | unsigned int err_mask; | ||
134 | |||
184 | if (reg > SATA_PMP_PSCR_CONTROL) | 135 | if (reg > SATA_PMP_PSCR_CONTROL) |
185 | return -EINVAL; | 136 | return -EINVAL; |
186 | 137 | ||
187 | return sata_pmp_read(link, reg, r_val); | 138 | err_mask = sata_pmp_read(link, reg, r_val); |
139 | if (err_mask) { | ||
140 | ata_link_printk(link, KERN_WARNING, "failed to read SCR %d " | ||
141 | "(Emask=0x%x)\n", reg, err_mask); | ||
142 | return -EIO; | ||
143 | } | ||
144 | return 0; | ||
188 | } | 145 | } |
189 | 146 | ||
190 | /** | 147 | /** |
@@ -204,10 +161,18 @@ int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *r_val) | |||
204 | */ | 161 | */ |
205 | int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val) | 162 | int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val) |
206 | { | 163 | { |
164 | unsigned int err_mask; | ||
165 | |||
207 | if (reg > SATA_PMP_PSCR_CONTROL) | 166 | if (reg > SATA_PMP_PSCR_CONTROL) |
208 | return -EINVAL; | 167 | return -EINVAL; |
209 | 168 | ||
210 | return sata_pmp_write(link, reg, val); | 169 | err_mask = sata_pmp_write(link, reg, val); |
170 | if (err_mask) { | ||
171 | ata_link_printk(link, KERN_WARNING, "failed to write SCR %d " | ||
172 | "(Emask=0x%x)\n", reg, err_mask); | ||
173 | return -EIO; | ||
174 | } | ||
175 | return 0; | ||
211 | } | 176 | } |
212 | 177 | ||
213 | /** | 178 | /** |
@@ -361,16 +326,17 @@ void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class) | |||
361 | static int sata_pmp_read_gscr(struct ata_device *dev, u32 *gscr) | 326 | static int sata_pmp_read_gscr(struct ata_device *dev, u32 *gscr) |
362 | { | 327 | { |
363 | static const int gscr_to_read[] = { 0, 1, 2, 32, 33, 64, 96 }; | 328 | static const int gscr_to_read[] = { 0, 1, 2, 32, 33, 64, 96 }; |
364 | int i, rc; | 329 | int i; |
365 | 330 | ||
366 | for (i = 0; i < ARRAY_SIZE(gscr_to_read); i++) { | 331 | for (i = 0; i < ARRAY_SIZE(gscr_to_read); i++) { |
367 | int reg = gscr_to_read[i]; | 332 | int reg = gscr_to_read[i]; |
333 | unsigned int err_mask; | ||
368 | 334 | ||
369 | rc = sata_pmp_read(dev->link, reg, &gscr[reg]); | 335 | err_mask = sata_pmp_read(dev->link, reg, &gscr[reg]); |
370 | if (rc) { | 336 | if (err_mask) { |
371 | ata_dev_printk(dev, KERN_ERR, "failed to read " | 337 | ata_dev_printk(dev, KERN_ERR, "failed to read PMP " |
372 | "PMP GSCR[%d] (errno=%d)\n", reg, rc); | 338 | "GSCR[%d] (Emask=0x%x)\n", reg, err_mask); |
373 | return rc; | 339 | return -EIO; |
374 | } | 340 | } |
375 | } | 341 | } |
376 | 342 | ||
@@ -392,6 +358,7 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
392 | { | 358 | { |
393 | struct ata_port *ap = dev->link->ap; | 359 | struct ata_port *ap = dev->link->ap; |
394 | u32 *gscr = dev->gscr; | 360 | u32 *gscr = dev->gscr; |
361 | unsigned int err_mask = 0; | ||
395 | const char *reason; | 362 | const char *reason; |
396 | int nr_ports, rc; | 363 | int nr_ports, rc; |
397 | 364 | ||
@@ -408,8 +375,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
408 | dev->flags |= ATA_DFLAG_AN; | 375 | dev->flags |= ATA_DFLAG_AN; |
409 | 376 | ||
410 | /* monitor SERR_PHYRDY_CHG on fan-out ports */ | 377 | /* monitor SERR_PHYRDY_CHG on fan-out ports */ |
411 | rc = sata_pmp_write(dev->link, SATA_PMP_GSCR_ERROR_EN, SERR_PHYRDY_CHG); | 378 | err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_ERROR_EN, |
412 | if (rc) { | 379 | SERR_PHYRDY_CHG); |
380 | if (err_mask) { | ||
381 | rc = -EIO; | ||
413 | reason = "failed to write GSCR_ERROR_EN"; | 382 | reason = "failed to write GSCR_ERROR_EN"; |
414 | goto fail; | 383 | goto fail; |
415 | } | 384 | } |
@@ -418,9 +387,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
418 | if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { | 387 | if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { |
419 | gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; | 388 | gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; |
420 | 389 | ||
421 | rc = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN, | 390 | err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN, |
422 | gscr[SATA_PMP_GSCR_FEAT_EN]); | 391 | gscr[SATA_PMP_GSCR_FEAT_EN]); |
423 | if (rc) { | 392 | if (err_mask) { |
393 | rc = -EIO; | ||
424 | reason = "failed to write GSCR_FEAT_EN"; | 394 | reason = "failed to write GSCR_FEAT_EN"; |
425 | goto fail; | 395 | goto fail; |
426 | } | 396 | } |
@@ -447,7 +417,8 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
447 | 417 | ||
448 | fail: | 418 | fail: |
449 | ata_dev_printk(dev, KERN_ERR, | 419 | ata_dev_printk(dev, KERN_ERR, |
450 | "failed to configure Port Multiplier (%s)\n", reason); | 420 | "failed to configure Port Multiplier (%s, Emask=0x%x)\n", |
421 | reason, err_mask); | ||
451 | return rc; | 422 | return rc; |
452 | } | 423 | } |
453 | 424 | ||
@@ -812,13 +783,14 @@ static int sata_pmp_revalidate(struct ata_device *dev, unsigned int new_class) | |||
812 | */ | 783 | */ |
813 | static int sata_pmp_revalidate_quick(struct ata_device *dev) | 784 | static int sata_pmp_revalidate_quick(struct ata_device *dev) |
814 | { | 785 | { |
786 | unsigned int err_mask; | ||
815 | u32 prod_id; | 787 | u32 prod_id; |
816 | int rc; | ||
817 | 788 | ||
818 | rc = sata_pmp_read(dev->link, SATA_PMP_GSCR_PROD_ID, &prod_id); | 789 | err_mask = sata_pmp_read(dev->link, SATA_PMP_GSCR_PROD_ID, &prod_id); |
819 | if (rc) { | 790 | if (err_mask) { |
820 | ata_dev_printk(dev, KERN_ERR, "failed to read PMP product ID\n"); | 791 | ata_dev_printk(dev, KERN_ERR, "failed to read PMP product ID " |
821 | return rc; | 792 | "(Emask=0x%x)\n", err_mask); |
793 | return -EIO; | ||
822 | } | 794 | } |
823 | 795 | ||
824 | if (prod_id != dev->gscr[SATA_PMP_GSCR_PROD_ID]) { | 796 | if (prod_id != dev->gscr[SATA_PMP_GSCR_PROD_ID]) { |
@@ -1049,6 +1021,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap, | |||
1049 | struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; | 1021 | struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; |
1050 | struct ata_link *link; | 1022 | struct ata_link *link; |
1051 | struct ata_device *dev; | 1023 | struct ata_device *dev; |
1024 | unsigned int err_mask; | ||
1052 | u32 gscr_error, sntf; | 1025 | u32 gscr_error, sntf; |
1053 | int cnt, rc; | 1026 | int cnt, rc; |
1054 | 1027 | ||
@@ -1107,20 +1080,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap, | |||
1107 | if (pmp_dev->flags & ATA_DFLAG_AN) { | 1080 | if (pmp_dev->flags & ATA_DFLAG_AN) { |
1108 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; | 1081 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; |
1109 | 1082 | ||
1110 | rc = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, | 1083 | err_mask = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, |
1111 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); | 1084 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); |
1112 | if (rc) { | 1085 | if (err_mask) { |
1113 | ata_dev_printk(pmp_dev, KERN_ERR, | 1086 | ata_dev_printk(pmp_dev, KERN_ERR, "failed to write " |
1114 | "failed to write PMP_FEAT_EN\n"); | 1087 | "PMP_FEAT_EN (Emask=0x%x)\n", err_mask); |
1088 | rc = -EIO; | ||
1115 | goto pmp_fail; | 1089 | goto pmp_fail; |
1116 | } | 1090 | } |
1117 | } | 1091 | } |
1118 | 1092 | ||
1119 | /* check GSCR_ERROR */ | 1093 | /* check GSCR_ERROR */ |
1120 | rc = sata_pmp_read(pmp_link, SATA_PMP_GSCR_ERROR, &gscr_error); | 1094 | err_mask = sata_pmp_read(pmp_link, SATA_PMP_GSCR_ERROR, &gscr_error); |
1121 | if (rc) { | 1095 | if (err_mask) { |
1122 | ata_dev_printk(pmp_dev, KERN_ERR, | 1096 | ata_dev_printk(pmp_dev, KERN_ERR, "failed to read " |
1123 | "failed to read PMP_GSCR_ERROR\n"); | 1097 | "PMP_GSCR_ERROR (Emask=0x%x)\n", err_mask); |
1098 | rc = -EIO; | ||
1124 | goto pmp_fail; | 1099 | goto pmp_fail; |
1125 | } | 1100 | } |
1126 | 1101 | ||