diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 255 |
1 files changed, 126 insertions, 129 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index f1516ca2c52a..92e2b950eff4 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -205,8 +205,6 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * | |||
205 | static void ahci_irq_clear(struct ata_port *ap); | 205 | static void ahci_irq_clear(struct ata_port *ap); |
206 | static int ahci_port_start(struct ata_port *ap); | 206 | static int ahci_port_start(struct ata_port *ap); |
207 | static void ahci_port_stop(struct ata_port *ap); | 207 | static void ahci_port_stop(struct ata_port *ap); |
208 | static int ahci_start_engine(void __iomem *port_mmio); | ||
209 | static int ahci_stop_engine(void __iomem *port_mmio); | ||
210 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | 208 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); |
211 | static void ahci_qc_prep(struct ata_queued_cmd *qc); | 209 | static void ahci_qc_prep(struct ata_queued_cmd *qc); |
212 | static u8 ahci_check_status(struct ata_port *ap); | 210 | static u8 ahci_check_status(struct ata_port *ap); |
@@ -374,108 +372,6 @@ static inline void __iomem *ahci_port_base (void __iomem *base, unsigned int por | |||
374 | return (void __iomem *) ahci_port_base_ul((unsigned long)base, port); | 372 | return (void __iomem *) ahci_port_base_ul((unsigned long)base, port); |
375 | } | 373 | } |
376 | 374 | ||
377 | static int ahci_port_start(struct ata_port *ap) | ||
378 | { | ||
379 | struct device *dev = ap->host_set->dev; | ||
380 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
381 | struct ahci_port_priv *pp; | ||
382 | void __iomem *mmio = ap->host_set->mmio_base; | ||
383 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
384 | void *mem; | ||
385 | dma_addr_t mem_dma; | ||
386 | int rc; | ||
387 | |||
388 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | ||
389 | if (!pp) | ||
390 | return -ENOMEM; | ||
391 | memset(pp, 0, sizeof(*pp)); | ||
392 | |||
393 | rc = ata_pad_alloc(ap, dev); | ||
394 | if (rc) { | ||
395 | kfree(pp); | ||
396 | return rc; | ||
397 | } | ||
398 | |||
399 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); | ||
400 | if (!mem) { | ||
401 | ata_pad_free(ap, dev); | ||
402 | kfree(pp); | ||
403 | return -ENOMEM; | ||
404 | } | ||
405 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); | ||
406 | |||
407 | /* | ||
408 | * First item in chunk of DMA memory: 32-slot command table, | ||
409 | * 32 bytes each in size | ||
410 | */ | ||
411 | pp->cmd_slot = mem; | ||
412 | pp->cmd_slot_dma = mem_dma; | ||
413 | |||
414 | mem += AHCI_CMD_SLOT_SZ; | ||
415 | mem_dma += AHCI_CMD_SLOT_SZ; | ||
416 | |||
417 | /* | ||
418 | * Second item: Received-FIS area | ||
419 | */ | ||
420 | pp->rx_fis = mem; | ||
421 | pp->rx_fis_dma = mem_dma; | ||
422 | |||
423 | mem += AHCI_RX_FIS_SZ; | ||
424 | mem_dma += AHCI_RX_FIS_SZ; | ||
425 | |||
426 | /* | ||
427 | * Third item: data area for storing a single command | ||
428 | * and its scatter-gather table | ||
429 | */ | ||
430 | pp->cmd_tbl = mem; | ||
431 | pp->cmd_tbl_dma = mem_dma; | ||
432 | |||
433 | ap->private_data = pp; | ||
434 | |||
435 | if (hpriv->cap & HOST_CAP_64) | ||
436 | writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); | ||
437 | writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); | ||
438 | readl(port_mmio + PORT_LST_ADDR); /* flush */ | ||
439 | |||
440 | if (hpriv->cap & HOST_CAP_64) | ||
441 | writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); | ||
442 | writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); | ||
443 | readl(port_mmio + PORT_FIS_ADDR); /* flush */ | ||
444 | |||
445 | writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | | ||
446 | PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | | ||
447 | PORT_CMD_START, port_mmio + PORT_CMD); | ||
448 | readl(port_mmio + PORT_CMD); /* flush */ | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | |||
454 | static void ahci_port_stop(struct ata_port *ap) | ||
455 | { | ||
456 | struct device *dev = ap->host_set->dev; | ||
457 | struct ahci_port_priv *pp = ap->private_data; | ||
458 | void __iomem *mmio = ap->host_set->mmio_base; | ||
459 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
460 | u32 tmp; | ||
461 | |||
462 | tmp = readl(port_mmio + PORT_CMD); | ||
463 | tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); | ||
464 | writel(tmp, port_mmio + PORT_CMD); | ||
465 | readl(port_mmio + PORT_CMD); /* flush */ | ||
466 | |||
467 | /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so | ||
468 | * this is slightly incorrect. | ||
469 | */ | ||
470 | msleep(500); | ||
471 | |||
472 | ap->private_data = NULL; | ||
473 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, | ||
474 | pp->cmd_slot, pp->cmd_slot_dma); | ||
475 | ata_pad_free(ap, dev); | ||
476 | kfree(pp); | ||
477 | } | ||
478 | |||
479 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) | 375 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) |
480 | { | 376 | { |
481 | unsigned int sc_reg; | 377 | unsigned int sc_reg; |
@@ -510,31 +406,6 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, | |||
510 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); | 406 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); |
511 | } | 407 | } |
512 | 408 | ||
513 | static int ahci_stop_engine(void __iomem *port_mmio) | ||
514 | { | ||
515 | u32 tmp; | ||
516 | |||
517 | tmp = readl(port_mmio + PORT_CMD); | ||
518 | |||
519 | /* Check if the HBA is idle */ | ||
520 | if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) | ||
521 | return 0; | ||
522 | |||
523 | /* Setting HBA to idle */ | ||
524 | tmp &= ~PORT_CMD_START; | ||
525 | writel(tmp, port_mmio + PORT_CMD); | ||
526 | |||
527 | /* wait for engine to stop. This could be | ||
528 | * as long as 500 msec | ||
529 | */ | ||
530 | tmp = ata_wait_register(port_mmio + PORT_CMD, | ||
531 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); | ||
532 | if(tmp & PORT_CMD_LIST_ON) | ||
533 | return -EIO; | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int ahci_start_engine(void __iomem *port_mmio) | 409 | static int ahci_start_engine(void __iomem *port_mmio) |
539 | { | 410 | { |
540 | u32 tmp; | 411 | u32 tmp; |
@@ -570,6 +441,31 @@ static int ahci_start_engine(void __iomem *port_mmio) | |||
570 | return 0; | 441 | return 0; |
571 | } | 442 | } |
572 | 443 | ||
444 | static int ahci_stop_engine(void __iomem *port_mmio) | ||
445 | { | ||
446 | u32 tmp; | ||
447 | |||
448 | tmp = readl(port_mmio + PORT_CMD); | ||
449 | |||
450 | /* Check if the HBA is idle */ | ||
451 | if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) | ||
452 | return 0; | ||
453 | |||
454 | /* Setting HBA to idle */ | ||
455 | tmp &= ~PORT_CMD_START; | ||
456 | writel(tmp, port_mmio + PORT_CMD); | ||
457 | |||
458 | /* wait for engine to stop. This could be | ||
459 | * as long as 500 msec | ||
460 | */ | ||
461 | tmp = ata_wait_register(port_mmio + PORT_CMD, | ||
462 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); | ||
463 | if(tmp & PORT_CMD_LIST_ON) | ||
464 | return -EIO; | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | |||
573 | static unsigned int ahci_dev_classify(struct ata_port *ap) | 469 | static unsigned int ahci_dev_classify(struct ata_port *ap) |
574 | { | 470 | { |
575 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 471 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
@@ -1109,6 +1005,107 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | |||
1109 | } | 1005 | } |
1110 | } | 1006 | } |
1111 | 1007 | ||
1008 | static int ahci_port_start(struct ata_port *ap) | ||
1009 | { | ||
1010 | struct device *dev = ap->host_set->dev; | ||
1011 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
1012 | struct ahci_port_priv *pp; | ||
1013 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1014 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1015 | void *mem; | ||
1016 | dma_addr_t mem_dma; | ||
1017 | int rc; | ||
1018 | |||
1019 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | ||
1020 | if (!pp) | ||
1021 | return -ENOMEM; | ||
1022 | memset(pp, 0, sizeof(*pp)); | ||
1023 | |||
1024 | rc = ata_pad_alloc(ap, dev); | ||
1025 | if (rc) { | ||
1026 | kfree(pp); | ||
1027 | return rc; | ||
1028 | } | ||
1029 | |||
1030 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); | ||
1031 | if (!mem) { | ||
1032 | ata_pad_free(ap, dev); | ||
1033 | kfree(pp); | ||
1034 | return -ENOMEM; | ||
1035 | } | ||
1036 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); | ||
1037 | |||
1038 | /* | ||
1039 | * First item in chunk of DMA memory: 32-slot command table, | ||
1040 | * 32 bytes each in size | ||
1041 | */ | ||
1042 | pp->cmd_slot = mem; | ||
1043 | pp->cmd_slot_dma = mem_dma; | ||
1044 | |||
1045 | mem += AHCI_CMD_SLOT_SZ; | ||
1046 | mem_dma += AHCI_CMD_SLOT_SZ; | ||
1047 | |||
1048 | /* | ||
1049 | * Second item: Received-FIS area | ||
1050 | */ | ||
1051 | pp->rx_fis = mem; | ||
1052 | pp->rx_fis_dma = mem_dma; | ||
1053 | |||
1054 | mem += AHCI_RX_FIS_SZ; | ||
1055 | mem_dma += AHCI_RX_FIS_SZ; | ||
1056 | |||
1057 | /* | ||
1058 | * Third item: data area for storing a single command | ||
1059 | * and its scatter-gather table | ||
1060 | */ | ||
1061 | pp->cmd_tbl = mem; | ||
1062 | pp->cmd_tbl_dma = mem_dma; | ||
1063 | |||
1064 | ap->private_data = pp; | ||
1065 | |||
1066 | if (hpriv->cap & HOST_CAP_64) | ||
1067 | writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); | ||
1068 | writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); | ||
1069 | readl(port_mmio + PORT_LST_ADDR); /* flush */ | ||
1070 | |||
1071 | if (hpriv->cap & HOST_CAP_64) | ||
1072 | writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); | ||
1073 | writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); | ||
1074 | readl(port_mmio + PORT_FIS_ADDR); /* flush */ | ||
1075 | |||
1076 | writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | | ||
1077 | PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | | ||
1078 | PORT_CMD_START, port_mmio + PORT_CMD); | ||
1079 | readl(port_mmio + PORT_CMD); /* flush */ | ||
1080 | |||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | static void ahci_port_stop(struct ata_port *ap) | ||
1085 | { | ||
1086 | struct device *dev = ap->host_set->dev; | ||
1087 | struct ahci_port_priv *pp = ap->private_data; | ||
1088 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1089 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1090 | u32 tmp; | ||
1091 | |||
1092 | tmp = readl(port_mmio + PORT_CMD); | ||
1093 | tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); | ||
1094 | writel(tmp, port_mmio + PORT_CMD); | ||
1095 | readl(port_mmio + PORT_CMD); /* flush */ | ||
1096 | |||
1097 | /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so | ||
1098 | * this is slightly incorrect. | ||
1099 | */ | ||
1100 | msleep(500); | ||
1101 | |||
1102 | ap->private_data = NULL; | ||
1103 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, | ||
1104 | pp->cmd_slot, pp->cmd_slot_dma); | ||
1105 | ata_pad_free(ap, dev); | ||
1106 | kfree(pp); | ||
1107 | } | ||
1108 | |||
1112 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, | 1109 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, |
1113 | unsigned int port_idx) | 1110 | unsigned int port_idx) |
1114 | { | 1111 | { |