diff options
Diffstat (limited to 'drivers/ata/ahci.c')
| -rw-r--r-- | drivers/ata/ahci.c | 309 |
1 files changed, 83 insertions, 226 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b1eb4e24c86a..739ba3f222e8 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -62,7 +62,6 @@ enum { | |||
| 62 | AHCI_MAX_PORTS = 32, | 62 | AHCI_MAX_PORTS = 32, |
| 63 | AHCI_MAX_SG = 168, /* hardware max is 64K */ | 63 | AHCI_MAX_SG = 168, /* hardware max is 64K */ |
| 64 | AHCI_DMA_BOUNDARY = 0xffffffff, | 64 | AHCI_DMA_BOUNDARY = 0xffffffff, |
| 65 | AHCI_USE_CLUSTERING = 1, | ||
| 66 | AHCI_MAX_CMDS = 32, | 65 | AHCI_MAX_CMDS = 32, |
| 67 | AHCI_CMD_SZ = 32, | 66 | AHCI_CMD_SZ = 32, |
| 68 | AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ, | 67 | AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ, |
| @@ -198,7 +197,6 @@ enum { | |||
| 198 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 197 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
| 199 | ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | | 198 | ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | |
| 200 | ATA_FLAG_IPM, | 199 | ATA_FLAG_IPM, |
| 201 | AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY, | ||
| 202 | 200 | ||
| 203 | ICH_MAP = 0x90, /* ICH MAP register */ | 201 | ICH_MAP = 0x90, /* ICH MAP register */ |
| 204 | }; | 202 | }; |
| @@ -245,19 +243,24 @@ static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); | |||
| 245 | static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); | 243 | static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
| 246 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 244 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
| 247 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | 245 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); |
| 248 | static void ahci_irq_clear(struct ata_port *ap); | 246 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); |
| 249 | static int ahci_port_start(struct ata_port *ap); | 247 | static int ahci_port_start(struct ata_port *ap); |
| 250 | static void ahci_port_stop(struct ata_port *ap); | 248 | static void ahci_port_stop(struct ata_port *ap); |
| 251 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | ||
| 252 | static void ahci_qc_prep(struct ata_queued_cmd *qc); | 249 | static void ahci_qc_prep(struct ata_queued_cmd *qc); |
| 253 | static u8 ahci_check_status(struct ata_port *ap); | ||
| 254 | static void ahci_freeze(struct ata_port *ap); | 250 | static void ahci_freeze(struct ata_port *ap); |
| 255 | static void ahci_thaw(struct ata_port *ap); | 251 | static void ahci_thaw(struct ata_port *ap); |
| 256 | static void ahci_pmp_attach(struct ata_port *ap); | 252 | static void ahci_pmp_attach(struct ata_port *ap); |
| 257 | static void ahci_pmp_detach(struct ata_port *ap); | 253 | static void ahci_pmp_detach(struct ata_port *ap); |
| 254 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | ||
| 255 | unsigned long deadline); | ||
| 256 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, | ||
| 257 | unsigned long deadline); | ||
| 258 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | ||
| 259 | unsigned long deadline); | ||
| 260 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | ||
| 261 | unsigned long deadline); | ||
| 262 | static void ahci_postreset(struct ata_link *link, unsigned int *class); | ||
| 258 | static void ahci_error_handler(struct ata_port *ap); | 263 | static void ahci_error_handler(struct ata_port *ap); |
| 259 | static void ahci_vt8251_error_handler(struct ata_port *ap); | ||
| 260 | static void ahci_p5wdh_error_handler(struct ata_port *ap); | ||
| 261 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 264 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); |
| 262 | static int ahci_port_resume(struct ata_port *ap); | 265 | static int ahci_port_resume(struct ata_port *ap); |
| 263 | static void ahci_dev_config(struct ata_device *dev); | 266 | static void ahci_dev_config(struct ata_device *dev); |
| @@ -276,129 +279,54 @@ static struct class_device_attribute *ahci_shost_attrs[] = { | |||
| 276 | }; | 279 | }; |
| 277 | 280 | ||
| 278 | static struct scsi_host_template ahci_sht = { | 281 | static struct scsi_host_template ahci_sht = { |
| 279 | .module = THIS_MODULE, | 282 | ATA_NCQ_SHT(DRV_NAME), |
| 280 | .name = DRV_NAME, | ||
| 281 | .ioctl = ata_scsi_ioctl, | ||
| 282 | .queuecommand = ata_scsi_queuecmd, | ||
| 283 | .change_queue_depth = ata_scsi_change_queue_depth, | ||
| 284 | .can_queue = AHCI_MAX_CMDS - 1, | 283 | .can_queue = AHCI_MAX_CMDS - 1, |
| 285 | .this_id = ATA_SHT_THIS_ID, | ||
| 286 | .sg_tablesize = AHCI_MAX_SG, | 284 | .sg_tablesize = AHCI_MAX_SG, |
| 287 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | ||
| 288 | .emulated = ATA_SHT_EMULATED, | ||
| 289 | .use_clustering = AHCI_USE_CLUSTERING, | ||
| 290 | .proc_name = DRV_NAME, | ||
| 291 | .dma_boundary = AHCI_DMA_BOUNDARY, | 285 | .dma_boundary = AHCI_DMA_BOUNDARY, |
| 292 | .slave_configure = ata_scsi_slave_config, | ||
| 293 | .slave_destroy = ata_scsi_slave_destroy, | ||
| 294 | .bios_param = ata_std_bios_param, | ||
| 295 | .shost_attrs = ahci_shost_attrs, | 286 | .shost_attrs = ahci_shost_attrs, |
| 296 | }; | 287 | }; |
| 297 | 288 | ||
| 298 | static const struct ata_port_operations ahci_ops = { | 289 | static struct ata_port_operations ahci_ops = { |
| 299 | .check_status = ahci_check_status, | 290 | .inherits = &sata_pmp_port_ops, |
| 300 | .check_altstatus = ahci_check_status, | ||
| 301 | .dev_select = ata_noop_dev_select, | ||
| 302 | |||
| 303 | .dev_config = ahci_dev_config, | ||
| 304 | |||
| 305 | .tf_read = ahci_tf_read, | ||
| 306 | 291 | ||
| 307 | .qc_defer = sata_pmp_qc_defer_cmd_switch, | 292 | .qc_defer = sata_pmp_qc_defer_cmd_switch, |
| 308 | .qc_prep = ahci_qc_prep, | 293 | .qc_prep = ahci_qc_prep, |
| 309 | .qc_issue = ahci_qc_issue, | 294 | .qc_issue = ahci_qc_issue, |
| 310 | 295 | .qc_fill_rtf = ahci_qc_fill_rtf, | |
| 311 | .irq_clear = ahci_irq_clear, | ||
| 312 | |||
| 313 | .scr_read = ahci_scr_read, | ||
| 314 | .scr_write = ahci_scr_write, | ||
| 315 | 296 | ||
| 316 | .freeze = ahci_freeze, | 297 | .freeze = ahci_freeze, |
| 317 | .thaw = ahci_thaw, | 298 | .thaw = ahci_thaw, |
| 318 | 299 | .softreset = ahci_softreset, | |
| 300 | .hardreset = ahci_hardreset, | ||
| 301 | .postreset = ahci_postreset, | ||
| 302 | .pmp_softreset = ahci_softreset, | ||
| 319 | .error_handler = ahci_error_handler, | 303 | .error_handler = ahci_error_handler, |
| 320 | .post_internal_cmd = ahci_post_internal_cmd, | 304 | .post_internal_cmd = ahci_post_internal_cmd, |
| 321 | 305 | .dev_config = ahci_dev_config, | |
| 322 | .pmp_attach = ahci_pmp_attach, | ||
| 323 | .pmp_detach = ahci_pmp_detach, | ||
| 324 | |||
| 325 | #ifdef CONFIG_PM | ||
| 326 | .port_suspend = ahci_port_suspend, | ||
| 327 | .port_resume = ahci_port_resume, | ||
| 328 | #endif | ||
| 329 | .enable_pm = ahci_enable_alpm, | ||
| 330 | .disable_pm = ahci_disable_alpm, | ||
| 331 | |||
| 332 | .port_start = ahci_port_start, | ||
| 333 | .port_stop = ahci_port_stop, | ||
| 334 | }; | ||
| 335 | |||
| 336 | static const struct ata_port_operations ahci_vt8251_ops = { | ||
| 337 | .check_status = ahci_check_status, | ||
| 338 | .check_altstatus = ahci_check_status, | ||
| 339 | .dev_select = ata_noop_dev_select, | ||
| 340 | |||
| 341 | .tf_read = ahci_tf_read, | ||
| 342 | |||
| 343 | .qc_defer = sata_pmp_qc_defer_cmd_switch, | ||
| 344 | .qc_prep = ahci_qc_prep, | ||
| 345 | .qc_issue = ahci_qc_issue, | ||
| 346 | |||
| 347 | .irq_clear = ahci_irq_clear, | ||
| 348 | 306 | ||
| 349 | .scr_read = ahci_scr_read, | 307 | .scr_read = ahci_scr_read, |
| 350 | .scr_write = ahci_scr_write, | 308 | .scr_write = ahci_scr_write, |
| 351 | |||
| 352 | .freeze = ahci_freeze, | ||
| 353 | .thaw = ahci_thaw, | ||
| 354 | |||
| 355 | .error_handler = ahci_vt8251_error_handler, | ||
| 356 | .post_internal_cmd = ahci_post_internal_cmd, | ||
| 357 | |||
| 358 | .pmp_attach = ahci_pmp_attach, | 309 | .pmp_attach = ahci_pmp_attach, |
| 359 | .pmp_detach = ahci_pmp_detach, | 310 | .pmp_detach = ahci_pmp_detach, |
| 360 | 311 | ||
| 312 | .enable_pm = ahci_enable_alpm, | ||
| 313 | .disable_pm = ahci_disable_alpm, | ||
| 361 | #ifdef CONFIG_PM | 314 | #ifdef CONFIG_PM |
| 362 | .port_suspend = ahci_port_suspend, | 315 | .port_suspend = ahci_port_suspend, |
| 363 | .port_resume = ahci_port_resume, | 316 | .port_resume = ahci_port_resume, |
| 364 | #endif | 317 | #endif |
| 365 | |||
| 366 | .port_start = ahci_port_start, | 318 | .port_start = ahci_port_start, |
| 367 | .port_stop = ahci_port_stop, | 319 | .port_stop = ahci_port_stop, |
| 368 | }; | 320 | }; |
| 369 | 321 | ||
| 370 | static const struct ata_port_operations ahci_p5wdh_ops = { | 322 | static struct ata_port_operations ahci_vt8251_ops = { |
| 371 | .check_status = ahci_check_status, | 323 | .inherits = &ahci_ops, |
| 372 | .check_altstatus = ahci_check_status, | 324 | .hardreset = ahci_vt8251_hardreset, |
| 373 | .dev_select = ata_noop_dev_select, | 325 | }; |
| 374 | |||
| 375 | .tf_read = ahci_tf_read, | ||
| 376 | |||
| 377 | .qc_defer = sata_pmp_qc_defer_cmd_switch, | ||
| 378 | .qc_prep = ahci_qc_prep, | ||
| 379 | .qc_issue = ahci_qc_issue, | ||
| 380 | |||
| 381 | .irq_clear = ahci_irq_clear, | ||
| 382 | |||
| 383 | .scr_read = ahci_scr_read, | ||
| 384 | .scr_write = ahci_scr_write, | ||
| 385 | |||
| 386 | .freeze = ahci_freeze, | ||
| 387 | .thaw = ahci_thaw, | ||
| 388 | |||
| 389 | .error_handler = ahci_p5wdh_error_handler, | ||
| 390 | .post_internal_cmd = ahci_post_internal_cmd, | ||
| 391 | |||
| 392 | .pmp_attach = ahci_pmp_attach, | ||
| 393 | .pmp_detach = ahci_pmp_detach, | ||
| 394 | |||
| 395 | #ifdef CONFIG_PM | ||
| 396 | .port_suspend = ahci_port_suspend, | ||
| 397 | .port_resume = ahci_port_resume, | ||
| 398 | #endif | ||
| 399 | 326 | ||
| 400 | .port_start = ahci_port_start, | 327 | static struct ata_port_operations ahci_p5wdh_ops = { |
| 401 | .port_stop = ahci_port_stop, | 328 | .inherits = &ahci_ops, |
| 329 | .hardreset = ahci_p5wdh_hardreset, | ||
| 402 | }; | 330 | }; |
| 403 | 331 | ||
| 404 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | 332 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) |
| @@ -407,7 +335,6 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 407 | /* board_ahci */ | 335 | /* board_ahci */ |
| 408 | { | 336 | { |
| 409 | .flags = AHCI_FLAG_COMMON, | 337 | .flags = AHCI_FLAG_COMMON, |
| 410 | .link_flags = AHCI_LFLAG_COMMON, | ||
| 411 | .pio_mask = 0x1f, /* pio0-4 */ | 338 | .pio_mask = 0x1f, /* pio0-4 */ |
| 412 | .udma_mask = ATA_UDMA6, | 339 | .udma_mask = ATA_UDMA6, |
| 413 | .port_ops = &ahci_ops, | 340 | .port_ops = &ahci_ops, |
| @@ -416,7 +343,6 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 416 | { | 343 | { |
| 417 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), | 344 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), |
| 418 | .flags = AHCI_FLAG_COMMON, | 345 | .flags = AHCI_FLAG_COMMON, |
| 419 | .link_flags = AHCI_LFLAG_COMMON | ATA_LFLAG_HRST_TO_RESUME, | ||
| 420 | .pio_mask = 0x1f, /* pio0-4 */ | 346 | .pio_mask = 0x1f, /* pio0-4 */ |
| 421 | .udma_mask = ATA_UDMA6, | 347 | .udma_mask = ATA_UDMA6, |
| 422 | .port_ops = &ahci_vt8251_ops, | 348 | .port_ops = &ahci_vt8251_ops, |
| @@ -425,7 +351,6 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 425 | { | 351 | { |
| 426 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), | 352 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), |
| 427 | .flags = AHCI_FLAG_COMMON, | 353 | .flags = AHCI_FLAG_COMMON, |
| 428 | .link_flags = AHCI_LFLAG_COMMON, | ||
| 429 | .pio_mask = 0x1f, /* pio0-4 */ | 354 | .pio_mask = 0x1f, /* pio0-4 */ |
| 430 | .udma_mask = ATA_UDMA6, | 355 | .udma_mask = ATA_UDMA6, |
| 431 | .port_ops = &ahci_ops, | 356 | .port_ops = &ahci_ops, |
| @@ -436,7 +361,6 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 436 | AHCI_HFLAG_32BIT_ONLY | | 361 | AHCI_HFLAG_32BIT_ONLY | |
| 437 | AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), | 362 | AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), |
| 438 | .flags = AHCI_FLAG_COMMON, | 363 | .flags = AHCI_FLAG_COMMON, |
| 439 | .link_flags = AHCI_LFLAG_COMMON, | ||
| 440 | .pio_mask = 0x1f, /* pio0-4 */ | 364 | .pio_mask = 0x1f, /* pio0-4 */ |
| 441 | .udma_mask = ATA_UDMA6, | 365 | .udma_mask = ATA_UDMA6, |
| 442 | .port_ops = &ahci_ops, | 366 | .port_ops = &ahci_ops, |
| @@ -447,7 +371,6 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 447 | AHCI_HFLAG_MV_PATA), | 371 | AHCI_HFLAG_MV_PATA), |
| 448 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 372 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 449 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, | 373 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, |
| 450 | .link_flags = AHCI_LFLAG_COMMON, | ||
| 451 | .pio_mask = 0x1f, /* pio0-4 */ | 374 | .pio_mask = 0x1f, /* pio0-4 */ |
| 452 | .udma_mask = ATA_UDMA6, | 375 | .udma_mask = ATA_UDMA6, |
| 453 | .port_ops = &ahci_ops, | 376 | .port_ops = &ahci_ops, |
| @@ -457,7 +380,6 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 457 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 380 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | |
| 458 | AHCI_HFLAG_NO_PMP), | 381 | AHCI_HFLAG_NO_PMP), |
| 459 | .flags = AHCI_FLAG_COMMON, | 382 | .flags = AHCI_FLAG_COMMON, |
| 460 | .link_flags = AHCI_LFLAG_COMMON, | ||
| 461 | .pio_mask = 0x1f, /* pio0-4 */ | 383 | .pio_mask = 0x1f, /* pio0-4 */ |
| 462 | .udma_mask = ATA_UDMA6, | 384 | .udma_mask = ATA_UDMA6, |
| 463 | .port_ops = &ahci_ops, | 385 | .port_ops = &ahci_ops, |
| @@ -1255,13 +1177,14 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | |||
| 1255 | 1177 | ||
| 1256 | static int ahci_kick_engine(struct ata_port *ap, int force_restart) | 1178 | static int ahci_kick_engine(struct ata_port *ap, int force_restart) |
| 1257 | { | 1179 | { |
| 1258 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; | 1180 | void __iomem *port_mmio = ahci_port_base(ap); |
| 1259 | struct ahci_host_priv *hpriv = ap->host->private_data; | 1181 | struct ahci_host_priv *hpriv = ap->host->private_data; |
| 1182 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
| 1260 | u32 tmp; | 1183 | u32 tmp; |
| 1261 | int busy, rc; | 1184 | int busy, rc; |
| 1262 | 1185 | ||
| 1263 | /* do we need to kick the port? */ | 1186 | /* do we need to kick the port? */ |
| 1264 | busy = ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ); | 1187 | busy = status & (ATA_BUSY | ATA_DRQ); |
| 1265 | if (!busy && !force_restart) | 1188 | if (!busy && !force_restart) |
| 1266 | return 0; | 1189 | return 0; |
| 1267 | 1190 | ||
| @@ -1328,10 +1251,21 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, | |||
| 1328 | return 0; | 1251 | return 0; |
| 1329 | } | 1252 | } |
| 1330 | 1253 | ||
| 1331 | static int ahci_do_softreset(struct ata_link *link, unsigned int *class, | 1254 | static int ahci_check_ready(struct ata_link *link) |
| 1332 | int pmp, unsigned long deadline) | 1255 | { |
| 1256 | void __iomem *port_mmio = ahci_port_base(link->ap); | ||
| 1257 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
| 1258 | |||
| 1259 | if (!(status & ATA_BUSY)) | ||
| 1260 | return 1; | ||
| 1261 | return 0; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | ||
| 1265 | unsigned long deadline) | ||
| 1333 | { | 1266 | { |
| 1334 | struct ata_port *ap = link->ap; | 1267 | struct ata_port *ap = link->ap; |
| 1268 | int pmp = sata_srst_pmp(link); | ||
| 1335 | const char *reason = NULL; | 1269 | const char *reason = NULL; |
| 1336 | unsigned long now, msecs; | 1270 | unsigned long now, msecs; |
| 1337 | struct ata_taskfile tf; | 1271 | struct ata_taskfile tf; |
| @@ -1339,12 +1273,6 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
| 1339 | 1273 | ||
| 1340 | DPRINTK("ENTER\n"); | 1274 | DPRINTK("ENTER\n"); |
| 1341 | 1275 | ||
| 1342 | if (ata_link_offline(link)) { | ||
| 1343 | DPRINTK("PHY reports no device\n"); | ||
| 1344 | *class = ATA_DEV_NONE; | ||
| 1345 | return 0; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | /* prepare for SRST (AHCI-1.1 10.4.1) */ | 1276 | /* prepare for SRST (AHCI-1.1 10.4.1) */ |
| 1349 | rc = ahci_kick_engine(ap, 1); | 1277 | rc = ahci_kick_engine(ap, 1); |
| 1350 | if (rc && rc != -EOPNOTSUPP) | 1278 | if (rc && rc != -EOPNOTSUPP) |
| @@ -1374,10 +1302,8 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
| 1374 | tf.ctl &= ~ATA_SRST; | 1302 | tf.ctl &= ~ATA_SRST; |
| 1375 | ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); | 1303 | ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); |
| 1376 | 1304 | ||
| 1377 | /* wait a while before checking status */ | 1305 | /* wait for link to become ready */ |
| 1378 | ata_wait_after_reset(ap, deadline); | 1306 | rc = ata_wait_after_reset(link, deadline, ahci_check_ready); |
| 1379 | |||
| 1380 | rc = ata_wait_ready(ap, deadline); | ||
| 1381 | /* link occupied, -ENODEV too is an error */ | 1307 | /* link occupied, -ENODEV too is an error */ |
| 1382 | if (rc) { | 1308 | if (rc) { |
| 1383 | reason = "device not ready"; | 1309 | reason = "device not ready"; |
| @@ -1393,24 +1319,15 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
| 1393 | return rc; | 1319 | return rc; |
| 1394 | } | 1320 | } |
| 1395 | 1321 | ||
| 1396 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | ||
| 1397 | unsigned long deadline) | ||
| 1398 | { | ||
| 1399 | int pmp = 0; | ||
| 1400 | |||
| 1401 | if (link->ap->flags & ATA_FLAG_PMP) | ||
| 1402 | pmp = SATA_PMP_CTRL_PORT; | ||
| 1403 | |||
| 1404 | return ahci_do_softreset(link, class, pmp, deadline); | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, | 1322 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, |
| 1408 | unsigned long deadline) | 1323 | unsigned long deadline) |
| 1409 | { | 1324 | { |
| 1325 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | ||
| 1410 | struct ata_port *ap = link->ap; | 1326 | struct ata_port *ap = link->ap; |
| 1411 | struct ahci_port_priv *pp = ap->private_data; | 1327 | struct ahci_port_priv *pp = ap->private_data; |
| 1412 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 1328 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
| 1413 | struct ata_taskfile tf; | 1329 | struct ata_taskfile tf; |
| 1330 | bool online; | ||
| 1414 | int rc; | 1331 | int rc; |
| 1415 | 1332 | ||
| 1416 | DPRINTK("ENTER\n"); | 1333 | DPRINTK("ENTER\n"); |
| @@ -1422,14 +1339,13 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1422 | tf.command = 0x80; | 1339 | tf.command = 0x80; |
| 1423 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | 1340 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
| 1424 | 1341 | ||
| 1425 | rc = sata_std_hardreset(link, class, deadline); | 1342 | rc = sata_link_hardreset(link, timing, deadline, &online, |
| 1343 | ahci_check_ready); | ||
| 1426 | 1344 | ||
| 1427 | ahci_start_engine(ap); | 1345 | ahci_start_engine(ap); |
| 1428 | 1346 | ||
| 1429 | if (rc == 0 && ata_link_online(link)) | 1347 | if (online) |
| 1430 | *class = ahci_dev_classify(ap); | 1348 | *class = ahci_dev_classify(ap); |
| 1431 | if (rc != -EAGAIN && *class == ATA_DEV_UNKNOWN) | ||
| 1432 | *class = ATA_DEV_NONE; | ||
| 1433 | 1349 | ||
| 1434 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); | 1350 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); |
| 1435 | return rc; | 1351 | return rc; |
| @@ -1439,7 +1355,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1439 | unsigned long deadline) | 1355 | unsigned long deadline) |
| 1440 | { | 1356 | { |
| 1441 | struct ata_port *ap = link->ap; | 1357 | struct ata_port *ap = link->ap; |
| 1442 | u32 serror; | 1358 | bool online; |
| 1443 | int rc; | 1359 | int rc; |
| 1444 | 1360 | ||
| 1445 | DPRINTK("ENTER\n"); | 1361 | DPRINTK("ENTER\n"); |
| @@ -1447,11 +1363,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1447 | ahci_stop_engine(ap); | 1363 | ahci_stop_engine(ap); |
| 1448 | 1364 | ||
| 1449 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), | 1365 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), |
| 1450 | deadline); | 1366 | deadline, &online, NULL); |
| 1451 | |||
| 1452 | /* vt8251 needs SError cleared for the port to operate */ | ||
| 1453 | ahci_scr_read(ap, SCR_ERROR, &serror); | ||
| 1454 | ahci_scr_write(ap, SCR_ERROR, serror); | ||
| 1455 | 1367 | ||
| 1456 | ahci_start_engine(ap); | 1368 | ahci_start_engine(ap); |
| 1457 | 1369 | ||
| @@ -1460,7 +1372,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1460 | /* vt8251 doesn't clear BSY on signature FIS reception, | 1372 | /* vt8251 doesn't clear BSY on signature FIS reception, |
| 1461 | * request follow-up softreset. | 1373 | * request follow-up softreset. |
| 1462 | */ | 1374 | */ |
| 1463 | return rc ?: -EAGAIN; | 1375 | return online ? -EAGAIN : rc; |
| 1464 | } | 1376 | } |
| 1465 | 1377 | ||
| 1466 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | 1378 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, |
| @@ -1470,6 +1382,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1470 | struct ahci_port_priv *pp = ap->private_data; | 1382 | struct ahci_port_priv *pp = ap->private_data; |
| 1471 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 1383 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
| 1472 | struct ata_taskfile tf; | 1384 | struct ata_taskfile tf; |
| 1385 | bool online; | ||
| 1473 | int rc; | 1386 | int rc; |
| 1474 | 1387 | ||
| 1475 | ahci_stop_engine(ap); | 1388 | ahci_stop_engine(ap); |
| @@ -1480,16 +1393,10 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1480 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | 1393 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
| 1481 | 1394 | ||
| 1482 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), | 1395 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), |
| 1483 | deadline); | 1396 | deadline, &online, NULL); |
| 1484 | 1397 | ||
| 1485 | ahci_start_engine(ap); | 1398 | ahci_start_engine(ap); |
| 1486 | 1399 | ||
| 1487 | if (rc || ata_link_offline(link)) | ||
| 1488 | return rc; | ||
| 1489 | |||
| 1490 | /* spec mandates ">= 2ms" before checking status */ | ||
| 1491 | msleep(150); | ||
| 1492 | |||
| 1493 | /* The pseudo configuration device on SIMG4726 attached to | 1400 | /* The pseudo configuration device on SIMG4726 attached to |
| 1494 | * ASUS P5W-DH Deluxe doesn't send signature FIS after | 1401 | * ASUS P5W-DH Deluxe doesn't send signature FIS after |
| 1495 | * hardreset if no device is attached to the first downstream | 1402 | * hardreset if no device is attached to the first downstream |
| @@ -1503,11 +1410,13 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
| 1503 | * have to be reset again. For most cases, this should | 1410 | * have to be reset again. For most cases, this should |
| 1504 | * suffice while making probing snappish enough. | 1411 | * suffice while making probing snappish enough. |
| 1505 | */ | 1412 | */ |
| 1506 | rc = ata_wait_ready(ap, jiffies + 2 * HZ); | 1413 | if (online) { |
| 1507 | if (rc) | 1414 | rc = ata_wait_after_reset(link, jiffies + 2 * HZ, |
| 1508 | ahci_kick_engine(ap, 0); | 1415 | ahci_check_ready); |
| 1509 | 1416 | if (rc) | |
| 1510 | return 0; | 1417 | ahci_kick_engine(ap, 0); |
| 1418 | } | ||
| 1419 | return rc; | ||
| 1511 | } | 1420 | } |
| 1512 | 1421 | ||
| 1513 | static void ahci_postreset(struct ata_link *link, unsigned int *class) | 1422 | static void ahci_postreset(struct ata_link *link, unsigned int *class) |
| @@ -1530,27 +1439,6 @@ static void ahci_postreset(struct ata_link *link, unsigned int *class) | |||
| 1530 | } | 1439 | } |
| 1531 | } | 1440 | } |
| 1532 | 1441 | ||
| 1533 | static int ahci_pmp_softreset(struct ata_link *link, unsigned int *class, | ||
| 1534 | unsigned long deadline) | ||
| 1535 | { | ||
| 1536 | return ahci_do_softreset(link, class, link->pmp, deadline); | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | static u8 ahci_check_status(struct ata_port *ap) | ||
| 1540 | { | ||
| 1541 | void __iomem *mmio = ap->ioaddr.cmd_addr; | ||
| 1542 | |||
| 1543 | return readl(mmio + PORT_TFDATA) & 0xFF; | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | ||
| 1547 | { | ||
| 1548 | struct ahci_port_priv *pp = ap->private_data; | ||
| 1549 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | ||
| 1550 | |||
| 1551 | ata_tf_from_fis(d2h_fis, tf); | ||
| 1552 | } | ||
| 1553 | |||
| 1554 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) | 1442 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) |
| 1555 | { | 1443 | { |
| 1556 | struct scatterlist *sg; | 1444 | struct scatterlist *sg; |
| @@ -1663,27 +1551,27 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
| 1663 | u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK); | 1551 | u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK); |
| 1664 | 1552 | ||
| 1665 | active_ehi->err_mask |= AC_ERR_HSM; | 1553 | active_ehi->err_mask |= AC_ERR_HSM; |
| 1666 | active_ehi->action |= ATA_EH_SOFTRESET; | 1554 | active_ehi->action |= ATA_EH_RESET; |
| 1667 | ata_ehi_push_desc(active_ehi, | 1555 | ata_ehi_push_desc(active_ehi, |
| 1668 | "unknown FIS %08x %08x %08x %08x" , | 1556 | "unknown FIS %08x %08x %08x %08x" , |
| 1669 | unk[0], unk[1], unk[2], unk[3]); | 1557 | unk[0], unk[1], unk[2], unk[3]); |
| 1670 | } | 1558 | } |
| 1671 | 1559 | ||
| 1672 | if (ap->nr_pmp_links && (irq_stat & PORT_IRQ_BAD_PMP)) { | 1560 | if (sata_pmp_attached(ap) && (irq_stat & PORT_IRQ_BAD_PMP)) { |
| 1673 | active_ehi->err_mask |= AC_ERR_HSM; | 1561 | active_ehi->err_mask |= AC_ERR_HSM; |
| 1674 | active_ehi->action |= ATA_EH_SOFTRESET; | 1562 | active_ehi->action |= ATA_EH_RESET; |
| 1675 | ata_ehi_push_desc(active_ehi, "incorrect PMP"); | 1563 | ata_ehi_push_desc(active_ehi, "incorrect PMP"); |
| 1676 | } | 1564 | } |
| 1677 | 1565 | ||
| 1678 | if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { | 1566 | if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { |
| 1679 | host_ehi->err_mask |= AC_ERR_HOST_BUS; | 1567 | host_ehi->err_mask |= AC_ERR_HOST_BUS; |
| 1680 | host_ehi->action |= ATA_EH_SOFTRESET; | 1568 | host_ehi->action |= ATA_EH_RESET; |
| 1681 | ata_ehi_push_desc(host_ehi, "host bus error"); | 1569 | ata_ehi_push_desc(host_ehi, "host bus error"); |
| 1682 | } | 1570 | } |
| 1683 | 1571 | ||
| 1684 | if (irq_stat & PORT_IRQ_IF_ERR) { | 1572 | if (irq_stat & PORT_IRQ_IF_ERR) { |
| 1685 | host_ehi->err_mask |= AC_ERR_ATA_BUS; | 1573 | host_ehi->err_mask |= AC_ERR_ATA_BUS; |
| 1686 | host_ehi->action |= ATA_EH_SOFTRESET; | 1574 | host_ehi->action |= ATA_EH_RESET; |
| 1687 | ata_ehi_push_desc(host_ehi, "interface fatal error"); | 1575 | ata_ehi_push_desc(host_ehi, "interface fatal error"); |
| 1688 | } | 1576 | } |
| 1689 | 1577 | ||
| @@ -1704,7 +1592,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
| 1704 | 1592 | ||
| 1705 | static void ahci_port_intr(struct ata_port *ap) | 1593 | static void ahci_port_intr(struct ata_port *ap) |
| 1706 | { | 1594 | { |
| 1707 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; | 1595 | void __iomem *port_mmio = ahci_port_base(ap); |
| 1708 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1596 | struct ata_eh_info *ehi = &ap->link.eh_info; |
| 1709 | struct ahci_port_priv *pp = ap->private_data; | 1597 | struct ahci_port_priv *pp = ap->private_data; |
| 1710 | struct ahci_host_priv *hpriv = ap->host->private_data; | 1598 | struct ahci_host_priv *hpriv = ap->host->private_data; |
| @@ -1766,21 +1654,16 @@ static void ahci_port_intr(struct ata_port *ap) | |||
| 1766 | else | 1654 | else |
| 1767 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); | 1655 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); |
| 1768 | 1656 | ||
| 1769 | rc = ata_qc_complete_multiple(ap, qc_active, NULL); | 1657 | rc = ata_qc_complete_multiple(ap, qc_active); |
| 1770 | 1658 | ||
| 1771 | /* while resetting, invalid completions are expected */ | 1659 | /* while resetting, invalid completions are expected */ |
| 1772 | if (unlikely(rc < 0 && !resetting)) { | 1660 | if (unlikely(rc < 0 && !resetting)) { |
| 1773 | ehi->err_mask |= AC_ERR_HSM; | 1661 | ehi->err_mask |= AC_ERR_HSM; |
| 1774 | ehi->action |= ATA_EH_SOFTRESET; | 1662 | ehi->action |= ATA_EH_RESET; |
| 1775 | ata_port_freeze(ap); | 1663 | ata_port_freeze(ap); |
| 1776 | } | 1664 | } |
| 1777 | } | 1665 | } |
| 1778 | 1666 | ||
| 1779 | static void ahci_irq_clear(struct ata_port *ap) | ||
| 1780 | { | ||
| 1781 | /* TODO */ | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | static irqreturn_t ahci_interrupt(int irq, void *dev_instance) | 1667 | static irqreturn_t ahci_interrupt(int irq, void *dev_instance) |
| 1785 | { | 1668 | { |
| 1786 | struct ata_host *host = dev_instance; | 1669 | struct ata_host *host = dev_instance; |
| @@ -1854,6 +1737,15 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
| 1854 | return 0; | 1737 | return 0; |
| 1855 | } | 1738 | } |
| 1856 | 1739 | ||
| 1740 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) | ||
| 1741 | { | ||
| 1742 | struct ahci_port_priv *pp = qc->ap->private_data; | ||
| 1743 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | ||
| 1744 | |||
| 1745 | ata_tf_from_fis(d2h_fis, &qc->result_tf); | ||
| 1746 | return true; | ||
| 1747 | } | ||
| 1748 | |||
| 1857 | static void ahci_freeze(struct ata_port *ap) | 1749 | static void ahci_freeze(struct ata_port *ap) |
| 1858 | { | 1750 | { |
| 1859 | void __iomem *port_mmio = ahci_port_base(ap); | 1751 | void __iomem *port_mmio = ahci_port_base(ap); |
| @@ -1886,37 +1778,7 @@ static void ahci_error_handler(struct ata_port *ap) | |||
| 1886 | ahci_start_engine(ap); | 1778 | ahci_start_engine(ap); |
| 1887 | } | 1779 | } |
| 1888 | 1780 | ||
| 1889 | /* perform recovery */ | 1781 | sata_pmp_error_handler(ap); |
| 1890 | sata_pmp_do_eh(ap, ata_std_prereset, ahci_softreset, | ||
| 1891 | ahci_hardreset, ahci_postreset, | ||
| 1892 | sata_pmp_std_prereset, ahci_pmp_softreset, | ||
| 1893 | sata_pmp_std_hardreset, sata_pmp_std_postreset); | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | static void ahci_vt8251_error_handler(struct ata_port *ap) | ||
| 1897 | { | ||
| 1898 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { | ||
| 1899 | /* restart engine */ | ||
| 1900 | ahci_stop_engine(ap); | ||
| 1901 | ahci_start_engine(ap); | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | /* perform recovery */ | ||
| 1905 | ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_vt8251_hardreset, | ||
| 1906 | ahci_postreset); | ||
| 1907 | } | ||
| 1908 | |||
| 1909 | static void ahci_p5wdh_error_handler(struct ata_port *ap) | ||
| 1910 | { | ||
| 1911 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { | ||
| 1912 | /* restart engine */ | ||
| 1913 | ahci_stop_engine(ap); | ||
| 1914 | ahci_start_engine(ap); | ||
| 1915 | } | ||
| 1916 | |||
| 1917 | /* perform recovery */ | ||
| 1918 | ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_p5wdh_hardreset, | ||
| 1919 | ahci_postreset); | ||
| 1920 | } | 1782 | } |
| 1921 | 1783 | ||
| 1922 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | 1784 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) |
| @@ -1961,7 +1823,7 @@ static int ahci_port_resume(struct ata_port *ap) | |||
| 1961 | ahci_power_up(ap); | 1823 | ahci_power_up(ap); |
| 1962 | ahci_start_port(ap); | 1824 | ahci_start_port(ap); |
| 1963 | 1825 | ||
| 1964 | if (ap->nr_pmp_links) | 1826 | if (sata_pmp_attached(ap)) |
| 1965 | ahci_pmp_attach(ap); | 1827 | ahci_pmp_attach(ap); |
| 1966 | else | 1828 | else |
| 1967 | ahci_pmp_detach(ap); | 1829 | ahci_pmp_detach(ap); |
| @@ -2324,7 +2186,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 2324 | 2186 | ||
| 2325 | for (i = 0; i < host->n_ports; i++) { | 2187 | for (i = 0; i < host->n_ports; i++) { |
| 2326 | struct ata_port *ap = host->ports[i]; | 2188 | struct ata_port *ap = host->ports[i]; |
| 2327 | void __iomem *port_mmio = ahci_port_base(ap); | ||
| 2328 | 2189 | ||
| 2329 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar"); | 2190 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar"); |
| 2330 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, | 2191 | ata_port_pbar_desc(ap, AHCI_PCI_BAR, |
| @@ -2333,12 +2194,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 2333 | /* set initial link pm policy */ | 2194 | /* set initial link pm policy */ |
| 2334 | ap->pm_policy = NOT_AVAILABLE; | 2195 | ap->pm_policy = NOT_AVAILABLE; |
| 2335 | 2196 | ||
| 2336 | /* standard SATA port setup */ | ||
| 2337 | if (hpriv->port_map & (1 << i)) | ||
| 2338 | ap->ioaddr.cmd_addr = port_mmio; | ||
| 2339 | |||
| 2340 | /* disabled/not-implemented port */ | 2197 | /* disabled/not-implemented port */ |
| 2341 | else | 2198 | if (!(hpriv->port_map & (1 << i))) |
| 2342 | ap->ops = &ata_dummy_port_ops; | 2199 | ap->ops = &ata_dummy_port_ops; |
| 2343 | } | 2200 | } |
| 2344 | 2201 | ||
