mirror of https://gitee.com/openkylin/linux.git
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (119 commits) [libata] struct pci_dev related cleanups libata: use ata_exec_internal() for PMP register access libata: implement ATA_PFLAG_RESETTING libata: add @timeout to ata_exec_internal[_sg]() ahci: fix notification handling ahci: clean up PORT_IRQ_BAD_PMP enabling ahci: kill leftover from enabling NCQ over PMP libata: wrap schedule_timeout_uninterruptible() in loop libata: skip suppress reporting if ATA_EHI_QUIET libata: clear ehi description after initial host report pata_jmicron: match vendor and class code only libata: add ST9160821AS / 3.ALD to NCQ blacklist pata_acpi: ACPI driver support libata-core: Expose gtm methods for driver use libata: add HDT722516DLA380 to NCQ blacklist libata: blacklist NCQ on Seagate Barracuda ST380817AS [libata] Turn on ACPI by default libata_scsi: Fix ATAPI transfer lengths libata: correct handling of SRST reset sequences libata: Integrate ACPI-based PATA/SATA hotplug - version 5 ...
This commit is contained in:
commit
ab9c232286
|
@ -865,6 +865,10 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip
|
||||
Format: addr:<io>,irq:<irq>
|
||||
|
||||
libata.noacpi [LIBATA] Disables use of ACPI in libata suspend/resume
|
||||
when set.
|
||||
Format: <int>
|
||||
|
||||
load_ramdisk= [RAM] List of ramdisks to load from floppy
|
||||
See Documentation/ramdisk.txt.
|
||||
|
||||
|
@ -1085,10 +1089,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
emulation library even if a 387 maths coprocessor
|
||||
is present.
|
||||
|
||||
noacpi [LIBATA] Disables use of ACPI in libata suspend/resume
|
||||
when set.
|
||||
Format: <int>
|
||||
|
||||
noaliencache [MM, NUMA, SLAB] Disables the allocation of alien
|
||||
caches in the slab allocator. Saves per-node memory,
|
||||
but will impact performance.
|
||||
|
|
|
@ -173,6 +173,15 @@ config SATA_INIC162X
|
|||
help
|
||||
This option enables support for Initio 162x Serial ATA.
|
||||
|
||||
config PATA_ACPI
|
||||
tristate "ACPI firmware driver for PATA"
|
||||
depends on ATA_ACPI
|
||||
help
|
||||
This option enables an ACPI method driver which drives
|
||||
motherboard PATA controller interfaces through the ACPI
|
||||
firmware in the BIOS. This driver can sometimes handle
|
||||
otherwise unsupported hardware.
|
||||
|
||||
config PATA_ALI
|
||||
tristate "ALi PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
|
@ -192,16 +201,25 @@ config PATA_AMD
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_ARTOP
|
||||
tristate "ARTOP 6210/6260 PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
tristate "ARTOP 6210/6260 PATA support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for ARTOP PATA controllers.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_AT32
|
||||
tristate "Atmel AVR32 PATA support (Experimental)"
|
||||
depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the IDE devices on the
|
||||
Atmel AT32AP platform.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_ATIIXP
|
||||
tristate "ATI PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
tristate "ATI PATA support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for the ATI ATA interfaces
|
||||
found on the many ATI chipsets.
|
||||
|
@ -219,8 +237,8 @@ config PATA_CMD640_PCI
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_CMD64X
|
||||
tristate "CMD64x PATA support (Very Experimental)"
|
||||
depends on PCI&& EXPERIMENTAL
|
||||
tristate "CMD64x PATA support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for the CMD64x series chips
|
||||
except for the CMD640.
|
||||
|
@ -282,8 +300,8 @@ config ATA_GENERIC
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_HPT366
|
||||
tristate "HPT 366/368 PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
tristate "HPT 366/368 PATA support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for the HPT 366 and 368
|
||||
PATA controllers via the new ATA layer.
|
||||
|
@ -432,6 +450,15 @@ config PATA_NS87410
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_NS87415
|
||||
tristate "Nat Semi NS87415 PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the National Semiconductor
|
||||
NS87415 PCI-IDE controller.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_OPTI
|
||||
tristate "OPTI621/6215 PATA support (Very Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
|
@ -596,4 +623,20 @@ config PATA_SCC
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_BF54X
|
||||
tristate "Blackfin 54x ATAPI support"
|
||||
depends on BF542 || BF548 || BF549
|
||||
help
|
||||
This option enables support for the built-in ATAPI controller on
|
||||
Blackfin 54x family chips.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_BF54X_DMA
|
||||
bool "DMA mode"
|
||||
depends on PATA_BF54X
|
||||
default y
|
||||
help
|
||||
Enable DMA mode for Blackfin ATAPI controller.
|
||||
|
||||
endif # ATA
|
||||
|
|
|
@ -21,6 +21,7 @@ obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
|
|||
obj-$(CONFIG_PATA_ALI) += pata_ali.o
|
||||
obj-$(CONFIG_PATA_AMD) += pata_amd.o
|
||||
obj-$(CONFIG_PATA_ARTOP) += pata_artop.o
|
||||
obj-$(CONFIG_PATA_AT32) += pata_at32.o
|
||||
obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o
|
||||
obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o
|
||||
obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o
|
||||
|
@ -39,6 +40,7 @@ obj-$(CONFIG_PATA_IT8213) += pata_it8213.o
|
|||
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o
|
||||
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
|
||||
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
|
||||
obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o
|
||||
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
|
||||
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
|
||||
obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
|
||||
|
@ -61,12 +63,16 @@ obj-$(CONFIG_PATA_SIS) += pata_sis.o
|
|||
obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
|
||||
obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
|
||||
obj-$(CONFIG_PATA_SCC) += pata_scc.o
|
||||
obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o
|
||||
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
|
||||
obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
|
||||
# Should be last but two libata driver
|
||||
obj-$(CONFIG_PATA_ACPI) += pata_acpi.o
|
||||
# Should be last but one libata driver
|
||||
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
|
||||
# Should be last libata driver
|
||||
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
|
||||
|
||||
libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o
|
||||
libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o \
|
||||
libata-pmp.o
|
||||
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "ahci"
|
||||
#define DRV_VERSION "2.3"
|
||||
#define DRV_VERSION "3.0"
|
||||
|
||||
|
||||
enum {
|
||||
|
@ -77,11 +77,10 @@ enum {
|
|||
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
|
||||
|
||||
board_ahci = 0,
|
||||
board_ahci_pi = 1,
|
||||
board_ahci_vt8251 = 2,
|
||||
board_ahci_ign_iferr = 3,
|
||||
board_ahci_sb600 = 4,
|
||||
board_ahci_mv = 5,
|
||||
board_ahci_vt8251 = 1,
|
||||
board_ahci_ign_iferr = 2,
|
||||
board_ahci_sb600 = 3,
|
||||
board_ahci_mv = 4,
|
||||
|
||||
/* global controller registers */
|
||||
HOST_CAP = 0x00, /* host capabilities */
|
||||
|
@ -97,6 +96,7 @@ enum {
|
|||
|
||||
/* HOST_CAP bits */
|
||||
HOST_CAP_SSC = (1 << 14), /* Slumber capable */
|
||||
HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */
|
||||
HOST_CAP_CLO = (1 << 24), /* Command List Override support */
|
||||
HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
|
||||
HOST_CAP_SNTF = (1 << 29), /* SNotification register */
|
||||
|
@ -144,7 +144,8 @@ enum {
|
|||
PORT_IRQ_IF_ERR |
|
||||
PORT_IRQ_CONNECT |
|
||||
PORT_IRQ_PHYRDY |
|
||||
PORT_IRQ_UNK_FIS,
|
||||
PORT_IRQ_UNK_FIS |
|
||||
PORT_IRQ_BAD_PMP,
|
||||
PORT_IRQ_ERROR = PORT_IRQ_FREEZE |
|
||||
PORT_IRQ_TF_ERR |
|
||||
PORT_IRQ_HBUS_DATA_ERR,
|
||||
|
@ -154,6 +155,7 @@ enum {
|
|||
|
||||
/* PORT_CMD bits */
|
||||
PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */
|
||||
PORT_CMD_PMP = (1 << 17), /* PMP attached */
|
||||
PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */
|
||||
PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */
|
||||
PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */
|
||||
|
@ -167,19 +169,22 @@ enum {
|
|||
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
|
||||
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
|
||||
|
||||
/* hpriv->flags bits */
|
||||
AHCI_HFLAG_NO_NCQ = (1 << 0),
|
||||
AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */
|
||||
AHCI_HFLAG_IGN_SERR_INTERNAL = (1 << 2), /* ignore SERR_INTERNAL */
|
||||
AHCI_HFLAG_32BIT_ONLY = (1 << 3), /* force 32bit */
|
||||
AHCI_HFLAG_MV_PATA = (1 << 4), /* PATA port */
|
||||
AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */
|
||||
AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */
|
||||
|
||||
/* ap->flags bits */
|
||||
AHCI_FLAG_NO_NCQ = (1 << 24),
|
||||
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
|
||||
AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
|
||||
AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
|
||||
AHCI_FLAG_32BIT_ONLY = (1 << 28), /* force 32bit */
|
||||
AHCI_FLAG_MV_PATA = (1 << 29), /* PATA port */
|
||||
AHCI_FLAG_NO_MSI = (1 << 30), /* no PCI MSI */
|
||||
AHCI_FLAG_NO_HOTPLUG = (1 << 24), /* ignore PxSERR.DIAG.N */
|
||||
|
||||
AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY |
|
||||
ATA_FLAG_ACPI_SATA,
|
||||
ATA_FLAG_ACPI_SATA | ATA_FLAG_AN,
|
||||
AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY,
|
||||
};
|
||||
|
||||
struct ahci_cmd_hdr {
|
||||
|
@ -198,6 +203,7 @@ struct ahci_sg {
|
|||
};
|
||||
|
||||
struct ahci_host_priv {
|
||||
unsigned int flags; /* AHCI_HFLAG_* */
|
||||
u32 cap; /* cap to use */
|
||||
u32 port_map; /* port map to use */
|
||||
u32 saved_cap; /* saved initial cap */
|
||||
|
@ -205,6 +211,7 @@ struct ahci_host_priv {
|
|||
};
|
||||
|
||||
struct ahci_port_priv {
|
||||
struct ata_link *active_link;
|
||||
struct ahci_cmd_hdr *cmd_slot;
|
||||
dma_addr_t cmd_slot_dma;
|
||||
void *cmd_tbl;
|
||||
|
@ -215,6 +222,7 @@ struct ahci_port_priv {
|
|||
unsigned int ncq_saw_d2h:1;
|
||||
unsigned int ncq_saw_dmas:1;
|
||||
unsigned int ncq_saw_sdb:1;
|
||||
u32 intr_mask; /* interrupts to enable */
|
||||
};
|
||||
|
||||
static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
|
||||
|
@ -229,6 +237,8 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc);
|
|||
static u8 ahci_check_status(struct ata_port *ap);
|
||||
static void ahci_freeze(struct ata_port *ap);
|
||||
static void ahci_thaw(struct ata_port *ap);
|
||||
static void ahci_pmp_attach(struct ata_port *ap);
|
||||
static void ahci_pmp_detach(struct ata_port *ap);
|
||||
static void ahci_error_handler(struct ata_port *ap);
|
||||
static void ahci_vt8251_error_handler(struct ata_port *ap);
|
||||
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
|
||||
|
@ -262,20 +272,17 @@ static struct scsi_host_template ahci_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations ahci_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.check_status = ahci_check_status,
|
||||
.check_altstatus = ahci_check_status,
|
||||
.dev_select = ata_noop_dev_select,
|
||||
|
||||
.tf_read = ahci_tf_read,
|
||||
|
||||
.qc_defer = sata_pmp_qc_defer_cmd_switch,
|
||||
.qc_prep = ahci_qc_prep,
|
||||
.qc_issue = ahci_qc_issue,
|
||||
|
||||
.irq_clear = ahci_irq_clear,
|
||||
.irq_on = ata_dummy_irq_on,
|
||||
.irq_ack = ata_dummy_irq_ack,
|
||||
|
||||
.scr_read = ahci_scr_read,
|
||||
.scr_write = ahci_scr_write,
|
||||
|
@ -286,6 +293,9 @@ static const struct ata_port_operations ahci_ops = {
|
|||
.error_handler = ahci_error_handler,
|
||||
.post_internal_cmd = ahci_post_internal_cmd,
|
||||
|
||||
.pmp_attach = ahci_pmp_attach,
|
||||
.pmp_detach = ahci_pmp_detach,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
.port_suspend = ahci_port_suspend,
|
||||
.port_resume = ahci_port_resume,
|
||||
|
@ -296,20 +306,17 @@ static const struct ata_port_operations ahci_ops = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations ahci_vt8251_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.check_status = ahci_check_status,
|
||||
.check_altstatus = ahci_check_status,
|
||||
.dev_select = ata_noop_dev_select,
|
||||
|
||||
.tf_read = ahci_tf_read,
|
||||
|
||||
.qc_defer = sata_pmp_qc_defer_cmd_switch,
|
||||
.qc_prep = ahci_qc_prep,
|
||||
.qc_issue = ahci_qc_issue,
|
||||
|
||||
.irq_clear = ahci_irq_clear,
|
||||
.irq_on = ata_dummy_irq_on,
|
||||
.irq_ack = ata_dummy_irq_ack,
|
||||
|
||||
.scr_read = ahci_scr_read,
|
||||
.scr_write = ahci_scr_write,
|
||||
|
@ -320,6 +327,9 @@ static const struct ata_port_operations ahci_vt8251_ops = {
|
|||
.error_handler = ahci_vt8251_error_handler,
|
||||
.post_internal_cmd = ahci_post_internal_cmd,
|
||||
|
||||
.pmp_attach = ahci_pmp_attach,
|
||||
.pmp_detach = ahci_pmp_detach,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
.port_suspend = ahci_port_suspend,
|
||||
.port_resume = ahci_port_resume,
|
||||
|
@ -329,53 +339,52 @@ static const struct ata_port_operations ahci_vt8251_ops = {
|
|||
.port_stop = ahci_port_stop,
|
||||
};
|
||||
|
||||
#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
|
||||
|
||||
static const struct ata_port_info ahci_port_info[] = {
|
||||
/* board_ahci */
|
||||
{
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_pi */
|
||||
{
|
||||
.flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
|
||||
.link_flags = AHCI_LFLAG_COMMON,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_vt8251 */
|
||||
{
|
||||
.flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
|
||||
AHCI_FLAG_NO_NCQ,
|
||||
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
.link_flags = AHCI_LFLAG_COMMON | ATA_LFLAG_HRST_TO_RESUME,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_vt8251_ops,
|
||||
},
|
||||
/* board_ahci_ign_iferr */
|
||||
{
|
||||
.flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
|
||||
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
.link_flags = AHCI_LFLAG_COMMON,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_sb600 */
|
||||
{
|
||||
.flags = AHCI_FLAG_COMMON |
|
||||
AHCI_FLAG_IGN_SERR_INTERNAL |
|
||||
AHCI_FLAG_32BIT_ONLY,
|
||||
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
|
||||
AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_PMP),
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
.link_flags = AHCI_LFLAG_COMMON,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_mv */
|
||||
{
|
||||
.sht = &ahci_sht,
|
||||
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
|
||||
AHCI_HFLAG_MV_PATA),
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI |
|
||||
AHCI_FLAG_NO_NCQ | AHCI_FLAG_NO_MSI |
|
||||
AHCI_FLAG_MV_PATA,
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
|
||||
.link_flags = AHCI_LFLAG_COMMON,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
|
@ -394,23 +403,25 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
|
||||
{ PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
|
||||
{ PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292c), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292c), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
|
||||
{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
|
||||
|
||||
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
|
@ -474,6 +485,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci }, /* MCP77 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci }, /* MCP77 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci }, /* MCP77 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0ab8), board_ahci }, /* MCP79 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0ab9), board_ahci }, /* MCP79 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0aba), board_ahci }, /* MCP79 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0abb), board_ahci }, /* MCP79 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0abc), board_ahci }, /* MCP79 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci }, /* MCP79 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci }, /* MCP79 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci }, /* MCP79 */
|
||||
|
||||
/* SiS */
|
||||
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
|
||||
|
@ -524,7 +543,6 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap)
|
|||
/**
|
||||
* ahci_save_initial_config - Save and fixup initial config values
|
||||
* @pdev: target PCI device
|
||||
* @pi: associated ATA port info
|
||||
* @hpriv: host private area to store config values
|
||||
*
|
||||
* Some registers containing configuration info might be setup by
|
||||
|
@ -538,7 +556,6 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap)
|
|||
* None.
|
||||
*/
|
||||
static void ahci_save_initial_config(struct pci_dev *pdev,
|
||||
const struct ata_port_info *pi,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
|
||||
|
@ -552,26 +569,22 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
|
|||
hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
|
||||
|
||||
/* some chips have errata preventing 64bit use */
|
||||
if ((cap & HOST_CAP_64) && (pi->flags & AHCI_FLAG_32BIT_ONLY)) {
|
||||
if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"controller can't do 64bit DMA, forcing 32bit\n");
|
||||
cap &= ~HOST_CAP_64;
|
||||
}
|
||||
|
||||
if ((cap & HOST_CAP_NCQ) && (pi->flags & AHCI_FLAG_NO_NCQ)) {
|
||||
if ((cap & HOST_CAP_NCQ) && (hpriv->flags & AHCI_HFLAG_NO_NCQ)) {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"controller can't do NCQ, turning off CAP_NCQ\n");
|
||||
cap &= ~HOST_CAP_NCQ;
|
||||
}
|
||||
|
||||
/* fixup zero port_map */
|
||||
if (!port_map) {
|
||||
port_map = (1 << ahci_nr_ports(cap)) - 1;
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"PORTS_IMPL is zero, forcing 0x%x\n", port_map);
|
||||
|
||||
/* write the fixed up value to the PI register */
|
||||
hpriv->saved_port_map = port_map;
|
||||
if ((cap && HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"controller can't do PMP, turning off CAP_PMP\n");
|
||||
cap &= ~HOST_CAP_PMP;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -579,7 +592,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
|
|||
* is asserted through the standard AHCI port
|
||||
* presence register, as bit 4 (counting from 0)
|
||||
*/
|
||||
if (pi->flags & AHCI_FLAG_MV_PATA) {
|
||||
if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"MV_AHCI HACK: port_map %x -> %x\n",
|
||||
hpriv->port_map,
|
||||
|
@ -589,7 +602,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
/* cross check port_map and cap.n_ports */
|
||||
if (pi->flags & AHCI_FLAG_HONOR_PI) {
|
||||
if (port_map) {
|
||||
u32 tmp_port_map = port_map;
|
||||
int n_ports = ahci_nr_ports(cap);
|
||||
|
||||
|
@ -600,17 +613,26 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
|
|||
}
|
||||
}
|
||||
|
||||
/* Whine if inconsistent. No need to update cap.
|
||||
* port_map is used to determine number of ports.
|
||||
/* If n_ports and port_map are inconsistent, whine and
|
||||
* clear port_map and let it be generated from n_ports.
|
||||
*/
|
||||
if (n_ports || tmp_port_map)
|
||||
if (n_ports || tmp_port_map) {
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"nr_ports (%u) and implemented port map "
|
||||
"(0x%x) don't match\n",
|
||||
"(0x%x) don't match, using nr_ports\n",
|
||||
ahci_nr_ports(cap), port_map);
|
||||
} else {
|
||||
/* fabricate port_map from cap.nr_ports */
|
||||
port_map = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* fabricate port_map from cap.nr_ports */
|
||||
if (!port_map) {
|
||||
port_map = (1 << ahci_nr_ports(cap)) - 1;
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"forcing PORTS_IMPL to 0x%x\n", port_map);
|
||||
|
||||
/* write the fixed up value to the PI register */
|
||||
hpriv->saved_port_map = port_map;
|
||||
}
|
||||
|
||||
/* record values to use during operation */
|
||||
|
@ -836,8 +858,14 @@ static int ahci_reset_controller(struct ata_host *host)
|
|||
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
|
||||
u32 tmp;
|
||||
|
||||
/* global controller reset */
|
||||
/* we must be in AHCI mode, before using anything
|
||||
* AHCI-specific, such as HOST_RESET.
|
||||
*/
|
||||
tmp = readl(mmio + HOST_CTL);
|
||||
if (!(tmp & HOST_AHCI_EN))
|
||||
writel(tmp | HOST_AHCI_EN, mmio + HOST_CTL);
|
||||
|
||||
/* global controller reset */
|
||||
if ((tmp & HOST_RESET) == 0) {
|
||||
writel(tmp | HOST_RESET, mmio + HOST_CTL);
|
||||
readl(mmio + HOST_CTL); /* flush */
|
||||
|
@ -904,13 +932,14 @@ static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap,
|
|||
|
||||
static void ahci_init_controller(struct ata_host *host)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = host->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
|
||||
int i;
|
||||
void __iomem *port_mmio;
|
||||
u32 tmp;
|
||||
|
||||
if (host->ports[0]->flags & AHCI_FLAG_MV_PATA) {
|
||||
if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
|
||||
port_mmio = __ahci_port_base(host, 4);
|
||||
|
||||
writel(0, port_mmio + PORT_IRQ_MASK);
|
||||
|
@ -1042,9 +1071,10 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
|
||||
static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
|
||||
int pmp, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
const char *reason = NULL;
|
||||
unsigned long now, msecs;
|
||||
struct ata_taskfile tf;
|
||||
|
@ -1052,7 +1082,7 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
|
|||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
if (ata_port_offline(ap)) {
|
||||
if (ata_link_offline(link)) {
|
||||
DPRINTK("PHY reports no device\n");
|
||||
*class = ATA_DEV_NONE;
|
||||
return 0;
|
||||
|
@ -1061,10 +1091,10 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
|
|||
/* prepare for SRST (AHCI-1.1 10.4.1) */
|
||||
rc = ahci_kick_engine(ap, 1);
|
||||
if (rc)
|
||||
ata_port_printk(ap, KERN_WARNING,
|
||||
ata_link_printk(link, KERN_WARNING,
|
||||
"failed to reset engine (errno=%d)", rc);
|
||||
|
||||
ata_tf_init(ap->device, &tf);
|
||||
ata_tf_init(link->device, &tf);
|
||||
|
||||
/* issue the first D2H Register FIS */
|
||||
msecs = 0;
|
||||
|
@ -1109,19 +1139,25 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class,
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
|
||||
ata_link_printk(link, KERN_ERR, "softreset failed (%s)\n", reason);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ahci_softreset(struct ata_port *ap, unsigned int *class,
|
||||
static int ahci_softreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
return ahci_do_softreset(ap, class, 0, deadline);
|
||||
int pmp = 0;
|
||||
|
||||
if (link->ap->flags & ATA_FLAG_PMP)
|
||||
pmp = SATA_PMP_CTRL_PORT;
|
||||
|
||||
return ahci_do_softreset(link, class, pmp, deadline);
|
||||
}
|
||||
|
||||
static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
static int ahci_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
|
||||
struct ata_taskfile tf;
|
||||
|
@ -1132,26 +1168,27 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
ahci_stop_engine(ap);
|
||||
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(ap->device, &tf);
|
||||
ata_tf_init(link->device, &tf);
|
||||
tf.command = 0x80;
|
||||
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
|
||||
|
||||
rc = sata_std_hardreset(ap, class, deadline);
|
||||
rc = sata_std_hardreset(link, class, deadline);
|
||||
|
||||
ahci_start_engine(ap);
|
||||
|
||||
if (rc == 0 && ata_port_online(ap))
|
||||
if (rc == 0 && ata_link_online(link))
|
||||
*class = ahci_dev_classify(ap);
|
||||
if (*class == ATA_DEV_UNKNOWN)
|
||||
if (rc != -EAGAIN && *class == ATA_DEV_UNKNOWN)
|
||||
*class = ATA_DEV_NONE;
|
||||
|
||||
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
u32 serror;
|
||||
int rc;
|
||||
|
||||
|
@ -1159,7 +1196,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
|
||||
ahci_stop_engine(ap);
|
||||
|
||||
rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context),
|
||||
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
|
||||
deadline);
|
||||
|
||||
/* vt8251 needs SError cleared for the port to operate */
|
||||
|
@ -1176,12 +1213,13 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
return rc ?: -EAGAIN;
|
||||
}
|
||||
|
||||
static void ahci_postreset(struct ata_port *ap, unsigned int *class)
|
||||
static void ahci_postreset(struct ata_link *link, unsigned int *class)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 new_tmp, tmp;
|
||||
|
||||
ata_std_postreset(ap, class);
|
||||
ata_std_postreset(link, class);
|
||||
|
||||
/* Make sure port's ATAPI bit is set appropriately */
|
||||
new_tmp = tmp = readl(port_mmio + PORT_CMD);
|
||||
|
@ -1195,6 +1233,12 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class)
|
|||
}
|
||||
}
|
||||
|
||||
static int ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
return ahci_do_softreset(link, class, link->pmp, deadline);
|
||||
}
|
||||
|
||||
static u8 ahci_check_status(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->ioaddr.cmd_addr;
|
||||
|
@ -1253,7 +1297,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
|
|||
*/
|
||||
cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ;
|
||||
|
||||
ata_tf_to_fis(&qc->tf, 0, 1, cmd_tbl);
|
||||
ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, cmd_tbl);
|
||||
if (is_atapi) {
|
||||
memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
|
||||
memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len);
|
||||
|
@ -1266,7 +1310,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
|
|||
/*
|
||||
* Fill in command slot information.
|
||||
*/
|
||||
opts = cmd_fis_len | n_elem << 16;
|
||||
opts = cmd_fis_len | n_elem << 16 | (qc->dev->link->pmp << 12);
|
||||
if (qc->tf.flags & ATA_TFLAG_WRITE)
|
||||
opts |= AHCI_CMD_WRITE;
|
||||
if (is_atapi)
|
||||
|
@ -1277,66 +1321,87 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
|
|||
|
||||
static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
unsigned int err_mask = 0, action = 0;
|
||||
struct ata_queued_cmd *qc;
|
||||
struct ata_eh_info *host_ehi = &ap->link.eh_info;
|
||||
struct ata_link *link = NULL;
|
||||
struct ata_queued_cmd *active_qc;
|
||||
struct ata_eh_info *active_ehi;
|
||||
u32 serror;
|
||||
|
||||
ata_ehi_clear_desc(ehi);
|
||||
/* determine active link */
|
||||
ata_port_for_each_link(link, ap)
|
||||
if (ata_link_active(link))
|
||||
break;
|
||||
if (!link)
|
||||
link = &ap->link;
|
||||
|
||||
active_qc = ata_qc_from_tag(ap, link->active_tag);
|
||||
active_ehi = &link->eh_info;
|
||||
|
||||
/* record irq stat */
|
||||
ata_ehi_clear_desc(host_ehi);
|
||||
ata_ehi_push_desc(host_ehi, "irq_stat 0x%08x", irq_stat);
|
||||
|
||||
/* AHCI needs SError cleared; otherwise, it might lock up */
|
||||
ahci_scr_read(ap, SCR_ERROR, &serror);
|
||||
ahci_scr_write(ap, SCR_ERROR, serror);
|
||||
|
||||
/* analyze @irq_stat */
|
||||
ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat);
|
||||
host_ehi->serror |= serror;
|
||||
|
||||
/* some controllers set IRQ_IF_ERR on device errors, ignore it */
|
||||
if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
|
||||
if (hpriv->flags & AHCI_HFLAG_IGN_IRQ_IF_ERR)
|
||||
irq_stat &= ~PORT_IRQ_IF_ERR;
|
||||
|
||||
if (irq_stat & PORT_IRQ_TF_ERR) {
|
||||
err_mask |= AC_ERR_DEV;
|
||||
if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
|
||||
serror &= ~SERR_INTERNAL;
|
||||
}
|
||||
/* If qc is active, charge it; otherwise, the active
|
||||
* link. There's no active qc on NCQ errors. It will
|
||||
* be determined by EH by reading log page 10h.
|
||||
*/
|
||||
if (active_qc)
|
||||
active_qc->err_mask |= AC_ERR_DEV;
|
||||
else
|
||||
active_ehi->err_mask |= AC_ERR_DEV;
|
||||
|
||||
if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
|
||||
err_mask |= AC_ERR_HOST_BUS;
|
||||
action |= ATA_EH_SOFTRESET;
|
||||
}
|
||||
|
||||
if (irq_stat & PORT_IRQ_IF_ERR) {
|
||||
err_mask |= AC_ERR_ATA_BUS;
|
||||
action |= ATA_EH_SOFTRESET;
|
||||
ata_ehi_push_desc(ehi, "interface fatal error");
|
||||
}
|
||||
|
||||
if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) {
|
||||
ata_ehi_hotplugged(ehi);
|
||||
ata_ehi_push_desc(ehi, "%s", irq_stat & PORT_IRQ_CONNECT ?
|
||||
"connection status changed" : "PHY RDY changed");
|
||||
if (hpriv->flags & AHCI_HFLAG_IGN_SERR_INTERNAL)
|
||||
host_ehi->serror &= ~SERR_INTERNAL;
|
||||
}
|
||||
|
||||
if (irq_stat & PORT_IRQ_UNK_FIS) {
|
||||
u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK);
|
||||
|
||||
err_mask |= AC_ERR_HSM;
|
||||
action |= ATA_EH_SOFTRESET;
|
||||
ata_ehi_push_desc(ehi, "unknown FIS %08x %08x %08x %08x",
|
||||
active_ehi->err_mask |= AC_ERR_HSM;
|
||||
active_ehi->action |= ATA_EH_SOFTRESET;
|
||||
ata_ehi_push_desc(active_ehi,
|
||||
"unknown FIS %08x %08x %08x %08x" ,
|
||||
unk[0], unk[1], unk[2], unk[3]);
|
||||
}
|
||||
|
||||
/* okay, let's hand over to EH */
|
||||
ehi->serror |= serror;
|
||||
ehi->action |= action;
|
||||
if (ap->nr_pmp_links && (irq_stat & PORT_IRQ_BAD_PMP)) {
|
||||
active_ehi->err_mask |= AC_ERR_HSM;
|
||||
active_ehi->action |= ATA_EH_SOFTRESET;
|
||||
ata_ehi_push_desc(active_ehi, "incorrect PMP");
|
||||
}
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
if (qc)
|
||||
qc->err_mask |= err_mask;
|
||||
else
|
||||
ehi->err_mask |= err_mask;
|
||||
if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
|
||||
host_ehi->err_mask |= AC_ERR_HOST_BUS;
|
||||
host_ehi->action |= ATA_EH_SOFTRESET;
|
||||
ata_ehi_push_desc(host_ehi, "host bus error");
|
||||
}
|
||||
|
||||
if (irq_stat & PORT_IRQ_IF_ERR) {
|
||||
host_ehi->err_mask |= AC_ERR_ATA_BUS;
|
||||
host_ehi->action |= ATA_EH_SOFTRESET;
|
||||
ata_ehi_push_desc(host_ehi, "interface fatal error");
|
||||
}
|
||||
|
||||
if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) {
|
||||
ata_ehi_hotplugged(host_ehi);
|
||||
ata_ehi_push_desc(host_ehi, "%s",
|
||||
irq_stat & PORT_IRQ_CONNECT ?
|
||||
"connection status changed" : "PHY RDY changed");
|
||||
}
|
||||
|
||||
/* okay, let's hand over to EH */
|
||||
|
||||
if (irq_stat & PORT_IRQ_FREEZE)
|
||||
ata_port_freeze(ap);
|
||||
|
@ -1347,25 +1412,64 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
|
|||
static void ahci_port_intr(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
|
||||
u32 status, qc_active;
|
||||
int rc, known_irq = 0;
|
||||
|
||||
status = readl(port_mmio + PORT_IRQ_STAT);
|
||||
writel(status, port_mmio + PORT_IRQ_STAT);
|
||||
|
||||
/* ignore BAD_PMP while resetting */
|
||||
if (unlikely(resetting))
|
||||
status &= ~PORT_IRQ_BAD_PMP;
|
||||
|
||||
if (unlikely(status & PORT_IRQ_ERROR)) {
|
||||
ahci_error_intr(ap, status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ap->sactive)
|
||||
if (status & PORT_IRQ_SDB_FIS) {
|
||||
/* If SNotification is available, leave notification
|
||||
* handling to sata_async_notification(). If not,
|
||||
* emulate it by snooping SDB FIS RX area.
|
||||
*
|
||||
* Snooping FIS RX area is probably cheaper than
|
||||
* poking SNotification but some constrollers which
|
||||
* implement SNotification, ICH9 for example, don't
|
||||
* store AN SDB FIS into receive area.
|
||||
*/
|
||||
if (hpriv->cap & HOST_CAP_SNTF)
|
||||
sata_async_notification(ap);
|
||||
else {
|
||||
/* If the 'N' bit in word 0 of the FIS is set,
|
||||
* we just received asynchronous notification.
|
||||
* Tell libata about it.
|
||||
*/
|
||||
const __le32 *f = pp->rx_fis + RX_FIS_SDB;
|
||||
u32 f0 = le32_to_cpu(f[0]);
|
||||
|
||||
if (f0 & (1 << 15))
|
||||
sata_async_notification(ap);
|
||||
}
|
||||
}
|
||||
|
||||
/* pp->active_link is valid iff any command is in flight */
|
||||
if (ap->qc_active && pp->active_link->sactive)
|
||||
qc_active = readl(port_mmio + PORT_SCR_ACT);
|
||||
else
|
||||
qc_active = readl(port_mmio + PORT_CMD_ISSUE);
|
||||
|
||||
rc = ata_qc_complete_multiple(ap, qc_active, NULL);
|
||||
|
||||
/* If resetting, spurious or invalid completions are expected,
|
||||
* return unconditionally.
|
||||
*/
|
||||
if (resetting)
|
||||
return;
|
||||
|
||||
if (rc > 0)
|
||||
return;
|
||||
if (rc < 0) {
|
||||
|
@ -1380,7 +1484,7 @@ static void ahci_port_intr(struct ata_port *ap)
|
|||
/* if !NCQ, ignore. No modern ATA device has broken HSM
|
||||
* implementation for non-NCQ commands.
|
||||
*/
|
||||
if (!ap->sactive)
|
||||
if (!ap->link.sactive)
|
||||
return;
|
||||
|
||||
if (status & PORT_IRQ_D2H_REG_FIS) {
|
||||
|
@ -1433,7 +1537,7 @@ static void ahci_port_intr(struct ata_port *ap)
|
|||
if (!known_irq)
|
||||
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
|
||||
"(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
|
||||
status, ap->active_tag, ap->sactive);
|
||||
status, ap->link.active_tag, ap->link.sactive);
|
||||
}
|
||||
|
||||
static void ahci_irq_clear(struct ata_port *ap)
|
||||
|
@ -1498,6 +1602,13 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
|
|||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
|
||||
/* Keep track of the currently active link. It will be used
|
||||
* in completion path to determine whether NCQ phase is in
|
||||
* progress.
|
||||
*/
|
||||
pp->active_link = qc->dev->link;
|
||||
|
||||
if (qc->tf.protocol == ATA_PROT_NCQ)
|
||||
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
|
||||
|
@ -1520,6 +1631,7 @@ static void ahci_thaw(struct ata_port *ap)
|
|||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 tmp;
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
|
||||
/* clear IRQ */
|
||||
tmp = readl(port_mmio + PORT_IRQ_STAT);
|
||||
|
@ -1527,7 +1639,7 @@ static void ahci_thaw(struct ata_port *ap)
|
|||
writel(1 << ap->port_no, mmio + HOST_IRQ_STAT);
|
||||
|
||||
/* turn IRQ back on */
|
||||
writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
|
||||
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
|
||||
}
|
||||
|
||||
static void ahci_error_handler(struct ata_port *ap)
|
||||
|
@ -1539,8 +1651,10 @@ static void ahci_error_handler(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/* perform recovery */
|
||||
ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_hardreset,
|
||||
ahci_postreset);
|
||||
sata_pmp_do_eh(ap, ata_std_prereset, ahci_softreset,
|
||||
ahci_hardreset, ahci_postreset,
|
||||
sata_pmp_std_prereset, ahci_pmp_softreset,
|
||||
sata_pmp_std_hardreset, sata_pmp_std_postreset);
|
||||
}
|
||||
|
||||
static void ahci_vt8251_error_handler(struct ata_port *ap)
|
||||
|
@ -1565,11 +1679,44 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
|
|||
ahci_kick_engine(ap, 1);
|
||||
}
|
||||
|
||||
static void ahci_pmp_attach(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
u32 cmd;
|
||||
|
||||
cmd = readl(port_mmio + PORT_CMD);
|
||||
cmd |= PORT_CMD_PMP;
|
||||
writel(cmd, port_mmio + PORT_CMD);
|
||||
|
||||
pp->intr_mask |= PORT_IRQ_BAD_PMP;
|
||||
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
|
||||
}
|
||||
|
||||
static void ahci_pmp_detach(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
u32 cmd;
|
||||
|
||||
cmd = readl(port_mmio + PORT_CMD);
|
||||
cmd &= ~PORT_CMD_PMP;
|
||||
writel(cmd, port_mmio + PORT_CMD);
|
||||
|
||||
pp->intr_mask &= ~PORT_IRQ_BAD_PMP;
|
||||
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
|
||||
}
|
||||
|
||||
static int ahci_port_resume(struct ata_port *ap)
|
||||
{
|
||||
ahci_power_up(ap);
|
||||
ahci_start_port(ap);
|
||||
|
||||
if (ap->nr_pmp_links)
|
||||
ahci_pmp_attach(ap);
|
||||
else
|
||||
ahci_pmp_detach(ap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1681,6 +1828,12 @@ static int ahci_port_start(struct ata_port *ap)
|
|||
pp->cmd_tbl = mem;
|
||||
pp->cmd_tbl_dma = mem_dma;
|
||||
|
||||
/*
|
||||
* Save off initial list of interrupts to be enabled.
|
||||
* This could be changed later
|
||||
*/
|
||||
pp->intr_mask = DEF_PORT_IRQ;
|
||||
|
||||
ap->private_data = pp;
|
||||
|
||||
/* engage engines, captain */
|
||||
|
@ -1830,20 +1983,24 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
if ((pi.flags & AHCI_FLAG_NO_MSI) || pci_enable_msi(pdev))
|
||||
pci_intx(pdev, 1);
|
||||
|
||||
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
hpriv->flags |= (unsigned long)pi.private_data;
|
||||
|
||||
if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
|
||||
pci_intx(pdev, 1);
|
||||
|
||||
/* save initial config */
|
||||
ahci_save_initial_config(pdev, &pi, hpriv);
|
||||
ahci_save_initial_config(pdev, hpriv);
|
||||
|
||||
/* prepare host */
|
||||
if (hpriv->cap & HOST_CAP_NCQ)
|
||||
pi.flags |= ATA_FLAG_NCQ;
|
||||
|
||||
if (hpriv->cap & HOST_CAP_PMP)
|
||||
pi.flags |= ATA_FLAG_PMP;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map));
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
@ -1854,6 +2011,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
struct ata_port *ap = host->ports[i];
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
|
||||
ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar");
|
||||
ata_port_pbar_desc(ap, AHCI_PCI_BAR,
|
||||
0x100 + ap->port_no * 0x80, "port");
|
||||
|
||||
/* standard SATA port setup */
|
||||
if (hpriv->port_map & (1 << i))
|
||||
ap->ioaddr.cmd_addr = port_mmio;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
/**
|
||||
* generic_set_mode - mode setting
|
||||
* @ap: interface to set up
|
||||
* @link: link to set up
|
||||
* @unused: returned device on error
|
||||
*
|
||||
* Use a non standard set_mode function. We don't want to be tuned.
|
||||
|
@ -43,24 +43,24 @@
|
|||
* and respect them.
|
||||
*/
|
||||
|
||||
static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
|
||||
static int generic_set_mode(struct ata_link *link, struct ata_device **unused)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
int dma_enabled = 0;
|
||||
int i;
|
||||
struct ata_device *dev;
|
||||
|
||||
/* Bits 5 and 6 indicate if DMA is active on master/slave */
|
||||
if (ap->ioaddr.bmdma_addr)
|
||||
dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->dma_mode = XFER_MW_DMA_0;
|
||||
/* We do need the right mode information for DMA or PIO
|
||||
and this comes from the current configuration flags */
|
||||
if (dma_enabled & (1 << (5 + i))) {
|
||||
if (dma_enabled & (1 << (5 + dev->devno))) {
|
||||
ata_id_to_dma_mode(dev, XFER_MW_DMA_0);
|
||||
dev->flags &= ~ATA_DFLAG_PIO;
|
||||
} else {
|
||||
|
@ -95,7 +95,6 @@ static struct scsi_host_template generic_sht = {
|
|||
static struct ata_port_operations generic_port_ops = {
|
||||
.set_mode = generic_set_mode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -121,9 +120,8 @@ static struct ata_port_operations generic_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int all_generic_ide; /* Set to claim all devices */
|
||||
|
|
|
@ -123,7 +123,6 @@ enum {
|
|||
ich_pata_33 = 1, /* ICH up to UDMA 33 only */
|
||||
ich_pata_66 = 2, /* ICH up to 66 Mhz */
|
||||
ich_pata_100 = 3, /* ICH up to UDMA 100 */
|
||||
ich_pata_133 = 4, /* ICH up to UDMA 133 */
|
||||
ich5_sata = 5,
|
||||
ich6_sata = 6,
|
||||
ich6_sata_ahci = 7,
|
||||
|
@ -199,7 +198,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
|
|||
{ 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
{ 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
/* Intel ICH5 */
|
||||
{ 0x8086, 0x24DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
|
||||
{ 0x8086, 0x24DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
/* C-ICH (i810E2) */
|
||||
{ 0x8086, 0x245B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
/* ESB (855GME/875P + 6300ESB) UDMA 100 */
|
||||
|
@ -207,7 +206,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
|
|||
/* ICH6 (and 6) (i915) UDMA 100 */
|
||||
{ 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
/* ICH7/7-R (i945, i975) UDMA 100*/
|
||||
{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
|
||||
{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
/* ICH8 Mobile PATA Controller */
|
||||
{ 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
|
||||
|
@ -290,7 +289,6 @@ static struct scsi_host_template piix_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations piix_pata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = piix_set_piomode,
|
||||
.set_dmamode = piix_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -318,13 +316,11 @@ static const struct ata_port_operations piix_pata_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations ich_pata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = piix_set_piomode,
|
||||
.set_dmamode = ich_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -352,14 +348,11 @@ static const struct ata_port_operations ich_pata_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations piix_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -382,7 +375,6 @@ static const struct ata_port_operations piix_sata_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -445,15 +437,15 @@ static const struct piix_map_db ich8_map_db = {
|
|||
};
|
||||
|
||||
static const struct piix_map_db tolapai_map_db = {
|
||||
.mask = 0x3,
|
||||
.port_enable = 0x3,
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
{ P0, NA, P1, NA }, /* 00b */
|
||||
{ RV, RV, RV, RV }, /* 01b */
|
||||
{ RV, RV, RV, RV }, /* 10b */
|
||||
{ RV, RV, RV, RV },
|
||||
},
|
||||
.mask = 0x3,
|
||||
.port_enable = 0x3,
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
{ P0, NA, P1, NA }, /* 00b */
|
||||
{ RV, RV, RV, RV }, /* 01b */
|
||||
{ RV, RV, RV, RV }, /* 10b */
|
||||
{ RV, RV, RV, RV },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct piix_map_db *piix_map_db_table[] = {
|
||||
|
@ -466,7 +458,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
|
|||
};
|
||||
|
||||
static struct ata_port_info piix_port_info[] = {
|
||||
/* piix_pata_33: 0: PIIX4 at 33MHz */
|
||||
[piix_pata_33] = /* PIIX4 at 33MHz */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_PATA_FLAGS,
|
||||
|
@ -476,7 +468,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_pata_ops,
|
||||
},
|
||||
|
||||
/* ich_pata_33: 1 ICH0 - ICH at 33Mhz*/
|
||||
[ich_pata_33] = /* ICH0 - ICH at 33Mhz*/
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_PATA_FLAGS,
|
||||
|
@ -485,7 +477,8 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.udma_mask = ATA_UDMA2, /* UDMA33 */
|
||||
.port_ops = &ich_pata_ops,
|
||||
},
|
||||
/* ich_pata_66: 2 ICH controllers up to 66MHz */
|
||||
|
||||
[ich_pata_66] = /* ICH controllers up to 66MHz */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_PATA_FLAGS,
|
||||
|
@ -495,7 +488,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &ich_pata_ops,
|
||||
},
|
||||
|
||||
/* ich_pata_100: 3 */
|
||||
[ich_pata_100] =
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
|
||||
|
@ -505,17 +498,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &ich_pata_ops,
|
||||
},
|
||||
|
||||
/* ich_pata_133: 4 ICH with full UDMA6 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
|
||||
.pio_mask = 0x1f, /* pio 0-4 */
|
||||
.mwdma_mask = 0x06, /* Check: maybe 0x07 */
|
||||
.udma_mask = ATA_UDMA6, /* UDMA133 */
|
||||
.port_ops = &ich_pata_ops,
|
||||
},
|
||||
|
||||
/* ich5_sata: 5 */
|
||||
[ich5_sata] =
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_SATA_FLAGS,
|
||||
|
@ -525,7 +508,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich6_sata: 6 */
|
||||
[ich6_sata] =
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR,
|
||||
|
@ -535,7 +518,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich6_sata_ahci: 7 */
|
||||
[ich6_sata_ahci] =
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
|
||||
|
@ -546,7 +529,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich6m_sata_ahci: 8 */
|
||||
[ich6m_sata_ahci] =
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
|
||||
|
@ -557,7 +540,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich8_sata_ahci: 9 */
|
||||
[ich8_sata_ahci] =
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
|
||||
|
@ -568,7 +551,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* piix_pata_mwdma: 10: PIIX3 MWDMA only */
|
||||
[piix_pata_mwdma] = /* PIIX3 MWDMA only */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_PATA_FLAGS,
|
||||
|
@ -577,7 +560,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_pata_ops,
|
||||
},
|
||||
|
||||
/* tolapai_sata_ahci: 11: */
|
||||
[tolapai_sata_ahci] =
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
|
||||
|
@ -615,6 +598,7 @@ static const struct ich_laptop ich_laptop[] = {
|
|||
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
|
||||
{ 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
|
||||
{ 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
|
||||
{ 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
|
||||
{ 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
|
||||
/* end marker */
|
||||
{ 0, }
|
||||
|
@ -657,19 +641,20 @@ static int ich_pata_cable_detect(struct ata_port *ap)
|
|||
|
||||
/**
|
||||
* piix_pata_prereset - prereset for PATA host controller
|
||||
* @ap: Target port
|
||||
* @link: Target link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
static int piix_pata_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static void piix_pata_error_handler(struct ata_port *ap)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/acpi.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/pci.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include "libata.h"
|
||||
|
||||
#include <acpi/acpi_bus.h>
|
||||
|
@ -40,11 +41,40 @@ static int is_pci_dev(struct device *dev)
|
|||
return (dev->bus == &pci_bus_type);
|
||||
}
|
||||
|
||||
static void ata_acpi_associate_sata_port(struct ata_port *ap)
|
||||
/**
|
||||
* ata_acpi_associate_sata_port - associate SATA port with ACPI objects
|
||||
* @ap: target SATA port
|
||||
*
|
||||
* Look up ACPI objects associated with @ap and initialize acpi_handle
|
||||
* fields of @ap, the port and devices accordingly.
|
||||
*
|
||||
* LOCKING:
|
||||
* EH context.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno on failure.
|
||||
*/
|
||||
void ata_acpi_associate_sata_port(struct ata_port *ap)
|
||||
{
|
||||
acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
|
||||
WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
|
||||
|
||||
ap->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr);
|
||||
if (!ap->nr_pmp_links) {
|
||||
acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
|
||||
|
||||
ap->link.device->acpi_handle =
|
||||
acpi_get_child(ap->host->acpi_handle, adr);
|
||||
} else {
|
||||
struct ata_link *link;
|
||||
|
||||
ap->link.device->acpi_handle = NULL;
|
||||
|
||||
ata_port_for_each_link(link, ap) {
|
||||
acpi_integer adr = SATA_ADR(ap->port_no, link->pmp);
|
||||
|
||||
link->device->acpi_handle =
|
||||
acpi_get_child(ap->host->acpi_handle, adr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ata_acpi_associate_ide_port(struct ata_port *ap)
|
||||
|
@ -60,12 +90,53 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
|
|||
max_devices++;
|
||||
|
||||
for (i = 0; i < max_devices; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
struct ata_device *dev = &ap->link.device[i];
|
||||
|
||||
dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj,
|
||||
u32 event)
|
||||
{
|
||||
char event_string[12];
|
||||
char *envp[] = { event_string, NULL };
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
|
||||
if (event == 0 || event == 1) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
ata_ehi_clear_desc(ehi);
|
||||
ata_ehi_push_desc(ehi, "ACPI event");
|
||||
ata_ehi_hotplugged(ehi);
|
||||
ata_port_freeze(ap);
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
}
|
||||
|
||||
if (kobj) {
|
||||
sprintf(event_string, "BAY_EVENT=%d", event);
|
||||
kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
|
||||
}
|
||||
}
|
||||
|
||||
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct ata_device *dev = data;
|
||||
struct kobject *kobj = NULL;
|
||||
|
||||
if (dev->sdev)
|
||||
kobj = &dev->sdev->sdev_gendev.kobj;
|
||||
|
||||
ata_acpi_handle_hotplug (dev->link->ap, kobj, event);
|
||||
}
|
||||
|
||||
static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct ata_port *ap = data;
|
||||
|
||||
ata_acpi_handle_hotplug (ap, &ap->dev->kobj, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_acpi_associate - associate ATA host with ACPI objects
|
||||
* @host: target ATA host
|
||||
|
@ -81,7 +152,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
|
|||
*/
|
||||
void ata_acpi_associate(struct ata_host *host)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (!is_pci_dev(host->dev) || libata_noacpi)
|
||||
return;
|
||||
|
@ -97,6 +168,22 @@ void ata_acpi_associate(struct ata_host *host)
|
|||
ata_acpi_associate_sata_port(ap);
|
||||
else
|
||||
ata_acpi_associate_ide_port(ap);
|
||||
|
||||
if (ap->acpi_handle)
|
||||
acpi_install_notify_handler (ap->acpi_handle,
|
||||
ACPI_SYSTEM_NOTIFY,
|
||||
ata_acpi_ap_notify,
|
||||
ap);
|
||||
|
||||
for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
|
||||
struct ata_device *dev = &ap->link.device[j];
|
||||
|
||||
if (dev->acpi_handle)
|
||||
acpi_install_notify_handler (dev->acpi_handle,
|
||||
ACPI_SYSTEM_NOTIFY,
|
||||
ata_acpi_dev_notify,
|
||||
dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +200,7 @@ void ata_acpi_associate(struct ata_host *host)
|
|||
* RETURNS:
|
||||
* 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
|
||||
*/
|
||||
static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
|
||||
int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
|
||||
{
|
||||
struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
|
||||
union acpi_object *out_obj;
|
||||
|
@ -157,6 +244,8 @@ static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
|
|||
return rc;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ata_acpi_gtm);
|
||||
|
||||
/**
|
||||
* ata_acpi_stm - execute _STM
|
||||
* @ap: target ATA port
|
||||
|
@ -170,7 +259,7 @@ static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
|
|||
* RETURNS:
|
||||
* 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
|
||||
*/
|
||||
static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
|
||||
int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_object_list input;
|
||||
|
@ -182,10 +271,10 @@ static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
|
|||
/* Buffers for id may need byteswapping ? */
|
||||
in_params[1].type = ACPI_TYPE_BUFFER;
|
||||
in_params[1].buffer.length = 512;
|
||||
in_params[1].buffer.pointer = (u8 *)ap->device[0].id;
|
||||
in_params[1].buffer.pointer = (u8 *)ap->link.device[0].id;
|
||||
in_params[2].type = ACPI_TYPE_BUFFER;
|
||||
in_params[2].buffer.length = 512;
|
||||
in_params[2].buffer.pointer = (u8 *)ap->device[1].id;
|
||||
in_params[2].buffer.pointer = (u8 *)ap->link.device[1].id;
|
||||
|
||||
input.count = 3;
|
||||
input.pointer = in_params;
|
||||
|
@ -202,6 +291,8 @@ static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ata_acpi_stm);
|
||||
|
||||
/**
|
||||
* ata_dev_get_GTF - get the drive bootup default taskfile settings
|
||||
* @dev: target ATA device
|
||||
|
@ -226,7 +317,7 @@ static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
|
|||
static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
|
||||
void **ptr_to_free)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
acpi_status status;
|
||||
struct acpi_buffer output;
|
||||
union acpi_object *out_obj;
|
||||
|
@ -295,6 +386,44 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_acpi_cbl_80wire - Check for 80 wire cable
|
||||
* @ap: Port to check
|
||||
*
|
||||
* Return 1 if the ACPI mode data for this port indicates the BIOS selected
|
||||
* an 80wire mode.
|
||||
*/
|
||||
|
||||
int ata_acpi_cbl_80wire(struct ata_port *ap)
|
||||
{
|
||||
struct ata_acpi_gtm gtm;
|
||||
int valid = 0;
|
||||
|
||||
/* No _GTM data, no information */
|
||||
if (ata_acpi_gtm(ap, >m) < 0)
|
||||
return 0;
|
||||
|
||||
/* Split timing, DMA enabled */
|
||||
if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55)
|
||||
valid |= 1;
|
||||
if ((gtm.flags & 0x14) == 0x14 && gtm.drive[1].dma < 55)
|
||||
valid |= 2;
|
||||
/* Shared timing, DMA enabled */
|
||||
if ((gtm.flags & 0x11) == 0x01 && gtm.drive[0].dma < 55)
|
||||
valid |= 1;
|
||||
if ((gtm.flags & 0x14) == 0x04 && gtm.drive[0].dma < 55)
|
||||
valid |= 2;
|
||||
|
||||
/* Drive check */
|
||||
if ((valid & 1) && ata_dev_enabled(&ap->link.device[0]))
|
||||
return 1;
|
||||
if ((valid & 2) && ata_dev_enabled(&ap->link.device[1]))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire);
|
||||
|
||||
/**
|
||||
* taskfile_load_raw - send taskfile registers to host controller
|
||||
* @dev: target ATA device
|
||||
|
@ -320,7 +449,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
|
|||
static int taskfile_load_raw(struct ata_device *dev,
|
||||
const struct ata_acpi_gtf *gtf)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
struct ata_taskfile tf, rtf;
|
||||
unsigned int err_mask;
|
||||
|
||||
|
@ -349,7 +478,7 @@ static int taskfile_load_raw(struct ata_device *dev,
|
|||
tf.lbal, tf.lbam, tf.lbah, tf.device);
|
||||
|
||||
rtf = tf;
|
||||
err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0);
|
||||
err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0);
|
||||
if (err_mask) {
|
||||
ata_dev_printk(dev, KERN_ERR,
|
||||
"ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed "
|
||||
|
@ -424,7 +553,7 @@ static int ata_acpi_exec_tfs(struct ata_device *dev)
|
|||
*/
|
||||
static int ata_acpi_push_id(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
int err;
|
||||
acpi_status status;
|
||||
struct acpi_object_list input;
|
||||
|
@ -508,7 +637,7 @@ int ata_acpi_on_suspend(struct ata_port *ap)
|
|||
*/
|
||||
void ata_acpi_on_resume(struct ata_port *ap)
|
||||
{
|
||||
int i;
|
||||
struct ata_device *dev;
|
||||
|
||||
if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) {
|
||||
BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
|
||||
|
@ -518,8 +647,8 @@ void ata_acpi_on_resume(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/* schedule _GTF */
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++)
|
||||
ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING;
|
||||
ata_link_for_each_dev(dev, &ap->link)
|
||||
dev->flags |= ATA_DFLAG_ACPI_PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -538,8 +667,8 @@ void ata_acpi_on_resume(struct ata_port *ap)
|
|||
*/
|
||||
int ata_acpi_on_devcfg(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
struct ata_eh_context *ehc = &ap->link.eh_context;
|
||||
int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
|
||||
int rc;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -71,11 +71,10 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
|
|||
#define ALL_SUB_MPAGES 0xff
|
||||
|
||||
|
||||
static const u8 def_rw_recovery_mpage[] = {
|
||||
static const u8 def_rw_recovery_mpage[RW_RECOVERY_MPAGE_LEN] = {
|
||||
RW_RECOVERY_MPAGE,
|
||||
RW_RECOVERY_MPAGE_LEN - 2,
|
||||
(1 << 7) | /* AWRE, sat-r06 say it shall be 0 */
|
||||
(1 << 6), /* ARRE (auto read reallocation) */
|
||||
(1 << 7), /* AWRE */
|
||||
0, /* read retry count */
|
||||
0, 0, 0, 0,
|
||||
0, /* write retry count */
|
||||
|
@ -450,13 +449,8 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
|
|||
qc->scsicmd = cmd;
|
||||
qc->scsidone = done;
|
||||
|
||||
if (cmd->use_sg) {
|
||||
qc->__sg = (struct scatterlist *) cmd->request_buffer;
|
||||
qc->n_elem = cmd->use_sg;
|
||||
} else if (cmd->request_bufflen) {
|
||||
qc->__sg = &qc->sgent;
|
||||
qc->n_elem = 1;
|
||||
}
|
||||
qc->__sg = scsi_sglist(cmd);
|
||||
qc->n_elem = scsi_sg_count(cmd);
|
||||
} else {
|
||||
cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1);
|
||||
done(cmd);
|
||||
|
@ -755,6 +749,13 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
|
|||
{
|
||||
sdev->use_10_for_rw = 1;
|
||||
sdev->use_10_for_ms = 1;
|
||||
|
||||
/* Schedule policy is determined by ->qc_defer() callback and
|
||||
* it needs to see every deferred qc. Set dev_blocked to 1 to
|
||||
* prevent SCSI midlayer from automatically deferring
|
||||
* requests.
|
||||
*/
|
||||
sdev->max_device_blocked = 1;
|
||||
}
|
||||
|
||||
static void ata_scsi_dev_config(struct scsi_device *sdev,
|
||||
|
@ -943,6 +944,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
|
|||
goto invalid_fld; /* LOEJ bit set not supported */
|
||||
if (((cdb[4] >> 4) & 0xf) != 0)
|
||||
goto invalid_fld; /* power conditions not supported */
|
||||
|
||||
if (qc->dev->horkage & ATA_HORKAGE_SKIP_PM) {
|
||||
/* the device lacks PM support, finish without doing anything */
|
||||
scmd->result = SAM_STAT_GOOD;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (cdb[4] & 0x1) {
|
||||
tf->nsect = 1; /* 1 sector, lba=0 */
|
||||
|
||||
|
@ -1368,14 +1376,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
|
|||
case ATA_CMD_SET_FEATURES:
|
||||
if ((qc->tf.feature == SETFEATURES_WC_ON) ||
|
||||
(qc->tf.feature == SETFEATURES_WC_OFF)) {
|
||||
ap->eh_info.action |= ATA_EH_REVALIDATE;
|
||||
ap->link.eh_info.action |= ATA_EH_REVALIDATE;
|
||||
ata_port_schedule_eh(ap);
|
||||
}
|
||||
break;
|
||||
|
||||
case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
|
||||
case ATA_CMD_SET_MULTI: /* multi_count changed */
|
||||
ap->eh_info.action |= ATA_EH_REVALIDATE;
|
||||
ap->link.eh_info.action |= ATA_EH_REVALIDATE;
|
||||
ata_port_schedule_eh(ap);
|
||||
break;
|
||||
}
|
||||
|
@ -1421,37 +1429,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
|
|||
ata_qc_free(qc);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scmd_need_defer - Check whether we need to defer scmd
|
||||
* @dev: ATA device to which the command is addressed
|
||||
* @is_io: Is the command IO (and thus possibly NCQ)?
|
||||
*
|
||||
* NCQ and non-NCQ commands cannot run together. As upper layer
|
||||
* only knows the queue depth, we are responsible for maintaining
|
||||
* exclusion. This function checks whether a new command can be
|
||||
* issued to @dev.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*
|
||||
* RETURNS:
|
||||
* 1 if deferring is needed, 0 otherwise.
|
||||
*/
|
||||
static int ata_scmd_need_defer(struct ata_device *dev, int is_io)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
int is_ncq = is_io && ata_ncq_enabled(dev);
|
||||
|
||||
if (is_ncq) {
|
||||
if (!ata_tag_valid(ap->active_tag))
|
||||
return 0;
|
||||
} else {
|
||||
if (!ata_tag_valid(ap->active_tag) && !ap->sactive)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_translate - Translate then issue SCSI command to ATA device
|
||||
* @dev: ATA device to which the command is addressed
|
||||
|
@ -1483,14 +1460,12 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
void (*done)(struct scsi_cmnd *),
|
||||
ata_xlat_func_t xlat_func)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
struct ata_queued_cmd *qc;
|
||||
int is_io = xlat_func == ata_scsi_rw_xlat;
|
||||
int rc;
|
||||
|
||||
VPRINTK("ENTER\n");
|
||||
|
||||
if (unlikely(ata_scmd_need_defer(dev, is_io)))
|
||||
goto defer;
|
||||
|
||||
qc = ata_scsi_qc_new(dev, cmd, done);
|
||||
if (!qc)
|
||||
goto err_mem;
|
||||
|
@ -1498,17 +1473,13 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
/* data is present; dma-map it */
|
||||
if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
|
||||
cmd->sc_data_direction == DMA_TO_DEVICE) {
|
||||
if (unlikely(cmd->request_bufflen < 1)) {
|
||||
if (unlikely(scsi_bufflen(cmd) < 1)) {
|
||||
ata_dev_printk(dev, KERN_WARNING,
|
||||
"WARNING: zero len r/w req\n");
|
||||
goto err_did;
|
||||
}
|
||||
|
||||
if (cmd->use_sg)
|
||||
ata_sg_init(qc, cmd->request_buffer, cmd->use_sg);
|
||||
else
|
||||
ata_sg_init_one(qc, cmd->request_buffer,
|
||||
cmd->request_bufflen);
|
||||
ata_sg_init(qc, scsi_sglist(cmd), scsi_sg_count(cmd));
|
||||
|
||||
qc->dma_dir = cmd->sc_data_direction;
|
||||
}
|
||||
|
@ -1518,6 +1489,11 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
if (xlat_func(qc))
|
||||
goto early_finish;
|
||||
|
||||
if (ap->ops->qc_defer) {
|
||||
if ((rc = ap->ops->qc_defer(qc)))
|
||||
goto defer;
|
||||
}
|
||||
|
||||
/* select device, send command to hardware */
|
||||
ata_qc_issue(qc);
|
||||
|
||||
|
@ -1539,8 +1515,12 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
return 0;
|
||||
|
||||
defer:
|
||||
ata_qc_free(qc);
|
||||
DPRINTK("EXIT - defer\n");
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
if (rc == ATA_DEFER_LINK)
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
else
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1562,15 +1542,14 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
|
|||
u8 *buf;
|
||||
unsigned int buflen;
|
||||
|
||||
if (cmd->use_sg) {
|
||||
struct scatterlist *sg;
|
||||
struct scatterlist *sg = scsi_sglist(cmd);
|
||||
|
||||
sg = (struct scatterlist *) cmd->request_buffer;
|
||||
if (sg) {
|
||||
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
|
||||
buflen = sg->length;
|
||||
} else {
|
||||
buf = cmd->request_buffer;
|
||||
buflen = cmd->request_bufflen;
|
||||
buf = NULL;
|
||||
buflen = 0;
|
||||
}
|
||||
|
||||
*buf_out = buf;
|
||||
|
@ -1590,12 +1569,9 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
|
|||
|
||||
static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
|
||||
{
|
||||
if (cmd->use_sg) {
|
||||
struct scatterlist *sg;
|
||||
|
||||
sg = (struct scatterlist *) cmd->request_buffer;
|
||||
struct scatterlist *sg = scsi_sglist(cmd);
|
||||
if (sg)
|
||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1816,6 +1792,62 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
* @buflen: Response buffer length.
|
||||
*
|
||||
* Yields SAT-specified ATA VPD page.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
|
||||
unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
|
||||
unsigned int buflen)
|
||||
{
|
||||
u8 pbuf[60];
|
||||
struct ata_taskfile tf;
|
||||
unsigned int i;
|
||||
|
||||
if (!buflen)
|
||||
return 0;
|
||||
|
||||
memset(&pbuf, 0, sizeof(pbuf));
|
||||
memset(&tf, 0, sizeof(tf));
|
||||
|
||||
pbuf[1] = 0x89; /* our page code */
|
||||
pbuf[2] = (0x238 >> 8); /* page size fixed at 238h */
|
||||
pbuf[3] = (0x238 & 0xff);
|
||||
|
||||
memcpy(&pbuf[8], "linux ", 8);
|
||||
memcpy(&pbuf[16], "libata ", 16);
|
||||
memcpy(&pbuf[32], DRV_VERSION, 4);
|
||||
ata_id_string(args->id, &pbuf[32], ATA_ID_FW_REV, 4);
|
||||
|
||||
/* we don't store the ATA device signature, so we fake it */
|
||||
|
||||
tf.command = ATA_DRDY; /* really, this is Status reg */
|
||||
tf.lbal = 0x1;
|
||||
tf.nsect = 0x1;
|
||||
|
||||
ata_tf_to_fis(&tf, 0, 1, &pbuf[36]); /* TODO: PMP? */
|
||||
pbuf[36] = 0x34; /* force D2H Reg FIS (34h) */
|
||||
|
||||
pbuf[56] = ATA_CMD_ID_ATA;
|
||||
|
||||
i = min(buflen, 60U);
|
||||
memcpy(rbuf, &pbuf[0], i);
|
||||
buflen -= i;
|
||||
|
||||
if (!buflen)
|
||||
return 0;
|
||||
|
||||
memcpy(&rbuf[60], &args->id[0], min(buflen, 512U));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_noop - Command handler that simply returns success.
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
|
@ -2273,8 +2305,8 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
|
|||
qc->tf.feature |= ATAPI_PKT_DMA;
|
||||
} else {
|
||||
qc->tf.protocol = ATA_PROT_ATAPI;
|
||||
qc->tf.lbam = (8 * 1024) & 0xff;
|
||||
qc->tf.lbah = (8 * 1024) >> 8;
|
||||
qc->tf.lbam = SCSI_SENSE_BUFFERSIZE;
|
||||
qc->tf.lbah = 0;
|
||||
}
|
||||
qc->nbytes = SCSI_SENSE_BUFFERSIZE;
|
||||
|
||||
|
@ -2383,6 +2415,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
|||
struct ata_device *dev = qc->dev;
|
||||
int using_pio = (dev->flags & ATA_DFLAG_PIO);
|
||||
int nodata = (scmd->sc_data_direction == DMA_NONE);
|
||||
unsigned int nbytes;
|
||||
|
||||
memset(qc->cdb, 0, dev->cdb_len);
|
||||
memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
|
||||
|
@ -2396,20 +2429,26 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
|||
}
|
||||
|
||||
qc->tf.command = ATA_CMD_PACKET;
|
||||
qc->nbytes = scmd->request_bufflen;
|
||||
qc->nbytes = scsi_bufflen(scmd);
|
||||
|
||||
/* check whether ATAPI DMA is safe */
|
||||
if (!using_pio && ata_check_atapi_dma(qc))
|
||||
using_pio = 1;
|
||||
|
||||
/* Some controller variants snoop this value for Packet transfers
|
||||
to do state machine and FIFO management. Thus we want to set it
|
||||
properly, and for DMA where it is effectively meaningless */
|
||||
nbytes = min(qc->nbytes, (unsigned int)63 * 1024);
|
||||
|
||||
qc->tf.lbam = (nbytes & 0xFF);
|
||||
qc->tf.lbah = (nbytes >> 8);
|
||||
|
||||
if (using_pio || nodata) {
|
||||
/* no data, or PIO data xfer */
|
||||
if (nodata)
|
||||
qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
|
||||
else
|
||||
qc->tf.protocol = ATA_PROT_ATAPI;
|
||||
qc->tf.lbam = (8 * 1024) & 0xff;
|
||||
qc->tf.lbah = (8 * 1024) >> 8;
|
||||
} else {
|
||||
/* DMA data xfer */
|
||||
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
|
||||
|
@ -2420,24 +2459,42 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
|||
qc->tf.feature |= ATAPI_DMADIR;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: We need to translate 0x05 READ_BLOCK_LIMITS to a MODE_SENSE
|
||||
as ATAPI tape drives don't get this right otherwise */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ata_device * ata_find_dev(struct ata_port *ap, int id)
|
||||
static struct ata_device * ata_find_dev(struct ata_port *ap, int devno)
|
||||
{
|
||||
if (likely(id < ATA_MAX_DEVICES))
|
||||
return &ap->device[id];
|
||||
if (ap->nr_pmp_links == 0) {
|
||||
if (likely(devno < ata_link_max_devices(&ap->link)))
|
||||
return &ap->link.device[devno];
|
||||
} else {
|
||||
if (likely(devno < ap->nr_pmp_links))
|
||||
return &ap->pmp_link[devno].device[0];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap,
|
||||
const struct scsi_device *scsidev)
|
||||
{
|
||||
/* skip commands not addressed to targets we simulate */
|
||||
if (unlikely(scsidev->channel || scsidev->lun))
|
||||
return NULL;
|
||||
int devno;
|
||||
|
||||
return ata_find_dev(ap, scsidev->id);
|
||||
/* skip commands not addressed to targets we simulate */
|
||||
if (ap->nr_pmp_links == 0) {
|
||||
if (unlikely(scsidev->channel || scsidev->lun))
|
||||
return NULL;
|
||||
devno = scsidev->id;
|
||||
} else {
|
||||
if (unlikely(scsidev->id || scsidev->lun))
|
||||
return NULL;
|
||||
devno = scsidev->channel;
|
||||
}
|
||||
|
||||
return ata_find_dev(ap, devno);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2458,7 +2515,7 @@ static int ata_scsi_dev_enabled(struct ata_device *dev)
|
|||
if (unlikely(!ata_dev_enabled(dev)))
|
||||
return 0;
|
||||
|
||||
if (!atapi_enabled || (dev->ap->flags & ATA_FLAG_NO_ATAPI)) {
|
||||
if (!atapi_enabled || (dev->link->ap->flags & ATA_FLAG_NO_ATAPI)) {
|
||||
if (unlikely(dev->class == ATA_DEV_ATAPI)) {
|
||||
ata_dev_printk(dev, KERN_WARNING,
|
||||
"WARNING: ATAPI is %s, device ignored.\n",
|
||||
|
@ -2631,7 +2688,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
|||
case ATA_CMD_WRITE_LONG_ONCE:
|
||||
if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
|
||||
goto invalid_fld;
|
||||
qc->sect_size = scmd->request_bufflen;
|
||||
qc->sect_size = scsi_bufflen(scmd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2661,7 +2718,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
|||
* TODO: find out if we need to do more here to
|
||||
* cover scatter/gather case.
|
||||
*/
|
||||
qc->nbytes = scmd->request_bufflen;
|
||||
qc->nbytes = scsi_bufflen(scmd);
|
||||
|
||||
/* request result TF */
|
||||
qc->flags |= ATA_QCFLAG_RESULT_TF;
|
||||
|
@ -2746,28 +2803,48 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
|
|||
void (*done)(struct scsi_cmnd *),
|
||||
struct ata_device *dev)
|
||||
{
|
||||
u8 scsi_op = scmd->cmnd[0];
|
||||
ata_xlat_func_t xlat_func;
|
||||
int rc = 0;
|
||||
|
||||
if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) {
|
||||
DPRINTK("bad CDB len=%u, max=%u\n",
|
||||
scmd->cmd_len, dev->cdb_len);
|
||||
scmd->result = DID_ERROR << 16;
|
||||
done(scmd);
|
||||
return 0;
|
||||
if (dev->class == ATA_DEV_ATA) {
|
||||
if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len))
|
||||
goto bad_cdb_len;
|
||||
|
||||
xlat_func = ata_get_xlat_func(dev, scsi_op);
|
||||
} else {
|
||||
if (unlikely(!scmd->cmd_len))
|
||||
goto bad_cdb_len;
|
||||
|
||||
xlat_func = NULL;
|
||||
if (likely((scsi_op != ATA_16) || !atapi_passthru16)) {
|
||||
/* relay SCSI command to ATAPI device */
|
||||
if (unlikely(scmd->cmd_len > dev->cdb_len))
|
||||
goto bad_cdb_len;
|
||||
|
||||
xlat_func = atapi_xlat;
|
||||
} else {
|
||||
/* ATA_16 passthru, treat as an ATA command */
|
||||
if (unlikely(scmd->cmd_len > 16))
|
||||
goto bad_cdb_len;
|
||||
|
||||
xlat_func = ata_get_xlat_func(dev, scsi_op);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->class == ATA_DEV_ATA) {
|
||||
ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
|
||||
scmd->cmnd[0]);
|
||||
|
||||
if (xlat_func)
|
||||
rc = ata_scsi_translate(dev, scmd, done, xlat_func);
|
||||
else
|
||||
ata_scsi_simulate(dev, scmd, done);
|
||||
} else
|
||||
rc = ata_scsi_translate(dev, scmd, done, atapi_xlat);
|
||||
if (xlat_func)
|
||||
rc = ata_scsi_translate(dev, scmd, done, xlat_func);
|
||||
else
|
||||
ata_scsi_simulate(dev, scmd, done);
|
||||
|
||||
return rc;
|
||||
|
||||
bad_cdb_len:
|
||||
DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n",
|
||||
scmd->cmd_len, scsi_op, dev->cdb_len);
|
||||
scmd->result = DID_ERROR << 16;
|
||||
done(scmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2835,6 +2912,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
{
|
||||
struct ata_scsi_args args;
|
||||
const u8 *scsicmd = cmd->cmnd;
|
||||
u8 tmp8;
|
||||
|
||||
args.dev = dev;
|
||||
args.id = dev->id;
|
||||
|
@ -2842,15 +2920,9 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
args.done = done;
|
||||
|
||||
switch(scsicmd[0]) {
|
||||
/* no-op's, complete with success */
|
||||
case SYNCHRONIZE_CACHE:
|
||||
case REZERO_UNIT:
|
||||
case SEEK_6:
|
||||
case SEEK_10:
|
||||
case TEST_UNIT_READY:
|
||||
case FORMAT_UNIT: /* FIXME: correct? */
|
||||
case SEND_DIAGNOSTIC: /* FIXME: correct? */
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
|
||||
/* TODO: worth improving? */
|
||||
case FORMAT_UNIT:
|
||||
ata_scsi_invalid_field(cmd, done);
|
||||
break;
|
||||
|
||||
case INQUIRY:
|
||||
|
@ -2858,14 +2930,23 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
ata_scsi_invalid_field(cmd, done);
|
||||
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
|
||||
else if (scsicmd[2] == 0x00)
|
||||
else switch (scsicmd[2]) {
|
||||
case 0x00:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00);
|
||||
else if (scsicmd[2] == 0x80)
|
||||
break;
|
||||
case 0x80:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80);
|
||||
else if (scsicmd[2] == 0x83)
|
||||
break;
|
||||
case 0x83:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
|
||||
else
|
||||
break;
|
||||
case 0x89:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
|
||||
break;
|
||||
default:
|
||||
ata_scsi_invalid_field(cmd, done);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_SENSE:
|
||||
|
@ -2893,8 +2974,33 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns);
|
||||
break;
|
||||
|
||||
/* mandatory commands we haven't implemented yet */
|
||||
case REQUEST_SENSE:
|
||||
ata_scsi_set_sense(cmd, 0, 0, 0);
|
||||
cmd->result = (DRIVER_SENSE << 24);
|
||||
done(cmd);
|
||||
break;
|
||||
|
||||
/* if we reach this, then writeback caching is disabled,
|
||||
* turning this into a no-op.
|
||||
*/
|
||||
case SYNCHRONIZE_CACHE:
|
||||
/* fall through */
|
||||
|
||||
/* no-op's, complete with success */
|
||||
case REZERO_UNIT:
|
||||
case SEEK_6:
|
||||
case SEEK_10:
|
||||
case TEST_UNIT_READY:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
|
||||
break;
|
||||
|
||||
case SEND_DIAGNOSTIC:
|
||||
tmp8 = scsicmd[1] & ~(1 << 3);
|
||||
if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4]))
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
|
||||
else
|
||||
ata_scsi_invalid_field(cmd, done);
|
||||
break;
|
||||
|
||||
/* all other commands */
|
||||
default:
|
||||
|
@ -2928,6 +3034,13 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
|
|||
shost->max_channel = 1;
|
||||
shost->max_cmd_len = 16;
|
||||
|
||||
/* Schedule policy is determined by ->qc_defer()
|
||||
* callback and it needs to see every deferred qc.
|
||||
* Set host_blocked to 1 to prevent SCSI midlayer from
|
||||
* automatically deferring requests.
|
||||
*/
|
||||
shost->max_host_blocked = 1;
|
||||
|
||||
rc = scsi_add_host(ap->scsi_host, ap->host->dev);
|
||||
if (rc)
|
||||
goto err_add;
|
||||
|
@ -2951,25 +3064,32 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
|
|||
{
|
||||
int tries = 5;
|
||||
struct ata_device *last_failed_dev = NULL;
|
||||
struct ata_link *link;
|
||||
struct ata_device *dev;
|
||||
unsigned int i;
|
||||
|
||||
if (ap->flags & ATA_FLAG_DISABLED)
|
||||
return;
|
||||
|
||||
repeat:
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct scsi_device *sdev;
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
struct scsi_device *sdev;
|
||||
int channel = 0, id = 0;
|
||||
|
||||
dev = &ap->device[i];
|
||||
if (!ata_dev_enabled(dev) || dev->sdev)
|
||||
continue;
|
||||
|
||||
if (!ata_dev_enabled(dev) || dev->sdev)
|
||||
continue;
|
||||
if (ata_is_host_link(link))
|
||||
id = dev->devno;
|
||||
else
|
||||
channel = link->pmp;
|
||||
|
||||
sdev = __scsi_add_device(ap->scsi_host, 0, i, 0, NULL);
|
||||
if (!IS_ERR(sdev)) {
|
||||
dev->sdev = sdev;
|
||||
scsi_device_put(sdev);
|
||||
sdev = __scsi_add_device(ap->scsi_host, channel, id, 0,
|
||||
NULL);
|
||||
if (!IS_ERR(sdev)) {
|
||||
dev->sdev = sdev;
|
||||
scsi_device_put(sdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2977,12 +3097,14 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
|
|||
* failure occurred, scan would have failed silently. Check
|
||||
* whether all devices are attached.
|
||||
*/
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
dev = &ap->device[i];
|
||||
if (ata_dev_enabled(dev) && !dev->sdev)
|
||||
break;
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev) && !dev->sdev)
|
||||
goto exit_loop;
|
||||
}
|
||||
}
|
||||
if (i == ATA_MAX_DEVICES)
|
||||
exit_loop:
|
||||
if (!link)
|
||||
return;
|
||||
|
||||
/* we're missing some SCSI devices */
|
||||
|
@ -3049,7 +3171,7 @@ int ata_scsi_offline_dev(struct ata_device *dev)
|
|||
*/
|
||||
static void ata_scsi_remove_dev(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
struct scsi_device *sdev;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -3096,6 +3218,43 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void ata_scsi_handle_link_detach(struct ata_link *link)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
unsigned long flags;
|
||||
|
||||
if (!(dev->flags & ATA_DFLAG_DETACHED))
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
dev->flags &= ~ATA_DFLAG_DETACHED;
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
ata_scsi_remove_dev(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_media_change_notify - send media change event
|
||||
* @atadev: Pointer to the disk device with media change event
|
||||
*
|
||||
* Tell the block layer to send a media change notification
|
||||
* event.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
void ata_scsi_media_change_notify(struct ata_device *dev)
|
||||
{
|
||||
#ifdef OTHER_AN_PATCHES_HAVE_BEEN_APPLIED
|
||||
if (dev->sdev)
|
||||
scsi_device_event_notify(dev->sdev, SDEV_MEDIA_CHANGE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_hotplug - SCSI part of hotplug
|
||||
* @work: Pointer to ATA port to perform SCSI hotplug on
|
||||
|
@ -3121,20 +3280,14 @@ void ata_scsi_hotplug(struct work_struct *work)
|
|||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
/* unplug detached devices */
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
unsigned long flags;
|
||||
|
||||
if (!(dev->flags & ATA_DFLAG_DETACHED))
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
dev->flags &= ~ATA_DFLAG_DETACHED;
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
ata_scsi_remove_dev(dev);
|
||||
}
|
||||
/* Unplug detached devices. We cannot use link iterator here
|
||||
* because PMP links have to be scanned even if PMP is
|
||||
* currently not attached. Iterate manually.
|
||||
*/
|
||||
ata_scsi_handle_link_detach(&ap->link);
|
||||
if (ap->pmp_link)
|
||||
for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
|
||||
ata_scsi_handle_link_detach(&ap->pmp_link[i]);
|
||||
|
||||
/* scan for new ones */
|
||||
ata_scsi_scan_host(ap, 0);
|
||||
|
@ -3163,27 +3316,42 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
|
|||
{
|
||||
struct ata_port *ap = ata_shost_to_port(shost);
|
||||
unsigned long flags;
|
||||
int rc = 0;
|
||||
int devno, rc = 0;
|
||||
|
||||
if (!ap->ops->error_handler)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((channel != SCAN_WILD_CARD && channel != 0) ||
|
||||
(lun != SCAN_WILD_CARD && lun != 0))
|
||||
if (lun != SCAN_WILD_CARD && lun)
|
||||
return -EINVAL;
|
||||
|
||||
if (ap->nr_pmp_links == 0) {
|
||||
if (channel != SCAN_WILD_CARD && channel)
|
||||
return -EINVAL;
|
||||
devno = id;
|
||||
} else {
|
||||
if (id != SCAN_WILD_CARD && id)
|
||||
return -EINVAL;
|
||||
devno = channel;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
if (id == SCAN_WILD_CARD) {
|
||||
ap->eh_info.probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
|
||||
ap->eh_info.action |= ATA_EH_SOFTRESET;
|
||||
if (devno == SCAN_WILD_CARD) {
|
||||
struct ata_link *link;
|
||||
|
||||
ata_port_for_each_link(link, ap) {
|
||||
struct ata_eh_info *ehi = &link->eh_info;
|
||||
ehi->probe_mask |= (1 << ata_link_max_devices(link)) - 1;
|
||||
ehi->action |= ATA_EH_SOFTRESET;
|
||||
}
|
||||
} else {
|
||||
struct ata_device *dev = ata_find_dev(ap, id);
|
||||
struct ata_device *dev = ata_find_dev(ap, devno);
|
||||
|
||||
if (dev) {
|
||||
ap->eh_info.probe_mask |= 1 << dev->devno;
|
||||
ap->eh_info.action |= ATA_EH_SOFTRESET;
|
||||
ap->eh_info.flags |= ATA_EHI_RESUME_LINK;
|
||||
struct ata_eh_info *ehi = &dev->link->eh_info;
|
||||
ehi->probe_mask |= 1 << dev->devno;
|
||||
ehi->action |= ATA_EH_SOFTRESET;
|
||||
ehi->flags |= ATA_EHI_RESUME_LINK;
|
||||
} else
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
@ -3214,24 +3382,26 @@ void ata_scsi_dev_rescan(struct work_struct *work)
|
|||
{
|
||||
struct ata_port *ap =
|
||||
container_of(work, struct ata_port, scsi_rescan_task);
|
||||
struct ata_link *link;
|
||||
struct ata_device *dev;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
struct scsi_device *sdev = dev->sdev;
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
struct scsi_device *sdev = dev->sdev;
|
||||
|
||||
if (!ata_dev_enabled(dev) || !sdev)
|
||||
continue;
|
||||
if (scsi_device_get(sdev))
|
||||
continue;
|
||||
if (!ata_dev_enabled(dev) || !sdev)
|
||||
continue;
|
||||
if (scsi_device_get(sdev))
|
||||
continue;
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
scsi_rescan_device(&(sdev->sdev_gendev));
|
||||
scsi_device_put(sdev);
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
scsi_rescan_device(&(sdev->sdev_gendev));
|
||||
scsi_device_put(sdev);
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
@ -3359,7 +3529,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_destroy);
|
|||
int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap)
|
||||
{
|
||||
ata_scsi_sdev_config(sdev);
|
||||
ata_scsi_dev_config(sdev, ap->device);
|
||||
ata_scsi_dev_config(sdev, ap->link.device);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
|
||||
|
@ -3382,8 +3552,8 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
|
|||
|
||||
ata_scsi_dump_cdb(ap, cmd);
|
||||
|
||||
if (likely(ata_scsi_dev_enabled(ap->device)))
|
||||
rc = __ata_scsi_queuecmd(cmd, done, ap->device);
|
||||
if (likely(ata_scsi_dev_enabled(ap->link.device)))
|
||||
rc = __ata_scsi_queuecmd(cmd, done, ap->link.device);
|
||||
else {
|
||||
cmd->result = (DID_BAD_TARGET << 16);
|
||||
done(cmd);
|
||||
|
|
|
@ -64,46 +64,6 @@ u8 ata_irq_on(struct ata_port *ap)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
|
||||
|
||||
/**
|
||||
* ata_irq_ack - Acknowledge a device interrupt.
|
||||
* @ap: Port on which interrupts are enabled.
|
||||
*
|
||||
* Wait up to 10 ms for legacy IDE device to become idle (BUSY
|
||||
* or BUSY+DRQ clear). Obtain dma status and port status from
|
||||
* device. Clear the interrupt. Return port status.
|
||||
*
|
||||
* LOCKING:
|
||||
*/
|
||||
|
||||
u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
|
||||
{
|
||||
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
|
||||
u8 host_stat = 0, post_stat = 0, status;
|
||||
|
||||
status = ata_busy_wait(ap, bits, 1000);
|
||||
if (status & bits)
|
||||
if (ata_msg_err(ap))
|
||||
printk(KERN_ERR "abnormal status 0x%X\n", status);
|
||||
|
||||
if (ap->ioaddr.bmdma_addr) {
|
||||
/* get controller status; clear intr, err bits */
|
||||
host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
|
||||
ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
|
||||
post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
}
|
||||
if (ata_msg_intr(ap))
|
||||
printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
|
||||
__FUNCTION__,
|
||||
host_stat, post_stat, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq) { return 0; }
|
||||
|
||||
/**
|
||||
* ata_tf_load - send taskfile registers to host controller
|
||||
* @ap: Port to which output is sent
|
||||
|
@ -445,7 +405,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
unsigned long flags;
|
||||
int thaw = 0;
|
||||
|
||||
qc = __ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = __ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
|
||||
qc = NULL;
|
||||
|
||||
|
@ -500,7 +460,7 @@ void ata_bmdma_error_handler(struct ata_port *ap)
|
|||
ata_reset_fn_t hardreset;
|
||||
|
||||
hardreset = NULL;
|
||||
if (sata_scr_valid(ap))
|
||||
if (sata_scr_valid(&ap->link))
|
||||
hardreset = sata_std_hardreset;
|
||||
|
||||
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
|
||||
|
@ -607,6 +567,9 @@ int ata_pci_init_bmdma(struct ata_host *host)
|
|||
if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||
(ioread8(bmdma + 2) & 0x80))
|
||||
host->flags |= ATA_HOST_SIMPLEX;
|
||||
|
||||
ata_port_desc(ap, "bmdma 0x%llx",
|
||||
(unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -674,6 +637,10 @@ int ata_pci_init_sff_host(struct ata_host *host)
|
|||
((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
|
||||
(unsigned long long)pci_resource_start(pdev, base),
|
||||
(unsigned long long)pci_resource_start(pdev, base + 1));
|
||||
|
||||
mask |= 1 << i;
|
||||
}
|
||||
|
||||
|
@ -844,24 +811,30 @@ int ata_pci_init_one(struct pci_dev *pdev,
|
|||
IRQF_SHARED, DRV_NAME, host);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
host->irq = pdev->irq;
|
||||
|
||||
ata_port_desc(host->ports[0], "irq %d", pdev->irq);
|
||||
ata_port_desc(host->ports[1], "irq %d", pdev->irq);
|
||||
} else {
|
||||
if (!ata_port_is_dummy(host->ports[0])) {
|
||||
host->irq = ATA_PRIMARY_IRQ(pdev);
|
||||
rc = devm_request_irq(dev, host->irq,
|
||||
rc = devm_request_irq(dev, ATA_PRIMARY_IRQ(pdev),
|
||||
pi->port_ops->irq_handler,
|
||||
IRQF_SHARED, DRV_NAME, host);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
ata_port_desc(host->ports[0], "irq %d",
|
||||
ATA_PRIMARY_IRQ(pdev));
|
||||
}
|
||||
|
||||
if (!ata_port_is_dummy(host->ports[1])) {
|
||||
host->irq2 = ATA_SECONDARY_IRQ(pdev);
|
||||
rc = devm_request_irq(dev, host->irq2,
|
||||
rc = devm_request_irq(dev, ATA_SECONDARY_IRQ(pdev),
|
||||
pi->port_ops->irq_handler,
|
||||
IRQF_SHARED, DRV_NAME, host);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
ata_port_desc(host->ports[1], "irq %d",
|
||||
ATA_SECONDARY_IRQ(pdev));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -909,7 +882,7 @@ unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer
|
|||
/* Filter out DMA modes if the device has been configured by
|
||||
the BIOS as PIO only */
|
||||
|
||||
if (adev->ap->ioaddr.bmdma_addr == 0)
|
||||
if (adev->link->ap->ioaddr.bmdma_addr == 0)
|
||||
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
|
||||
return xfer_mask;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define __LIBATA_H__
|
||||
|
||||
#define DRV_NAME "libata"
|
||||
#define DRV_VERSION "3.00" /* must be exactly four chars */
|
||||
|
||||
struct ata_scsi_args {
|
||||
struct ata_device *dev;
|
||||
|
@ -56,6 +57,7 @@ extern unsigned int ata_print_id;
|
|||
extern struct workqueue_struct *ata_aux_wq;
|
||||
extern int atapi_enabled;
|
||||
extern int atapi_dmadir;
|
||||
extern int atapi_passthru16;
|
||||
extern int libata_fua;
|
||||
extern int libata_noacpi;
|
||||
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
|
||||
|
@ -67,21 +69,23 @@ extern void ata_dev_disable(struct ata_device *dev);
|
|||
extern void ata_port_flush_task(struct ata_port *ap);
|
||||
extern unsigned ata_exec_internal(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, const u8 *cdb,
|
||||
int dma_dir, void *buf, unsigned int buflen);
|
||||
int dma_dir, void *buf, unsigned int buflen,
|
||||
unsigned long timeout);
|
||||
extern unsigned ata_exec_internal_sg(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, const u8 *cdb,
|
||||
int dma_dir, struct scatterlist *sg,
|
||||
unsigned int n_elem);
|
||||
unsigned int n_elem, unsigned long timeout);
|
||||
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
|
||||
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
unsigned int flags, u16 *id);
|
||||
extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
|
||||
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags);
|
||||
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
|
||||
unsigned int readid_flags);
|
||||
extern int ata_dev_configure(struct ata_device *dev);
|
||||
extern int sata_down_spd_limit(struct ata_port *ap);
|
||||
extern int sata_set_spd_needed(struct ata_port *ap);
|
||||
extern int sata_down_spd_limit(struct ata_link *link);
|
||||
extern int sata_set_spd_needed(struct ata_link *link);
|
||||
extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
|
||||
extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
|
||||
extern int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
|
||||
extern void ata_sg_clean(struct ata_queued_cmd *qc);
|
||||
extern void ata_qc_free(struct ata_queued_cmd *qc);
|
||||
extern void ata_qc_issue(struct ata_queued_cmd *qc);
|
||||
|
@ -92,17 +96,21 @@ extern void ata_dev_select(struct ata_port *ap, unsigned int device,
|
|||
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
|
||||
extern int ata_flush_cache(struct ata_device *dev);
|
||||
extern void ata_dev_init(struct ata_device *dev);
|
||||
extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
|
||||
extern int sata_link_init_spd(struct ata_link *link);
|
||||
extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
|
||||
extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
|
||||
extern struct ata_port *ata_port_alloc(struct ata_host *host);
|
||||
|
||||
/* libata-acpi.c */
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
extern void ata_acpi_associate_sata_port(struct ata_port *ap);
|
||||
extern void ata_acpi_associate(struct ata_host *host);
|
||||
extern int ata_acpi_on_suspend(struct ata_port *ap);
|
||||
extern void ata_acpi_on_resume(struct ata_port *ap);
|
||||
extern int ata_acpi_on_devcfg(struct ata_device *adev);
|
||||
#else
|
||||
static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { }
|
||||
static inline void ata_acpi_associate(struct ata_host *host) { }
|
||||
static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
|
||||
static inline void ata_acpi_on_resume(struct ata_port *ap) { }
|
||||
|
@ -114,6 +122,7 @@ extern int ata_scsi_add_hosts(struct ata_host *host,
|
|||
struct scsi_host_template *sht);
|
||||
extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
|
||||
extern int ata_scsi_offline_dev(struct ata_device *dev);
|
||||
extern void ata_scsi_media_change_notify(struct ata_device *dev);
|
||||
extern void ata_scsi_hotplug(struct work_struct *work);
|
||||
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
|
||||
unsigned int buflen);
|
||||
|
@ -147,12 +156,32 @@ extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
|
|||
extern void ata_scsi_dev_rescan(struct work_struct *work);
|
||||
extern int ata_bus_probe(struct ata_port *ap);
|
||||
|
||||
/* libata-pmp.c */
|
||||
extern int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val);
|
||||
extern int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val);
|
||||
extern int sata_pmp_attach(struct ata_device *dev);
|
||||
|
||||
/* libata-eh.c */
|
||||
extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
|
||||
extern void ata_scsi_error(struct Scsi_Host *host);
|
||||
extern void ata_port_wait_eh(struct ata_port *ap);
|
||||
extern void ata_eh_fastdrain_timerfn(unsigned long arg);
|
||||
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
|
||||
extern void ata_eh_detach_dev(struct ata_device *dev);
|
||||
extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
|
||||
unsigned int action);
|
||||
extern void ata_eh_done(struct ata_link *link, struct ata_device *dev,
|
||||
unsigned int action);
|
||||
extern void ata_eh_autopsy(struct ata_port *ap);
|
||||
extern void ata_eh_report(struct ata_port *ap);
|
||||
extern int ata_eh_reset(struct ata_link *link, int classify,
|
||||
ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
|
||||
ata_reset_fn_t hardreset, ata_postreset_fn_t postreset);
|
||||
extern int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
||||
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
|
||||
ata_postreset_fn_t postreset,
|
||||
struct ata_link **r_failed_disk);
|
||||
extern void ata_eh_finish(struct ata_port *ap);
|
||||
|
||||
/* libata-sff.c */
|
||||
extern u8 ata_irq_on(struct ata_port *ap);
|
||||
|
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* ACPI PATA driver
|
||||
*
|
||||
* (c) 2007 Red Hat <alan@redhat.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <acpi/acnames.h>
|
||||
#include <acpi/acnamesp.h>
|
||||
#include <acpi/acparser.h>
|
||||
#include <acpi/acexcep.h>
|
||||
#include <acpi/acmacros.h>
|
||||
#include <acpi/actypes.h>
|
||||
|
||||
#include <linux/libata.h>
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_acpi"
|
||||
#define DRV_VERSION "0.2.3"
|
||||
|
||||
struct pata_acpi {
|
||||
struct ata_acpi_gtm gtm;
|
||||
void *last;
|
||||
unsigned long mask[2];
|
||||
};
|
||||
|
||||
/**
|
||||
* pacpi_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the PATA port setup we need.
|
||||
*/
|
||||
|
||||
static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pata_acpi *acpi = ap->private_data;
|
||||
if (ap->acpi_handle == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
* pacpi_cable_detect - cable type detection
|
||||
* @ap: port to detect
|
||||
*
|
||||
* Perform device specific cable detection
|
||||
*/
|
||||
|
||||
static int pacpi_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pata_acpi *acpi = ap->private_data;
|
||||
|
||||
if ((acpi->mask[0] | acpi->mask[1]) & (0xF8 << ATA_SHIFT_UDMA))
|
||||
return ATA_CBL_PATA80;
|
||||
else
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
* pacpi_error_handler - Setup and error handler
|
||||
* @ap: Port to handle
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void pacpi_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset,
|
||||
NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/* Welcome to ACPI, bring a bucket */
|
||||
static const unsigned int pio_cycle[7] = {
|
||||
600, 383, 240, 180, 120, 100, 80
|
||||
};
|
||||
static const unsigned int mwdma_cycle[5] = {
|
||||
480, 150, 120, 100, 80
|
||||
};
|
||||
static const unsigned int udma_cycle[7] = {
|
||||
120, 80, 60, 45, 30, 20, 15
|
||||
};
|
||||
|
||||
/**
|
||||
* pacpi_discover_modes - filter non ACPI modes
|
||||
* @adev: ATA device
|
||||
* @mask: proposed modes
|
||||
*
|
||||
* Try the modes available and see which ones the ACPI method will
|
||||
* set up sensibly. From this we get a mask of ACPI modes we can use
|
||||
*/
|
||||
|
||||
static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
int unit = adev->devno;
|
||||
struct pata_acpi *acpi = ap->private_data;
|
||||
int i;
|
||||
u32 t;
|
||||
unsigned long mask = (0x7f << ATA_SHIFT_UDMA) | (0x7 << ATA_SHIFT_MWDMA) | (0x1F << ATA_SHIFT_PIO);
|
||||
|
||||
struct ata_acpi_gtm probe;
|
||||
|
||||
probe = acpi->gtm;
|
||||
|
||||
/* We always use the 0 slot for crap hardware */
|
||||
if (!(probe.flags & 0x10))
|
||||
unit = 0;
|
||||
|
||||
ata_acpi_gtm(ap, &probe);
|
||||
|
||||
/* Start by scanning for PIO modes */
|
||||
for (i = 0; i < 7; i++) {
|
||||
t = probe.drive[unit].pio;
|
||||
if (t <= pio_cycle[i]) {
|
||||
mask |= (2 << (ATA_SHIFT_PIO + i)) - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* See if we have MWDMA or UDMA data. We don't bother with MWDMA
|
||||
if UDMA is availabe as this means the BIOS set UDMA and our
|
||||
error changedown if it works is UDMA to PIO anyway */
|
||||
if (probe.flags & (1 << (2 * unit))) {
|
||||
/* MWDMA */
|
||||
for (i = 0; i < 5; i++) {
|
||||
t = probe.drive[unit].dma;
|
||||
if (t <= mwdma_cycle[i]) {
|
||||
mask |= (2 << (ATA_SHIFT_MWDMA + i)) - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* UDMA */
|
||||
for (i = 0; i < 7; i++) {
|
||||
t = probe.drive[unit].dma;
|
||||
if (t <= udma_cycle[i]) {
|
||||
mask |= (2 << (ATA_SHIFT_UDMA + i)) - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mask & (0xF8 << ATA_SHIFT_UDMA))
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* pacpi_mode_filter - mode filter for ACPI
|
||||
* @adev: device
|
||||
* @mask: mask of valid modes
|
||||
*
|
||||
* Filter the valid mode list according to our own specific rules, in
|
||||
* this case the list of discovered valid modes obtained by ACPI probing
|
||||
*/
|
||||
|
||||
static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
struct pata_acpi *acpi = adev->link->ap->private_data;
|
||||
return ata_pci_default_filter(adev, mask & acpi->mask[adev->devno]);
|
||||
}
|
||||
|
||||
/**
|
||||
* pacpi_set_piomode - set initial PIO mode data
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*/
|
||||
|
||||
static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
int unit = adev->devno;
|
||||
struct pata_acpi *acpi = ap->private_data;
|
||||
|
||||
if(!(acpi->gtm.flags & 0x10))
|
||||
unit = 0;
|
||||
|
||||
/* Now stuff the nS values into the structure */
|
||||
acpi->gtm.drive[unit].pio = pio_cycle[adev->pio_mode - XFER_PIO_0];
|
||||
ata_acpi_stm(ap, &acpi->gtm);
|
||||
/* See what mode we actually got */
|
||||
ata_acpi_gtm(ap, &acpi->gtm);
|
||||
}
|
||||
|
||||
/**
|
||||
* pacpi_set_dmamode - set initial DMA mode data
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*/
|
||||
|
||||
static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
int unit = adev->devno;
|
||||
struct pata_acpi *acpi = ap->private_data;
|
||||
|
||||
if(!(acpi->gtm.flags & 0x10))
|
||||
unit = 0;
|
||||
|
||||
/* Now stuff the nS values into the structure */
|
||||
if (adev->dma_mode >= XFER_UDMA_0) {
|
||||
acpi->gtm.drive[unit].dma = udma_cycle[adev->dma_mode - XFER_UDMA_0];
|
||||
acpi->gtm.flags |= (1 << (2 * unit));
|
||||
} else {
|
||||
acpi->gtm.drive[unit].dma = mwdma_cycle[adev->dma_mode - XFER_MW_DMA_0];
|
||||
acpi->gtm.flags &= ~(1 << (2 * unit));
|
||||
}
|
||||
ata_acpi_stm(ap, &acpi->gtm);
|
||||
/* See what mode we actually got */
|
||||
ata_acpi_gtm(ap, &acpi->gtm);
|
||||
}
|
||||
|
||||
/**
|
||||
* pacpi_qc_issue_prot - command issue
|
||||
* @qc: command pending
|
||||
*
|
||||
* Called when the libata layer is about to issue a command. We wrap
|
||||
* this interface so that we can load the correct ATA timings if
|
||||
* neccessary.
|
||||
*/
|
||||
|
||||
static unsigned int pacpi_qc_issue_prot(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct ata_device *adev = qc->dev;
|
||||
struct pata_acpi *acpi = ap->private_data;
|
||||
|
||||
if (acpi->gtm.flags & 0x10)
|
||||
return ata_qc_issue_prot(qc);
|
||||
|
||||
if (adev != acpi->last) {
|
||||
pacpi_set_piomode(ap, adev);
|
||||
if (adev->dma_mode)
|
||||
pacpi_set_dmamode(ap, adev);
|
||||
acpi->last = adev;
|
||||
}
|
||||
return ata_qc_issue_prot(qc);
|
||||
}
|
||||
|
||||
/**
|
||||
* pacpi_port_start - port setup
|
||||
* @ap: ATA port being set up
|
||||
*
|
||||
* Use the port_start hook to maintain private control structures
|
||||
*/
|
||||
|
||||
static int pacpi_port_start(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct pata_acpi *acpi;
|
||||
|
||||
int ret;
|
||||
|
||||
if (ap->acpi_handle == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL);
|
||||
if (ap->private_data == NULL)
|
||||
return -ENOMEM;
|
||||
acpi->mask[0] = pacpi_discover_modes(ap, &ap->link.device[0]);
|
||||
acpi->mask[1] = pacpi_discover_modes(ap, &ap->link.device[1]);
|
||||
ret = ata_sff_port_start(ap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct scsi_host_template pacpi_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.ioctl = ata_scsi_ioctl,
|
||||
.queuecommand = ata_scsi_queuecmd,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
.proc_name = DRV_NAME,
|
||||
.dma_boundary = ATA_DMA_BOUNDARY,
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
/* Use standard CHS mapping rules */
|
||||
.bios_param = ata_std_bios_param,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations pacpi_ops = {
|
||||
.set_piomode = pacpi_set_piomode,
|
||||
.set_dmamode = pacpi_set_dmamode,
|
||||
.mode_filter = pacpi_mode_filter,
|
||||
|
||||
/* Task file is PCI ATA format, use helpers */
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
.exec_command = ata_exec_command,
|
||||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = pacpi_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = pacpi_cable_detect,
|
||||
|
||||
/* BMDMA handling is PCI ATA format, use helpers */
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
.bmdma_stop = ata_bmdma_stop,
|
||||
.bmdma_status = ata_bmdma_status,
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = pacpi_qc_issue_prot,
|
||||
.data_xfer = ata_data_xfer,
|
||||
|
||||
/* Timeout handling */
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
|
||||
/* Generic PATA PCI ATA helpers */
|
||||
.port_start = pacpi_port_start,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* pacpi_init_one - Register ACPI ATA PCI device with kernel services
|
||||
* @pdev: PCI device to register
|
||||
* @ent: Entry in pacpi_pci_tbl matching with @pdev
|
||||
*
|
||||
* Called from kernel PCI layer.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from PCI layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, or -ERRNO value.
|
||||
*/
|
||||
|
||||
static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
static const struct ata_port_info info = {
|
||||
.sht = &pacpi_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
|
||||
.port_ops = &pacpi_ops,
|
||||
};
|
||||
const struct ata_port_info *ppi[] = { &info, NULL };
|
||||
return ata_pci_init_one(pdev, ppi);
|
||||
}
|
||||
|
||||
static const struct pci_device_id pacpi_pci_tbl[] = {
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1},
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
static struct pci_driver pacpi_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = pacpi_pci_tbl,
|
||||
.probe = pacpi_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init pacpi_init(void)
|
||||
{
|
||||
return pci_register_driver(&pacpi_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit pacpi_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&pacpi_pci_driver);
|
||||
}
|
||||
|
||||
module_init(pacpi_init);
|
||||
module_exit(pacpi_exit);
|
||||
|
||||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_DESCRIPTION("SCSI low-level driver for ATA in ACPI mode");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(pci, pacpi_pci_tbl);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
|
@ -305,7 +305,6 @@ static struct scsi_host_template ali_sht = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations ali_early_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = ali_set_piomode,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -327,9 +326,8 @@ static struct ata_port_operations ali_early_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -337,8 +335,6 @@ static struct ata_port_operations ali_early_port_ops = {
|
|||
* detect
|
||||
*/
|
||||
static struct ata_port_operations ali_20_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.set_piomode = ali_set_piomode,
|
||||
.set_dmamode = ali_set_dmamode,
|
||||
.mode_filter = ali_20_filter,
|
||||
|
@ -369,16 +365,14 @@ static struct ata_port_operations ali_20_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/*
|
||||
* Port operations for DMA capable ALi with cable detect
|
||||
*/
|
||||
static struct ata_port_operations ali_c2_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = ali_set_piomode,
|
||||
.set_dmamode = ali_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -408,16 +402,14 @@ static struct ata_port_operations ali_c2_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/*
|
||||
* Port operations for DMA capable ALi with cable detect and LBA48
|
||||
*/
|
||||
static struct ata_port_operations ali_c5_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = ali_set_piomode,
|
||||
.set_dmamode = ali_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -446,9 +438,8 @@ static struct ata_port_operations ali_c5_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -119,27 +119,28 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
|
|||
}
|
||||
|
||||
/**
|
||||
* amd_probe_init - perform reset handling
|
||||
* @ap: ATA port
|
||||
* amd_pre_reset - perform reset handling
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Reset sequence checking enable bits to see which ports are
|
||||
* active.
|
||||
*/
|
||||
|
||||
static int amd_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits amd_enable_bits[] = {
|
||||
{ 0x40, 1, 0x02, 0x02 },
|
||||
{ 0x40, 1, 0x01, 0x01 }
|
||||
};
|
||||
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static void amd_error_handler(struct ata_port *ap)
|
||||
|
@ -221,25 +222,26 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
/**
|
||||
* nv_probe_init - cable detection
|
||||
* @ap: ATA port
|
||||
* @lin: ATA link
|
||||
*
|
||||
* Perform cable detection. The BIOS stores this in PCI config
|
||||
* space for us.
|
||||
*/
|
||||
|
||||
static int nv_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int nv_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits nv_enable_bits[] = {
|
||||
{ 0x50, 1, 0x02, 0x02 },
|
||||
{ 0x50, 1, 0x01, 0x01 }
|
||||
};
|
||||
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static void nv_error_handler(struct ata_port *ap)
|
||||
|
@ -268,6 +270,9 @@ static int nv_cable_detect(struct ata_port *ap)
|
|||
pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
|
||||
if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
|
||||
cbl = ATA_CBL_PATA80;
|
||||
/* And a triple check across suspend/resume with ACPI around */
|
||||
if (ata_acpi_cbl_80wire(ap))
|
||||
cbl = ATA_CBL_PATA80;
|
||||
return cbl;
|
||||
}
|
||||
|
||||
|
@ -327,7 +332,6 @@ static struct scsi_host_template amd_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations amd33_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = amd33_set_piomode,
|
||||
.set_dmamode = amd33_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -356,13 +360,11 @@ static struct ata_port_operations amd33_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations amd66_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = amd66_set_piomode,
|
||||
.set_dmamode = amd66_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -391,13 +393,11 @@ static struct ata_port_operations amd66_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations amd100_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = amd100_set_piomode,
|
||||
.set_dmamode = amd100_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -426,13 +426,11 @@ static struct ata_port_operations amd100_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations amd133_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = amd133_set_piomode,
|
||||
.set_dmamode = amd133_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -461,13 +459,11 @@ static struct ata_port_operations amd133_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations nv100_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = nv100_set_piomode,
|
||||
.set_dmamode = nv100_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -496,13 +492,11 @@ static struct ata_port_operations nv100_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations nv133_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = nv133_set_piomode,
|
||||
.set_dmamode = nv133_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -531,9 +525,8 @@ static struct ata_port_operations nv133_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
|
|
@ -40,8 +40,9 @@
|
|||
|
||||
static int clock = 0;
|
||||
|
||||
static int artop6210_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int artop6210_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
const struct pci_bits artop_enable_bits[] = {
|
||||
{ 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
|
@ -51,7 +52,7 @@ static int artop6210_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,27 +72,28 @@ static void artop6210_error_handler(struct ata_port *ap)
|
|||
|
||||
/**
|
||||
* artop6260_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @link: link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* The ARTOP hardware reports the cable detect bits in register 0x49.
|
||||
* Nothing complicated needed here.
|
||||
*/
|
||||
|
||||
static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int artop6260_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits artop_enable_bits[] = {
|
||||
{ 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
{ 0x4AU, 1U, 0x04UL, 0x04UL }, /* port 1 */
|
||||
};
|
||||
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
/* Odd numbered device ids are the units with enable bits (the -R cards) */
|
||||
if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -330,7 +332,6 @@ static struct scsi_host_template artop_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations artop6210_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = artop6210_set_piomode,
|
||||
.set_dmamode = artop6210_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -359,13 +360,11 @@ static const struct ata_port_operations artop6210_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations artop6260_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = artop6260_set_piomode,
|
||||
.set_dmamode = artop6260_set_dmamode,
|
||||
|
||||
|
@ -392,9 +391,8 @@ static const struct ata_port_operations artop6260_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
* AVR32 SMC/CFC PATA Driver
|
||||
*
|
||||
* Copyright (C) 2007 Atmel Norway
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/ata.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/smc.h>
|
||||
|
||||
#define DRV_NAME "pata_at32"
|
||||
#define DRV_VERSION "0.0.2"
|
||||
|
||||
/*
|
||||
* CompactFlash controller memory layout relative to the base address:
|
||||
*
|
||||
* Attribute memory: 0000 0000 -> 003f ffff
|
||||
* Common memory: 0040 0000 -> 007f ffff
|
||||
* I/O memory: 0080 0000 -> 00bf ffff
|
||||
* True IDE Mode: 00c0 0000 -> 00df ffff
|
||||
* Alt IDE Mode: 00e0 0000 -> 00ff ffff
|
||||
*
|
||||
* Only True IDE and Alt True IDE mode are needed for this driver.
|
||||
*
|
||||
* True IDE mode => CS0 = 0, CS1 = 1 (cmd, error, stat, etc)
|
||||
* Alt True IDE mode => CS0 = 1, CS1 = 0 (ctl, alt_stat)
|
||||
*/
|
||||
#define CF_IDE_OFFSET 0x00c00000
|
||||
#define CF_ALT_IDE_OFFSET 0x00e00000
|
||||
#define CF_RES_SIZE 2048
|
||||
|
||||
/*
|
||||
* Define DEBUG_BUS if you are doing debugging of your own EBI -> PATA
|
||||
* adaptor with a logic analyzer or similar.
|
||||
*/
|
||||
#undef DEBUG_BUS
|
||||
|
||||
/*
|
||||
* ATA PIO modes
|
||||
*
|
||||
* Name | Mb/s | Min cycle time | Mask
|
||||
* --------+-------+----------------+--------
|
||||
* Mode 0 | 3.3 | 600 ns | 0x01
|
||||
* Mode 1 | 5.2 | 383 ns | 0x03
|
||||
* Mode 2 | 8.3 | 240 ns | 0x07
|
||||
* Mode 3 | 11.1 | 180 ns | 0x0f
|
||||
* Mode 4 | 16.7 | 120 ns | 0x1f
|
||||
*/
|
||||
#define PIO_MASK (0x1f)
|
||||
|
||||
/*
|
||||
* Struct containing private information about device.
|
||||
*/
|
||||
struct at32_ide_info {
|
||||
unsigned int irq;
|
||||
struct resource res_ide;
|
||||
struct resource res_alt;
|
||||
void __iomem *ide_addr;
|
||||
void __iomem *alt_addr;
|
||||
unsigned int cs;
|
||||
struct smc_config smc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Setup SMC for the given ATA timing.
|
||||
*/
|
||||
static int pata_at32_setup_timing(struct device *dev,
|
||||
struct at32_ide_info *info,
|
||||
const struct ata_timing *timing)
|
||||
{
|
||||
/* These two values are found through testing */
|
||||
const int min_recover = 25;
|
||||
const int ncs_hold = 15;
|
||||
|
||||
struct smc_config *smc = &info->smc;
|
||||
|
||||
int active;
|
||||
int recover;
|
||||
|
||||
/* Total cycle time */
|
||||
smc->read_cycle = timing->cyc8b;
|
||||
|
||||
/* DIOR <= CFIOR timings */
|
||||
smc->nrd_setup = timing->setup;
|
||||
smc->nrd_pulse = timing->act8b;
|
||||
|
||||
/* Compute recover, extend total cycle if needed */
|
||||
active = smc->nrd_setup + smc->nrd_pulse;
|
||||
recover = smc->read_cycle - active;
|
||||
|
||||
if (recover < min_recover) {
|
||||
smc->read_cycle = active + min_recover;
|
||||
recover = min_recover;
|
||||
}
|
||||
|
||||
/* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */
|
||||
smc->ncs_read_setup = 0;
|
||||
smc->ncs_read_pulse = active + ncs_hold;
|
||||
|
||||
/* Write timings same as read timings */
|
||||
smc->write_cycle = smc->read_cycle;
|
||||
smc->nwe_setup = smc->nrd_setup;
|
||||
smc->nwe_pulse = smc->nrd_pulse;
|
||||
smc->ncs_write_setup = smc->ncs_read_setup;
|
||||
smc->ncs_write_pulse = smc->ncs_read_pulse;
|
||||
|
||||
/* Do some debugging output */
|
||||
dev_dbg(dev, "SMC: C=%d S=%d P=%d R=%d NCSS=%d NCSP=%d NCSR=%d\n",
|
||||
smc->read_cycle, smc->nrd_setup, smc->nrd_pulse,
|
||||
recover, smc->ncs_read_setup, smc->ncs_read_pulse,
|
||||
smc->read_cycle - smc->ncs_read_pulse);
|
||||
|
||||
/* Finally, configure the SMC */
|
||||
return smc_set_configuration(info->cs, smc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Procedures for libATA.
|
||||
*/
|
||||
static void pata_at32_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
struct ata_timing timing;
|
||||
struct at32_ide_info *info = ap->host->private_data;
|
||||
|
||||
int ret;
|
||||
|
||||
/* Compute ATA timing */
|
||||
ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0);
|
||||
if (ret) {
|
||||
dev_warn(ap->dev, "Failed to compute ATA timing %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup SMC to ATA timing */
|
||||
ret = pata_at32_setup_timing(ap->dev, info, &timing);
|
||||
if (ret) {
|
||||
dev_warn(ap->dev, "Failed to setup ATA timing %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void pata_at32_irq_clear(struct ata_port *ap)
|
||||
{
|
||||
/* No DMA controller yet */
|
||||
}
|
||||
|
||||
static struct scsi_host_template at32_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.ioctl = ata_scsi_ioctl,
|
||||
.queuecommand = ata_scsi_queuecmd,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
.proc_name = DRV_NAME,
|
||||
.dma_boundary = ATA_DMA_BOUNDARY,
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
};
|
||||
|
||||
static struct ata_port_operations at32_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = pata_at32_set_piomode,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.exec_command = ata_exec_command,
|
||||
.check_status = ata_check_status,
|
||||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
||||
.data_xfer = ata_data_xfer,
|
||||
|
||||
.irq_clear = pata_at32_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int __init pata_at32_init_one(struct device *dev,
|
||||
struct at32_ide_info *info)
|
||||
{
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
|
||||
host = ata_host_alloc(dev, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
ap = host->ports[0];
|
||||
|
||||
/* Setup ATA bindings */
|
||||
ap->ops = &at32_port_ops;
|
||||
ap->pio_mask = PIO_MASK;
|
||||
ap->flags = ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS
|
||||
| ATA_FLAG_PIO_POLLING;
|
||||
|
||||
/*
|
||||
* Since all 8-bit taskfile transfers has to go on the lower
|
||||
* byte of the data bus and there is a bug in the SMC that
|
||||
* makes it impossible to alter the bus width during runtime,
|
||||
* we need to hardwire the address signals as follows:
|
||||
*
|
||||
* A_IDE(2:0) <= A_EBI(3:1)
|
||||
*
|
||||
* This makes all addresses on the EBI even, thus all data
|
||||
* will be on the lower byte of the data bus. All addresses
|
||||
* used by libATA need to be altered according to this.
|
||||
*/
|
||||
ap->ioaddr.altstatus_addr = info->alt_addr + (0x06 << 1);
|
||||
ap->ioaddr.ctl_addr = info->alt_addr + (0x06 << 1);
|
||||
|
||||
ap->ioaddr.data_addr = info->ide_addr + (ATA_REG_DATA << 1);
|
||||
ap->ioaddr.error_addr = info->ide_addr + (ATA_REG_ERR << 1);
|
||||
ap->ioaddr.feature_addr = info->ide_addr + (ATA_REG_FEATURE << 1);
|
||||
ap->ioaddr.nsect_addr = info->ide_addr + (ATA_REG_NSECT << 1);
|
||||
ap->ioaddr.lbal_addr = info->ide_addr + (ATA_REG_LBAL << 1);
|
||||
ap->ioaddr.lbam_addr = info->ide_addr + (ATA_REG_LBAM << 1);
|
||||
ap->ioaddr.lbah_addr = info->ide_addr + (ATA_REG_LBAH << 1);
|
||||
ap->ioaddr.device_addr = info->ide_addr + (ATA_REG_DEVICE << 1);
|
||||
ap->ioaddr.status_addr = info->ide_addr + (ATA_REG_STATUS << 1);
|
||||
ap->ioaddr.command_addr = info->ide_addr + (ATA_REG_CMD << 1);
|
||||
|
||||
/* Set info as private data of ATA host */
|
||||
host->private_data = info;
|
||||
|
||||
/* Register ATA device and return */
|
||||
return ata_host_activate(host, info->irq, ata_interrupt,
|
||||
IRQF_SHARED | IRQF_TRIGGER_RISING,
|
||||
&at32_sht);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function may come in handy for people analyzing their own
|
||||
* EBI -> PATA adaptors.
|
||||
*/
|
||||
#ifdef DEBUG_BUS
|
||||
|
||||
static void __init pata_at32_debug_bus(struct device *dev,
|
||||
struct at32_ide_info *info)
|
||||
{
|
||||
const int d1 = 0xff;
|
||||
const int d2 = 0x00;
|
||||
|
||||
int i;
|
||||
|
||||
/* Write 8-bit values (registers) */
|
||||
iowrite8(d1, info->alt_addr + (0x06 << 1));
|
||||
iowrite8(d2, info->alt_addr + (0x06 << 1));
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
iowrite8(d1, info->ide_addr + (i << 1));
|
||||
iowrite8(d2, info->ide_addr + (i << 1));
|
||||
}
|
||||
|
||||
/* Write 16 bit values (data) */
|
||||
iowrite16(d1, info->ide_addr);
|
||||
iowrite16(d1 << 8, info->ide_addr);
|
||||
|
||||
iowrite16(d1, info->ide_addr);
|
||||
iowrite16(d1 << 8, info->ide_addr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int __init pata_at32_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct ata_timing initial_timing =
|
||||
{XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0};
|
||||
|
||||
struct device *dev = &pdev->dev;
|
||||
struct at32_ide_info *info;
|
||||
struct ide_platform_data *board = pdev->dev.platform_data;
|
||||
struct resource *res;
|
||||
|
||||
int irq;
|
||||
int ret;
|
||||
|
||||
if (!board)
|
||||
return -ENXIO;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
|
||||
/* Retrive IRQ */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
/* Setup struct containing private infomation */
|
||||
info = kzalloc(sizeof(struct at32_ide_info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(info, 0, sizeof(struct at32_ide_info));
|
||||
|
||||
info->irq = irq;
|
||||
info->cs = board->cs;
|
||||
|
||||
/* Request memory resources */
|
||||
info->res_ide.start = res->start + CF_IDE_OFFSET;
|
||||
info->res_ide.end = info->res_ide.start + CF_RES_SIZE - 1;
|
||||
info->res_ide.name = "ide";
|
||||
info->res_ide.flags = IORESOURCE_MEM;
|
||||
|
||||
ret = request_resource(res, &info->res_ide);
|
||||
if (ret)
|
||||
goto err_req_res_ide;
|
||||
|
||||
info->res_alt.start = res->start + CF_ALT_IDE_OFFSET;
|
||||
info->res_alt.end = info->res_alt.start + CF_RES_SIZE - 1;
|
||||
info->res_alt.name = "alt";
|
||||
info->res_alt.flags = IORESOURCE_MEM;
|
||||
|
||||
ret = request_resource(res, &info->res_alt);
|
||||
if (ret)
|
||||
goto err_req_res_alt;
|
||||
|
||||
/* Setup non-timing elements of SMC */
|
||||
info->smc.bus_width = 2; /* 16 bit data bus */
|
||||
info->smc.nrd_controlled = 1; /* Sample data on rising edge of NRD */
|
||||
info->smc.nwe_controlled = 0; /* Drive data on falling edge of NCS */
|
||||
info->smc.nwait_mode = 3; /* NWAIT is in READY mode */
|
||||
info->smc.byte_write = 0; /* Byte select access type */
|
||||
info->smc.tdf_mode = 0; /* TDF optimization disabled */
|
||||
info->smc.tdf_cycles = 0; /* No TDF wait cycles */
|
||||
|
||||
/* Setup ATA timing */
|
||||
ret = pata_at32_setup_timing(dev, info, &initial_timing);
|
||||
if (ret)
|
||||
goto err_setup_timing;
|
||||
|
||||
/* Setup ATA addresses */
|
||||
ret = -ENOMEM;
|
||||
info->ide_addr = devm_ioremap(dev, info->res_ide.start, 16);
|
||||
info->alt_addr = devm_ioremap(dev, info->res_alt.start, 16);
|
||||
if (!info->ide_addr || !info->alt_addr)
|
||||
goto err_ioremap;
|
||||
|
||||
#ifdef DEBUG_BUS
|
||||
pata_at32_debug_bus(dev, info);
|
||||
#endif
|
||||
|
||||
/* Register ATA device */
|
||||
ret = pata_at32_init_one(dev, info);
|
||||
if (ret)
|
||||
goto err_ata_device;
|
||||
|
||||
return 0;
|
||||
|
||||
err_ata_device:
|
||||
err_ioremap:
|
||||
err_setup_timing:
|
||||
release_resource(&info->res_alt);
|
||||
err_req_res_alt:
|
||||
release_resource(&info->res_ide);
|
||||
err_req_res_ide:
|
||||
kfree(info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __exit pata_at32_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ata_host *host = platform_get_drvdata(pdev);
|
||||
struct at32_ide_info *info;
|
||||
|
||||
if (!host)
|
||||
return 0;
|
||||
|
||||
info = host->private_data;
|
||||
ata_host_detach(host);
|
||||
|
||||
if (!info)
|
||||
return 0;
|
||||
|
||||
release_resource(&info->res_ide);
|
||||
release_resource(&info->res_alt);
|
||||
|
||||
kfree(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pata_at32_driver = {
|
||||
.remove = __exit_p(pata_at32_remove),
|
||||
.driver = {
|
||||
.name = "at32_ide",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init pata_at32_init(void)
|
||||
{
|
||||
return platform_driver_probe(&pata_at32_driver, pata_at32_probe);
|
||||
}
|
||||
|
||||
static void __exit pata_at32_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&pata_at32_driver);
|
||||
}
|
||||
|
||||
module_init(pata_at32_init);
|
||||
module_exit(pata_at32_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("AVR32 SMC/CFC PATA Driver");
|
||||
MODULE_AUTHOR("Kristoffer Nyborg Gregertsen <kngregertsen@norway.atmel.com>");
|
||||
MODULE_VERSION(DRV_VERSION);
|
|
@ -33,8 +33,9 @@ enum {
|
|||
ATIIXP_IDE_UDMA_MODE = 0x56
|
||||
};
|
||||
|
||||
static int atiixp_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int atiixp_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
static const struct pci_bits atiixp_enable_bits[] = {
|
||||
{ 0x48, 1, 0x01, 0x00 },
|
||||
{ 0x48, 1, 0x08, 0x00 }
|
||||
|
@ -44,7 +45,7 @@ static int atiixp_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static void atiixp_error_handler(struct ata_port *ap)
|
||||
|
@ -172,6 +173,9 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
*
|
||||
* When DMA begins we need to ensure that the UDMA control
|
||||
* register for the channel is correctly set.
|
||||
*
|
||||
* Note: The host lock held by the libata layer protects
|
||||
* us from two channels both trying to set DMA bits at once
|
||||
*/
|
||||
|
||||
static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
|
||||
|
@ -198,6 +202,9 @@ static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
|
|||
*
|
||||
* DMA has completed. Clear the UDMA flag as the next operations will
|
||||
* be PIO ones not UDMA data transfer.
|
||||
*
|
||||
* Note: The host lock held by the libata layer protects
|
||||
* us from two channels both trying to set DMA bits at once
|
||||
*/
|
||||
|
||||
static void atiixp_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
|
@ -232,7 +239,6 @@ static struct scsi_host_template atiixp_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations atiixp_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = atiixp_set_piomode,
|
||||
.set_dmamode = atiixp_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -261,9 +267,8 @@ static struct ata_port_operations atiixp_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -153,7 +153,7 @@ static int cmd640_port_start(struct ata_port *ap)
|
|||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct cmd640_reg *timing;
|
||||
|
||||
int ret = ata_port_start(ap);
|
||||
int ret = ata_sff_port_start(ap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -184,7 +184,6 @@ static struct scsi_host_template cmd640_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations cmd640_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cmd640_set_piomode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -213,7 +212,6 @@ static struct ata_port_operations cmd640_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = cmd640_port_start,
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_cmd64x"
|
||||
#define DRV_VERSION "0.2.4"
|
||||
#define DRV_VERSION "0.2.5"
|
||||
|
||||
/*
|
||||
* CMD64x specific registers definition.
|
||||
|
@ -88,14 +88,15 @@ static int cmd648_cable_detect(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/**
|
||||
* cmd64x_set_piomode - set initial PIO mode data
|
||||
* cmd64x_set_piomode - set PIO and MWDMA timing
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
* @mode: mode
|
||||
*
|
||||
* Called to do the PIO mode setup.
|
||||
* Called to do the PIO and MWDMA mode setup.
|
||||
*/
|
||||
|
||||
static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 mode)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct ata_timing t;
|
||||
|
@ -117,8 +118,9 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
int arttim = arttim_port[ap->port_no][adev->devno];
|
||||
int drwtim = drwtim_port[ap->port_no][adev->devno];
|
||||
|
||||
|
||||
if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) {
|
||||
/* ata_timing_compute is smart and will produce timings for MWDMA
|
||||
that don't violate the drives PIO capabilities. */
|
||||
if (ata_timing_compute(adev, mode, &t, T, 0) < 0) {
|
||||
printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -167,6 +169,20 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
pci_write_config_byte(pdev, drwtim, (t.active << 4) | t.recover);
|
||||
}
|
||||
|
||||
/**
|
||||
* cmd64x_set_piomode - set initial PIO mode data
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*
|
||||
* Used when configuring the devices ot set the PIO timings. All the
|
||||
* actual work is done by the PIO/MWDMA setting helper
|
||||
*/
|
||||
|
||||
static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
cmd64x_set_timing(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* cmd64x_set_dmamode - set initial DMA mode data
|
||||
* @ap: ATA interface
|
||||
|
@ -180,9 +196,6 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
static const u8 udma_data[] = {
|
||||
0x30, 0x20, 0x10, 0x20, 0x10, 0x00
|
||||
};
|
||||
static const u8 mwdma_data[] = {
|
||||
0x30, 0x20, 0x10
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 regU, regD;
|
||||
|
@ -208,8 +221,10 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
regU |= 1 << adev->devno; /* UDMA on */
|
||||
if (adev->dma_mode > 2) /* 15nS timing */
|
||||
regU |= 4 << adev->devno;
|
||||
} else
|
||||
regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift;
|
||||
} else {
|
||||
regU &= ~ (1 << adev->devno); /* UDMA off */
|
||||
cmd64x_set_timing(ap, adev, adev->dma_mode);
|
||||
}
|
||||
|
||||
regD |= 0x20 << adev->devno;
|
||||
|
||||
|
@ -269,7 +284,6 @@ static struct scsi_host_template cmd64x_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations cmd64x_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cmd64x_set_piomode,
|
||||
.set_dmamode = cmd64x_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -298,13 +312,11 @@ static struct ata_port_operations cmd64x_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cmd646r1_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cmd64x_set_piomode,
|
||||
.set_dmamode = cmd64x_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -333,13 +345,11 @@ static struct ata_port_operations cmd646r1_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cmd648_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cmd64x_set_piomode,
|
||||
.set_dmamode = cmd64x_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -368,7 +378,6 @@ static struct ata_port_operations cmd648_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
|
|
@ -158,7 +158,6 @@ static struct scsi_host_template cs5520_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations cs5520_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cs5520_set_piomode,
|
||||
.set_dmamode = cs5520_set_dmamode,
|
||||
|
||||
|
@ -184,13 +183,14 @@ static struct ata_port_operations cs5520_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
static const unsigned int cmd_port[] = { 0x1F0, 0x170 };
|
||||
static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
|
||||
struct ata_port_info pi = {
|
||||
.flags = ATA_FLAG_SLAVE_POSS,
|
||||
.pio_mask = 0x1f,
|
||||
|
@ -244,10 +244,10 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
|
|||
}
|
||||
|
||||
/* Map IO ports and initialize host accordingly */
|
||||
iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8);
|
||||
iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1);
|
||||
iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8);
|
||||
iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1);
|
||||
iomap[0] = devm_ioport_map(&pdev->dev, cmd_port[0], 8);
|
||||
iomap[1] = devm_ioport_map(&pdev->dev, ctl_port[0], 1);
|
||||
iomap[2] = devm_ioport_map(&pdev->dev, cmd_port[1], 8);
|
||||
iomap[3] = devm_ioport_map(&pdev->dev, ctl_port[1], 1);
|
||||
iomap[4] = pcim_iomap(pdev, 2, 0);
|
||||
|
||||
if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
|
||||
|
@ -260,6 +260,10 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
|
|||
ioaddr->bmdma_addr = iomap[4];
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
ata_port_desc(host->ports[0],
|
||||
"cmd 0x%x ctl 0x%x", cmd_port[0], ctl_port[0]);
|
||||
ata_port_pbar_desc(host->ports[0], 4, 0, "bmdma");
|
||||
|
||||
ioaddr = &host->ports[1]->ioaddr;
|
||||
ioaddr->cmd_addr = iomap[2];
|
||||
ioaddr->ctl_addr = iomap[3];
|
||||
|
@ -267,6 +271,10 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
|
|||
ioaddr->bmdma_addr = iomap[4] + 8;
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
ata_port_desc(host->ports[1],
|
||||
"cmd 0x%x ctl 0x%x", cmd_port[1], ctl_port[1]);
|
||||
ata_port_pbar_desc(host->ports[1], 4, 8, "bmdma");
|
||||
|
||||
/* activate the host */
|
||||
pci_set_master(pdev);
|
||||
rc = ata_host_start(host);
|
||||
|
@ -285,33 +293,12 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (i == 0)
|
||||
host->irq = irq[0];
|
||||
else
|
||||
host->irq2 = irq[1];
|
||||
ata_port_desc(ap, "irq %d", irq[i]);
|
||||
}
|
||||
|
||||
return ata_host_register(host, &cs5520_sht);
|
||||
}
|
||||
|
||||
/**
|
||||
* cs5520_remove_one - device unload
|
||||
* @pdev: PCI device being removed
|
||||
*
|
||||
* Handle an unplug/unload event for a PCI device. Unload the
|
||||
* PCI driver but do not use the default handler as we manage
|
||||
* resources ourself and *MUST NOT* disable the device as it has
|
||||
* other functions.
|
||||
*/
|
||||
|
||||
static void __devexit cs5520_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct device *dev = pci_dev_to_dev(pdev);
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
|
||||
ata_host_detach(host);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/**
|
||||
* cs5520_reinit_one - device resume
|
||||
|
@ -368,7 +355,7 @@ static struct pci_driver cs5520_pci_driver = {
|
|||
.name = DRV_NAME,
|
||||
.id_table = pata_cs5520,
|
||||
.probe = cs5520_init_one,
|
||||
.remove = cs5520_remove_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = cs5520_pci_device_suspend,
|
||||
.resume = cs5520_reinit_one,
|
||||
|
|
|
@ -179,7 +179,6 @@ static struct scsi_host_template cs5530_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations cs5530_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cs5530_set_piomode,
|
||||
.set_dmamode = cs5530_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -209,9 +208,8 @@ static struct ata_port_operations cs5530_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct dmi_system_id palmax_dmi_table[] = {
|
||||
|
|
|
@ -176,7 +176,6 @@ static struct scsi_host_template cs5535_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations cs5535_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cs5535_set_piomode,
|
||||
.set_dmamode = cs5535_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -206,9 +205,8 @@ static struct ata_port_operations cs5535_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -128,7 +128,6 @@ static struct scsi_host_template cy82c693_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations cy82c693_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cy82c693_set_piomode,
|
||||
.set_dmamode = cy82c693_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -158,9 +157,8 @@ static struct ata_port_operations cy82c693_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
|
|
@ -26,25 +26,26 @@
|
|||
|
||||
/**
|
||||
* efar_pre_reset - Enable bits
|
||||
* @ap: Port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection for the EFAR ATA interface. This is
|
||||
* different to the PIIX arrangement
|
||||
*/
|
||||
|
||||
static int efar_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int efar_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits efar_enable_bits[] = {
|
||||
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
|
||||
{ 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */
|
||||
};
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,7 +251,6 @@ static struct scsi_host_template efar_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations efar_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = efar_set_piomode,
|
||||
.set_dmamode = efar_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -278,9 +278,8 @@ static const struct ata_port_operations efar_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -312,7 +312,6 @@ static struct scsi_host_template hpt36x_sht = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations hpt366_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = hpt366_set_piomode,
|
||||
.set_dmamode = hpt366_set_dmamode,
|
||||
.mode_filter = hpt366_filter,
|
||||
|
@ -342,9 +341,8 @@ static struct ata_port_operations hpt366_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -304,15 +304,16 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
|
|||
|
||||
/**
|
||||
* hpt37x_pre_reset - reset the hpt37x bus
|
||||
* @ap: ATA port to reset
|
||||
* @link: ATA link to reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the initial reset handling for the 370/372 and 374 func 0
|
||||
*/
|
||||
|
||||
static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
u8 scr2, ata66;
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits hpt37x_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
|
@ -337,7 +338,7 @@ static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -352,7 +353,7 @@ static void hpt37x_error_handler(struct ata_port *ap)
|
|||
ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int hpt374_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits hpt37x_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
|
@ -360,6 +361,7 @@ static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
};
|
||||
u16 mcr3, mcr6;
|
||||
u8 ata66;
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
|
||||
|
@ -387,7 +389,7 @@ static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -642,7 +644,6 @@ static struct scsi_host_template hpt37x_sht = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations hpt370_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = hpt370_set_piomode,
|
||||
.set_dmamode = hpt370_set_dmamode,
|
||||
.mode_filter = hpt370_filter,
|
||||
|
@ -671,9 +672,8 @@ static struct ata_port_operations hpt370_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -681,7 +681,6 @@ static struct ata_port_operations hpt370_port_ops = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations hpt370a_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = hpt370_set_piomode,
|
||||
.set_dmamode = hpt370_set_dmamode,
|
||||
.mode_filter = hpt370a_filter,
|
||||
|
@ -710,9 +709,8 @@ static struct ata_port_operations hpt370a_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -721,7 +719,6 @@ static struct ata_port_operations hpt370a_port_ops = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations hpt372_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = hpt372_set_piomode,
|
||||
.set_dmamode = hpt372_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -750,9 +747,8 @@ static struct ata_port_operations hpt372_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -761,7 +757,6 @@ static struct ata_port_operations hpt372_port_ops = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations hpt374_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = hpt372_set_piomode,
|
||||
.set_dmamode = hpt372_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -790,9 +785,8 @@ static struct ata_port_operations hpt374_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -141,21 +141,22 @@ static int hpt3x2n_cable_detect(struct ata_port *ap)
|
|||
|
||||
/**
|
||||
* hpt3x2n_pre_reset - reset the hpt3x2n bus
|
||||
* @ap: ATA port to reset
|
||||
* @link: ATA link to reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the initial reset handling for the 3x2n series controllers.
|
||||
* Reset the hardware and state machine,
|
||||
*/
|
||||
|
||||
static int hpt3xn_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int hpt3xn_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
/* Reset the state machine */
|
||||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,7 +361,6 @@ static struct scsi_host_template hpt3x2n_sht = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations hpt3x2n_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = hpt3x2n_set_piomode,
|
||||
.set_dmamode = hpt3x2n_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -390,9 +390,8 @@ static struct ata_port_operations hpt3x2n_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -120,7 +120,6 @@ static struct scsi_host_template hpt3x3_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations hpt3x3_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = hpt3x3_set_piomode,
|
||||
#if defined(CONFIG_PATA_HPT3X3_DMA)
|
||||
.set_dmamode = hpt3x3_set_dmamode,
|
||||
|
@ -153,9 +152,8 @@ static struct ata_port_operations hpt3x3_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -239,7 +237,8 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
base = host->iomap[4]; /* Bus mastering base */
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
|
||||
struct ata_port *ap = host->ports[i];
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
ioaddr->cmd_addr = base + offset_cmd[i];
|
||||
ioaddr->altstatus_addr =
|
||||
|
@ -247,6 +246,9 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
ioaddr->scr_addr = NULL;
|
||||
ata_std_ports(ioaddr);
|
||||
ioaddr->bmdma_addr = base + 8 * i;
|
||||
|
||||
ata_port_pbar_desc(ap, 4, -1, "ioport");
|
||||
ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd");
|
||||
}
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
|
|
|
@ -70,6 +70,8 @@ struct pata_icside_info {
|
|||
unsigned int mwdma_mask;
|
||||
unsigned int nr_ports;
|
||||
const struct portinfo *port[2];
|
||||
unsigned long raw_base;
|
||||
unsigned long raw_ioc_base;
|
||||
};
|
||||
|
||||
#define ICS_TYPE_A3IN 0
|
||||
|
@ -357,26 +359,7 @@ static void pata_icside_error_handler(struct ata_port *ap)
|
|||
pata_icside_postreset);
|
||||
}
|
||||
|
||||
static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq)
|
||||
{
|
||||
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
|
||||
u8 status;
|
||||
|
||||
status = ata_busy_wait(ap, bits, 1000);
|
||||
if (status & bits)
|
||||
if (ata_msg_err(ap))
|
||||
printk(KERN_ERR "abnormal status 0x%X\n", status);
|
||||
|
||||
if (ata_msg_intr(ap))
|
||||
printk(KERN_INFO "%s: irq ack: drv_stat 0x%X\n",
|
||||
__FUNCTION__, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct ata_port_operations pata_icside_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.set_dmamode = pata_icside_set_dmamode,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -403,7 +386,6 @@ static struct ata_port_operations pata_icside_port_ops = {
|
|||
|
||||
.irq_clear = ata_dummy_noret,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = pata_icside_irq_ack,
|
||||
|
||||
.port_start = pata_icside_port_start,
|
||||
|
||||
|
@ -412,9 +394,10 @@ static struct ata_port_operations pata_icside_port_ops = {
|
|||
};
|
||||
|
||||
static void __devinit
|
||||
pata_icside_setup_ioaddr(struct ata_ioports *ioaddr, void __iomem *base,
|
||||
pata_icside_setup_ioaddr(struct ata_port *ap, void __iomem *base,
|
||||
const struct portinfo *info)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
void __iomem *cmd = base + info->dataoffset;
|
||||
|
||||
ioaddr->cmd_addr = cmd;
|
||||
|
@ -431,6 +414,13 @@ pata_icside_setup_ioaddr(struct ata_ioports *ioaddr, void __iomem *base,
|
|||
|
||||
ioaddr->ctl_addr = base + info->ctrloffset;
|
||||
ioaddr->altstatus_addr = ioaddr->ctl_addr;
|
||||
|
||||
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
|
||||
info->raw_base + info->dataoffset,
|
||||
info->raw_base + info->ctrloffset);
|
||||
|
||||
if (info->raw_ioc_base)
|
||||
ata_port_desc(ap, "iocbase 0x%lx", info->raw_ioc_base);
|
||||
}
|
||||
|
||||
static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
|
||||
|
@ -451,6 +441,8 @@ static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
|
|||
info->nr_ports = 1;
|
||||
info->port[0] = &pata_icside_portinfo_v5;
|
||||
|
||||
info->raw_base = ecard_resource_start(ec, ECARD_RES_MEMC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -491,6 +483,9 @@ static int __devinit pata_icside_register_v6(struct pata_icside_info *info)
|
|||
info->port[0] = &pata_icside_portinfo_v6_1;
|
||||
info->port[1] = &pata_icside_portinfo_v6_2;
|
||||
|
||||
info->raw_base = ecard_resource_start(ec, ECARD_RES_EASI);
|
||||
info->raw_ioc_base = ecard_resource_start(ec, ECARD_RES_IOCFAST);
|
||||
|
||||
return icside_dma_init(info);
|
||||
}
|
||||
|
||||
|
@ -527,7 +522,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
|
|||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
ap->ops = &pata_icside_port_ops;
|
||||
|
||||
pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]);
|
||||
pata_icside_setup_ioaddr(ap, info->base, info->port[i]);
|
||||
}
|
||||
|
||||
return ata_host_activate(host, ec->irq, ata_interrupt, 0,
|
||||
|
|
|
@ -38,7 +38,6 @@ static struct scsi_host_template isapnp_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations isapnp_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -58,9 +57,8 @@ static struct ata_port_operations isapnp_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -112,6 +110,10 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
|
|||
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
|
||||
(unsigned long long)pnp_port_start(idev, 0),
|
||||
(unsigned long long)pnp_port_start(idev, 1));
|
||||
|
||||
/* activate */
|
||||
return ata_host_activate(host, pnp_irq(idev, 0), ata_interrupt, 0,
|
||||
&isapnp_sht);
|
||||
|
|
|
@ -23,23 +23,24 @@
|
|||
|
||||
/**
|
||||
* it8213_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @link: link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Filter out ports by the enable bits before doing the normal reset
|
||||
* and probe.
|
||||
*/
|
||||
|
||||
static int it8213_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int it8213_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits it8213_enable_bits[] = {
|
||||
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
|
||||
};
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,7 +261,6 @@ static struct scsi_host_template it8213_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations it8213_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = it8213_set_piomode,
|
||||
.set_dmamode = it8213_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -288,9 +288,8 @@ static const struct ata_port_operations it8213_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -391,7 +391,7 @@ static void it821x_passthru_dev_select(struct ata_port *ap,
|
|||
{
|
||||
struct it821x_dev *itdev = ap->private_data;
|
||||
if (itdev && device != itdev->last_device) {
|
||||
struct ata_device *adev = &ap->device[device];
|
||||
struct ata_device *adev = &ap->link.device[device];
|
||||
it821x_program(ap, adev, itdev->pio[adev->devno]);
|
||||
itdev->last_device = device;
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)
|
|||
|
||||
/**
|
||||
* it821x_smart_set_mode - mode setting
|
||||
* @ap: interface to set up
|
||||
* @link: interface to set up
|
||||
* @unused: device that failed (error only)
|
||||
*
|
||||
* Use a non standard set_mode function. We don't want to be tuned.
|
||||
|
@ -459,12 +459,11 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)
|
|||
* and respect them.
|
||||
*/
|
||||
|
||||
static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused)
|
||||
static int it821x_smart_set_mode(struct ata_link *link, struct ata_device **unused)
|
||||
{
|
||||
int i;
|
||||
struct ata_device *dev;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
|
@ -564,7 +563,7 @@ static int it821x_port_start(struct ata_port *ap)
|
|||
struct it821x_dev *itdev;
|
||||
u8 conf;
|
||||
|
||||
int ret = ata_port_start(ap);
|
||||
int ret = ata_sff_port_start(ap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -621,7 +620,6 @@ static struct scsi_host_template it821x_sht = {
|
|||
|
||||
static struct ata_port_operations it821x_smart_port_ops = {
|
||||
.set_mode = it821x_smart_set_mode,
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -651,13 +649,11 @@ static struct ata_port_operations it821x_smart_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = it821x_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations it821x_passthru_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = it821x_passthru_set_piomode,
|
||||
.set_dmamode = it821x_passthru_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -688,7 +684,6 @@ static struct ata_port_operations it821x_passthru_port_ops = {
|
|||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = it821x_port_start,
|
||||
};
|
||||
|
|
|
@ -26,12 +26,11 @@
|
|||
#define DRV_NAME "pata_ixp4xx_cf"
|
||||
#define DRV_VERSION "0.2"
|
||||
|
||||
static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
|
||||
static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error)
|
||||
{
|
||||
int i;
|
||||
struct ata_device *dev;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
|
@ -49,7 +48,7 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
|
|||
unsigned int i;
|
||||
unsigned int words = buflen >> 1;
|
||||
u16 *buf16 = (u16 *) buf;
|
||||
struct ata_port *ap = adev->ap;
|
||||
struct ata_port *ap = adev->link->ap;
|
||||
void __iomem *mmio = ap->ioaddr.data_addr;
|
||||
struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
|
||||
|
||||
|
@ -108,7 +107,6 @@ static struct ata_port_operations ixp4xx_port_ops = {
|
|||
.set_mode = ixp4xx_set_mode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.exec_command = ata_exec_command,
|
||||
|
@ -128,14 +126,17 @@ static struct ata_port_operations ixp4xx_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_dummy_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
|
||||
struct ixp4xx_pata_data *data)
|
||||
struct ixp4xx_pata_data *data,
|
||||
unsigned long raw_cs0, unsigned long raw_cs1)
|
||||
{
|
||||
unsigned long raw_cmd = raw_cs0;
|
||||
unsigned long raw_ctl = raw_cs1 + 0x06;
|
||||
|
||||
ioaddr->cmd_addr = data->cs0;
|
||||
ioaddr->altstatus_addr = data->cs1 + 0x06;
|
||||
ioaddr->ctl_addr = data->cs1 + 0x06;
|
||||
|
@ -161,7 +162,12 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
|
|||
*(unsigned long *)&ioaddr->device_addr ^= 0x03;
|
||||
*(unsigned long *)&ioaddr->status_addr ^= 0x03;
|
||||
*(unsigned long *)&ioaddr->command_addr ^= 0x03;
|
||||
|
||||
raw_cmd ^= 0x03;
|
||||
raw_ctl ^= 0x03;
|
||||
#endif
|
||||
|
||||
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", raw_cmd, raw_ctl);
|
||||
}
|
||||
|
||||
static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
|
||||
|
@ -206,7 +212,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
|
|||
ap->pio_mask = 0x1f; /* PIO4 */
|
||||
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
|
||||
|
||||
ixp4xx_setup_port(&ap->ioaddr, data);
|
||||
ixp4xx_setup_port(ap, data, cs0->start, cs1->start);
|
||||
|
||||
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ typedef enum {
|
|||
|
||||
/**
|
||||
* jmicron_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the PATA port setup we need.
|
||||
|
@ -39,9 +39,9 @@ typedef enum {
|
|||
* and setup here. We assume that has been done by init_one and the
|
||||
* BIOS.
|
||||
*/
|
||||
|
||||
static int jmicron_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int jmicron_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 control;
|
||||
u32 control5;
|
||||
|
@ -103,7 +103,7 @@ static int jmicron_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
ap->cbl = ATA_CBL_SATA;
|
||||
break;
|
||||
}
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,8 +141,6 @@ static struct scsi_host_template jmicron_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations jmicron_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
/* Task file is PCI ATA format, use helpers */
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -168,7 +166,6 @@ static const struct ata_port_operations jmicron_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
/* Generic PATA PCI ATA helpers */
|
||||
.port_start = ata_port_start,
|
||||
|
@ -207,17 +204,8 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
|
|||
}
|
||||
|
||||
static const struct pci_device_id jmicron_pci_tbl[] = {
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361,
|
||||
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 361 },
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363,
|
||||
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 363 },
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365,
|
||||
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 365 },
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366,
|
||||
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 366 },
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368,
|
||||
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 368 },
|
||||
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */
|
|||
|
||||
/**
|
||||
* legacy_set_mode - mode setting
|
||||
* @ap: IDE interface
|
||||
* @link: IDE link
|
||||
* @unused: Device that failed when error is returned
|
||||
*
|
||||
* Use a non standard set_mode function. We don't want to be tuned.
|
||||
|
@ -107,12 +107,11 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */
|
|||
* expand on this as per hdparm in the base kernel.
|
||||
*/
|
||||
|
||||
static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused)
|
||||
static int legacy_set_mode(struct ata_link *link, struct ata_device **unused)
|
||||
{
|
||||
int i;
|
||||
struct ata_device *dev;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
|
@ -151,7 +150,6 @@ static struct scsi_host_template legacy_sht = {
|
|||
*/
|
||||
|
||||
static struct ata_port_operations simple_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -172,7 +170,6 @@ static struct ata_port_operations simple_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -180,7 +177,6 @@ static struct ata_port_operations simple_port_ops = {
|
|||
static struct ata_port_operations legacy_port_ops = {
|
||||
.set_mode = legacy_set_mode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -201,7 +197,6 @@ static struct ata_port_operations legacy_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -256,7 +251,7 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
|
||||
{
|
||||
struct ata_port *ap = adev->ap;
|
||||
struct ata_port *ap = adev->link->ap;
|
||||
int slop = buflen & 3;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -296,7 +291,6 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig
|
|||
static struct ata_port_operations pdc20230_port_ops = {
|
||||
.set_piomode = pdc20230_set_piomode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -317,7 +311,6 @@ static struct ata_port_operations pdc20230_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -352,7 +345,6 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
static struct ata_port_operations ht6560a_port_ops = {
|
||||
.set_piomode = ht6560a_set_piomode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -373,7 +365,6 @@ static struct ata_port_operations ht6560a_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -419,7 +410,6 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
static struct ata_port_operations ht6560b_port_ops = {
|
||||
.set_piomode = ht6560b_set_piomode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -440,7 +430,6 @@ static struct ata_port_operations ht6560b_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -541,7 +530,6 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev
|
|||
static struct ata_port_operations opti82c611a_port_ops = {
|
||||
.set_piomode = opti82c611a_set_piomode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -562,7 +550,6 @@ static struct ata_port_operations opti82c611a_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -675,7 +662,6 @@ static unsigned int opti82c46x_qc_issue_prot(struct ata_queued_cmd *qc)
|
|||
static struct ata_port_operations opti82c46x_port_ops = {
|
||||
.set_piomode = opti82c46x_set_piomode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -696,7 +682,6 @@ static struct ata_port_operations opti82c46x_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
@ -814,6 +799,8 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
|
|||
ata_std_ports(&ap->ioaddr);
|
||||
ap->private_data = ld;
|
||||
|
||||
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, ctrl);
|
||||
|
||||
ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
|
|
@ -24,14 +24,15 @@
|
|||
|
||||
/**
|
||||
* marvell_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @link: link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the PATA port setup we need.
|
||||
*/
|
||||
|
||||
static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int marvell_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 devices;
|
||||
void __iomem *barp;
|
||||
|
@ -54,7 +55,7 @@ static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
(!(devices & 0x10))) /* PATA enable ? */
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static int marvell_cable_detect(struct ata_port *ap)
|
||||
|
@ -110,8 +111,6 @@ static struct scsi_host_template marvell_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations marvell_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
/* Task file is PCI ATA format, use helpers */
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -138,10 +137,9 @@ static const struct ata_port_operations marvell_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
/* Generic PATA PCI ATA helpers */
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -283,7 +283,6 @@ static struct scsi_host_template mpc52xx_ata_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations mpc52xx_ata_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = mpc52xx_ata_set_piomode,
|
||||
.dev_select = mpc52xx_ata_dev_select,
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -299,12 +298,12 @@ static struct ata_port_operations mpc52xx_ata_port_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static int __devinit
|
||||
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
|
||||
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
|
||||
unsigned long raw_ata_regs)
|
||||
{
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
|
@ -338,6 +337,8 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
|
|||
aio->status_addr = &priv->ata_regs->tf_command;
|
||||
aio->command_addr = &priv->ata_regs->tf_command;
|
||||
|
||||
ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs);
|
||||
|
||||
/* activate host */
|
||||
return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
|
||||
&mpc52xx_ata_sht);
|
||||
|
@ -434,7 +435,7 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
|
|||
}
|
||||
|
||||
/* Register ourselves to libata */
|
||||
rv = mpc52xx_ata_init_one(&op->dev, priv);
|
||||
rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start);
|
||||
if (rv) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Error while registering to ATA layer\n");
|
||||
|
|
|
@ -46,15 +46,16 @@ enum {
|
|||
SECONDARY = (1 << 14)
|
||||
};
|
||||
|
||||
static int mpiix_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int mpiix_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits mpiix_enable_bits = { 0x6D, 1, 0x80, 0x80 };
|
||||
|
||||
if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,7 +169,6 @@ static struct scsi_host_template mpiix_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations mpiix_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = mpiix_set_piomode,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -189,9 +189,8 @@ static struct ata_port_operations mpiix_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
@ -202,7 +201,7 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
struct ata_port *ap;
|
||||
void __iomem *cmd_addr, *ctl_addr;
|
||||
u16 idetim;
|
||||
int irq;
|
||||
int cmd, ctl, irq;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
|
||||
|
@ -210,6 +209,7 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
host = ata_host_alloc(&dev->dev, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
ap = host->ports[0];
|
||||
|
||||
/* MPIIX has many functions which can be turned on or off according
|
||||
to other devices present. Make sure IDE is enabled before we try
|
||||
|
@ -221,25 +221,28 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
|
||||
/* See if it's primary or secondary channel... */
|
||||
if (!(idetim & SECONDARY)) {
|
||||
cmd = 0x1F0;
|
||||
ctl = 0x3F6;
|
||||
irq = 14;
|
||||
cmd_addr = devm_ioport_map(&dev->dev, 0x1F0, 8);
|
||||
ctl_addr = devm_ioport_map(&dev->dev, 0x3F6, 1);
|
||||
} else {
|
||||
cmd = 0x170;
|
||||
ctl = 0x376;
|
||||
irq = 15;
|
||||
cmd_addr = devm_ioport_map(&dev->dev, 0x170, 8);
|
||||
ctl_addr = devm_ioport_map(&dev->dev, 0x376, 1);
|
||||
}
|
||||
|
||||
cmd_addr = devm_ioport_map(&dev->dev, cmd, 8);
|
||||
ctl_addr = devm_ioport_map(&dev->dev, ctl, 1);
|
||||
if (!cmd_addr || !ctl_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
ata_port_desc(ap, "cmd 0x%x ctl 0x%x", cmd, ctl);
|
||||
|
||||
/* We do our own plumbing to avoid leaking special cases for whacko
|
||||
ancient hardware into the core code. There are two issues to
|
||||
worry about. #1 The chip is a bridge so if in legacy mode and
|
||||
without BARs set fools the setup. #2 If you pci_disable_device
|
||||
the MPIIX your box goes castors up */
|
||||
|
||||
ap = host->ports[0];
|
||||
ap->ops = &mpiix_port_ops;
|
||||
ap->pio_mask = 0x1F;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
|
|
|
@ -40,8 +40,6 @@ static struct scsi_host_template netcell_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations netcell_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
/* Task file is PCI ATA format, use helpers */
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -68,10 +66,9 @@ static const struct ata_port_operations netcell_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
/* Generic PATA PCI ATA helpers */
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -32,14 +32,15 @@
|
|||
|
||||
/**
|
||||
* ns87410_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Check enabled ports
|
||||
*/
|
||||
|
||||
static int ns87410_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int ns87410_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits ns87410_enable_bits[] = {
|
||||
{ 0x43, 1, 0x08, 0x08 },
|
||||
|
@ -49,7 +50,7 @@ static int ns87410_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,7 +162,6 @@ static struct scsi_host_template ns87410_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations ns87410_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = ns87410_set_piomode,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -184,9 +184,8 @@ static struct ata_port_operations ns87410_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* pata_ns87415.c - NS87415 (non PARISC) PATA
|
||||
*
|
||||
* (C) 2005 Red Hat <alan@redhat.com>
|
||||
*
|
||||
* This is a fairly generic MWDMA controller. It has some limitations
|
||||
* as it requires timing reloads on PIO/DMA transitions but it is otherwise
|
||||
* fairly well designed.
|
||||
*
|
||||
* This driver assumes the firmware has left the chip in a valid ST506
|
||||
* compliant state, either legacy IRQ 14/15 or native INTA shared. You
|
||||
* may need to add platform code if your system fails to do this.
|
||||
*
|
||||
* The same cell appears in the 87560 controller used by some PARISC
|
||||
* systems. This has its own special mountain of errata.
|
||||
*
|
||||
* TODO:
|
||||
* Test PARISC SuperIO
|
||||
* Get someone to test on SPARC
|
||||
* Implement lazy pio/dma switching for better performance
|
||||
* 8bit shared timing.
|
||||
* See if we need to kill the FIFO for ATAPI
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_ns87415"
|
||||
#define DRV_VERSION "0.0.1"
|
||||
|
||||
/**
|
||||
* ns87415_set_mode - Initialize host controller mode timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: Device whose timings we are configuring
|
||||
* @mode: Mode to set
|
||||
*
|
||||
* Program the mode registers for this controller, channel and
|
||||
* device. Because the chip is quite an old design we have to do this
|
||||
* for PIO/DMA switches.
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
|
||||
{
|
||||
struct pci_dev *dev = to_pci_dev(ap->host->dev);
|
||||
int unit = 2 * ap->port_no + adev->devno;
|
||||
int timing = 0x44 + 2 * unit;
|
||||
unsigned long T = 1000000000 / 33333; /* PCI clocks */
|
||||
struct ata_timing t;
|
||||
u16 clocking;
|
||||
u8 iordy;
|
||||
u8 status;
|
||||
|
||||
/* Timing register format is 17 - low nybble read timing with
|
||||
the high nybble being 16 - x for recovery time in PCI clocks */
|
||||
|
||||
ata_timing_compute(adev, adev->pio_mode, &t, T, 0);
|
||||
|
||||
clocking = 17 - FIT(t.active, 2, 17);
|
||||
clocking |= (16 - FIT(t.recover, 1, 16)) << 4;
|
||||
/* Use the same timing for read and write bytes */
|
||||
clocking |= (clocking << 8);
|
||||
pci_write_config_word(dev, timing, clocking);
|
||||
|
||||
/* Set the IORDY enable versus DMA enable on or off properly */
|
||||
pci_read_config_byte(dev, 0x42, &iordy);
|
||||
iordy &= ~(1 << (4 + unit));
|
||||
if (mode >= XFER_MW_DMA_0 || !ata_pio_need_iordy(adev))
|
||||
iordy |= (1 << (4 + unit));
|
||||
|
||||
/* Paranoia: We shouldn't ever get here with busy write buffers
|
||||
but if so wait */
|
||||
|
||||
pci_read_config_byte(dev, 0x43, &status);
|
||||
while (status & 0x03) {
|
||||
udelay(1);
|
||||
pci_read_config_byte(dev, 0x43, &status);
|
||||
}
|
||||
/* Flip the IORDY/DMA bits now we are sure the write buffers are
|
||||
clear */
|
||||
pci_write_config_byte(dev, 0x42, iordy);
|
||||
|
||||
/* TODO: Set byte 54 command timing to the best 8bit
|
||||
mode shared by all four devices */
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87415_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: Device to program
|
||||
*
|
||||
* Set PIO mode for device, in host controller PCI config space.
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void ns87415_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
ns87415_set_mode(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87415_bmdma_setup - Set up DMA
|
||||
* @qc: Command block
|
||||
*
|
||||
* Set up for bus masterng DMA. We have to do this ourselves
|
||||
* rather than use the helper due to a chip erratum
|
||||
*/
|
||||
|
||||
static void ns87415_bmdma_setup(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
|
||||
u8 dmactl;
|
||||
|
||||
/* load PRD table addr. */
|
||||
mb(); /* make sure PRD table writes are visible to controller */
|
||||
iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
|
||||
|
||||
/* specify data direction, triple-check start bit is clear */
|
||||
dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
|
||||
dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
|
||||
/* Due to an erratum we need to write these bits to the wrong
|
||||
place - which does save us an I/O bizarrely */
|
||||
dmactl |= ATA_DMA_INTR | ATA_DMA_ERR;
|
||||
if (!rw)
|
||||
dmactl |= ATA_DMA_WR;
|
||||
iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
|
||||
/* issue r/w command */
|
||||
ap->ops->exec_command(ap, &qc->tf);
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87415_bmdma_start - Begin DMA transfer
|
||||
* @qc: Command block
|
||||
*
|
||||
* Switch the timings for the chip and set up for a DMA transfer
|
||||
* before the DMA burst begins.
|
||||
*
|
||||
* FIXME: We should do lazy switching on bmdma_start versus
|
||||
* ata_pio_data_xfer for better performance.
|
||||
*/
|
||||
|
||||
static void ns87415_bmdma_start(struct ata_queued_cmd *qc)
|
||||
{
|
||||
ns87415_set_mode(qc->ap, qc->dev, qc->dev->dma_mode);
|
||||
ata_bmdma_start(qc);
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87415_bmdma_stop - End DMA transfer
|
||||
* @qc: Command block
|
||||
*
|
||||
* End DMA mode and switch the controller back into PIO mode
|
||||
*/
|
||||
|
||||
static void ns87415_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
{
|
||||
ata_bmdma_stop(qc);
|
||||
ns87415_set_mode(qc->ap, qc->dev, qc->dev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87415_bmdma_irq_clear - Clear interrupt
|
||||
* @ap: Channel to clear
|
||||
*
|
||||
* Erratum: Due to a chip bug regisers 02 and 0A bit 1 and 2 (the
|
||||
* error bits) are reset by writing to register 00 or 08.
|
||||
*/
|
||||
|
||||
static void ns87415_bmdma_irq_clear(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->ioaddr.bmdma_addr;
|
||||
|
||||
if (!mmio)
|
||||
return;
|
||||
iowrite8((ioread8(mmio + ATA_DMA_CMD) | ATA_DMA_INTR | ATA_DMA_ERR),
|
||||
mmio + ATA_DMA_CMD);
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87415_check_atapi_dma - ATAPI DMA filter
|
||||
* @qc: Command block
|
||||
*
|
||||
* Disable ATAPI DMA (for now). We may be able to do DMA if we
|
||||
* kill the prefetching. This isn't clear.
|
||||
*/
|
||||
|
||||
static int ns87415_check_atapi_dma(struct ata_queued_cmd *qc)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SUPERIO)
|
||||
|
||||
/* SUPERIO 87560 is a PoS chip that NatSem denies exists.
|
||||
* Unfortunately, it's built-in on all Astro-based PA-RISC workstations
|
||||
* which use the integrated NS87514 cell for CD-ROM support.
|
||||
* i.e we have to support for CD-ROM installs.
|
||||
* See drivers/parisc/superio.c for more gory details.
|
||||
*
|
||||
* Workarounds taken from drivers/ide/pci/ns87415.c
|
||||
*/
|
||||
|
||||
#include <asm/superio.h>
|
||||
|
||||
/**
|
||||
* ns87560_read_buggy - workaround buggy Super I/O chip
|
||||
* @port: Port to read
|
||||
*
|
||||
* Work around chipset problems in the 87560 SuperIO chip
|
||||
*/
|
||||
|
||||
static u8 ns87560_read_buggy(void __iomem *port)
|
||||
{
|
||||
u8 tmp;
|
||||
int retries = SUPERIO_IDE_MAX_RETRIES;
|
||||
do {
|
||||
tmp = ioread8(port);
|
||||
if (tmp != 0)
|
||||
return tmp;
|
||||
udelay(50);
|
||||
} while(retries-- > 0);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87560_check_status
|
||||
* @ap: channel to check
|
||||
*
|
||||
* Return the status of the channel working around the
|
||||
* 87560 flaws.
|
||||
*/
|
||||
|
||||
static u8 ns87560_check_status(struct ata_port *ap)
|
||||
{
|
||||
return ns87560_read_buggy(ap->ioaddr.status_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87560_tf_read - input device's ATA taskfile shadow registers
|
||||
* @ap: Port from which input is read
|
||||
* @tf: ATA taskfile register set for storing input
|
||||
*
|
||||
* Reads ATA taskfile registers for currently-selected device
|
||||
* into @tf. Work around the 87560 bugs.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
tf->command = ns87560_check_status(ap);
|
||||
tf->feature = ioread8(ioaddr->error_addr);
|
||||
tf->nsect = ioread8(ioaddr->nsect_addr);
|
||||
tf->lbal = ioread8(ioaddr->lbal_addr);
|
||||
tf->lbam = ioread8(ioaddr->lbam_addr);
|
||||
tf->lbah = ioread8(ioaddr->lbah_addr);
|
||||
tf->device = ns87560_read_buggy(ioaddr->device_addr);
|
||||
|
||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||
iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
|
||||
tf->hob_feature = ioread8(ioaddr->error_addr);
|
||||
tf->hob_nsect = ioread8(ioaddr->nsect_addr);
|
||||
tf->hob_lbal = ioread8(ioaddr->lbal_addr);
|
||||
tf->hob_lbam = ioread8(ioaddr->lbam_addr);
|
||||
tf->hob_lbah = ioread8(ioaddr->lbah_addr);
|
||||
iowrite8(tf->ctl, ioaddr->ctl_addr);
|
||||
ap->last_ctl = tf->ctl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ns87560_bmdma_status
|
||||
* @ap: channel to check
|
||||
*
|
||||
* Return the DMA status of the channel working around the
|
||||
* 87560 flaws.
|
||||
*/
|
||||
|
||||
static u8 ns87560_bmdma_status(struct ata_port *ap)
|
||||
{
|
||||
return ns87560_read_buggy(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
}
|
||||
|
||||
static const struct ata_port_operations ns87560_pata_ops = {
|
||||
.set_piomode = ns87415_set_piomode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ns87560_tf_read,
|
||||
.check_status = ns87560_check_status,
|
||||
.check_atapi_dma = ns87415_check_atapi_dma,
|
||||
.exec_command = ata_exec_command,
|
||||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ns87415_bmdma_setup,
|
||||
.bmdma_start = ns87415_bmdma_start,
|
||||
.bmdma_stop = ns87415_bmdma_stop,
|
||||
.bmdma_status = ns87560_bmdma_status,
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
.data_xfer = ata_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ns87415_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
#endif /* 87560 SuperIO Support */
|
||||
|
||||
|
||||
static const struct ata_port_operations ns87415_pata_ops = {
|
||||
.set_piomode = ns87415_set_piomode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
.check_atapi_dma = ns87415_check_atapi_dma,
|
||||
.exec_command = ata_exec_command,
|
||||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ns87415_bmdma_setup,
|
||||
.bmdma_start = ns87415_bmdma_start,
|
||||
.bmdma_stop = ns87415_bmdma_stop,
|
||||
.bmdma_status = ata_bmdma_status,
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
.data_xfer = ata_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ns87415_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct scsi_host_template ns87415_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.ioctl = ata_scsi_ioctl,
|
||||
.queuecommand = ata_scsi_queuecmd,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
.proc_name = DRV_NAME,
|
||||
.dma_boundary = ATA_DMA_BOUNDARY,
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ns87415_init_one - Register 87415 ATA PCI device with kernel services
|
||||
* @pdev: PCI device to register
|
||||
* @ent: Entry in ns87415_pci_tbl matching with @pdev
|
||||
*
|
||||
* Called from kernel PCI layer. We probe for combined mode (sigh),
|
||||
* and then hand over control to libata, for it to do the rest.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from PCI layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, or -ERRNO value.
|
||||
*/
|
||||
|
||||
static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
static const struct ata_port_info info = {
|
||||
.sht = &ns87415_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.port_ops = &ns87415_pata_ops,
|
||||
};
|
||||
const struct ata_port_info *ppi[] = { &info, NULL };
|
||||
#if defined(CONFIG_SUPERIO)
|
||||
static const struct ata_port_info info87560 = {
|
||||
.sht = &ns87415_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.port_ops = &ns87560_pata_ops,
|
||||
};
|
||||
|
||||
if (PCI_SLOT(pdev->devfn) == 0x0E)
|
||||
ppi[0] = &info87560;
|
||||
#endif
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev,
|
||||
"version " DRV_VERSION "\n");
|
||||
/* Select 512 byte sectors */
|
||||
pci_write_config_byte(pdev, 0x55, 0xEE);
|
||||
/* Select PIO0 8bit clocking */
|
||||
pci_write_config_byte(pdev, 0x54, 0xB7);
|
||||
return ata_pci_init_one(pdev, ppi);
|
||||
}
|
||||
|
||||
static const struct pci_device_id ns87415_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87415), },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
static struct pci_driver ns87415_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = ns87415_pci_tbl,
|
||||
.probe = ns87415_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init ns87415_init(void)
|
||||
{
|
||||
return pci_register_driver(&ns87415_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit ns87415_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ns87415_pci_driver);
|
||||
}
|
||||
|
||||
module_init(ns87415_init);
|
||||
module_exit(ns87415_exit);
|
||||
|
||||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_DESCRIPTION("ATA low-level driver for NS87415 controllers");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl);
|
||||
MODULE_VERSION(DRV_VERSION);
|
|
@ -29,14 +29,15 @@
|
|||
|
||||
/**
|
||||
* oldpiix_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int oldpiix_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int oldpiix_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits oldpiix_enable_bits[] = {
|
||||
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
|
||||
|
@ -46,7 +47,7 @@ static int oldpiix_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -237,7 +238,6 @@ static struct scsi_host_template oldpiix_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations oldpiix_pata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = oldpiix_set_piomode,
|
||||
.set_dmamode = oldpiix_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -265,9 +265,8 @@ static const struct ata_port_operations oldpiix_pata_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -46,14 +46,15 @@ enum {
|
|||
|
||||
/**
|
||||
* opti_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int opti_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int opti_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits opti_enable_bits[] = {
|
||||
{ 0x45, 1, 0x80, 0x00 },
|
||||
|
@ -63,7 +64,7 @@ static int opti_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,7 +183,6 @@ static struct scsi_host_template opti_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations opti_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = opti_set_piomode,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -209,9 +209,8 @@ static struct ata_port_operations opti_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
|
|
@ -47,14 +47,15 @@ static int pci_clock; /* 0 = 33 1 = 25 */
|
|||
|
||||
/**
|
||||
* optidma_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int optidma_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int optidma_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits optidma_enable_bits = {
|
||||
0x40, 1, 0x08, 0x00
|
||||
|
@ -63,7 +64,7 @@ static int optidma_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,25 +324,26 @@ static u8 optidma_make_bits43(struct ata_device *adev)
|
|||
|
||||
/**
|
||||
* optidma_set_mode - mode setup
|
||||
* @ap: port to set up
|
||||
* @link: link to set up
|
||||
*
|
||||
* Use the standard setup to tune the chipset and then finalise the
|
||||
* configuration by writing the nibble of extra bits of data into
|
||||
* the chip.
|
||||
*/
|
||||
|
||||
static int optidma_set_mode(struct ata_port *ap, struct ata_device **r_failed)
|
||||
static int optidma_set_mode(struct ata_link *link, struct ata_device **r_failed)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
u8 r;
|
||||
int nybble = 4 * ap->port_no;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int rc = ata_do_set_mode(ap, r_failed);
|
||||
int rc = ata_do_set_mode(link, r_failed);
|
||||
if (rc == 0) {
|
||||
pci_read_config_byte(pdev, 0x43, &r);
|
||||
|
||||
r &= (0x0F << nybble);
|
||||
r |= (optidma_make_bits43(&ap->device[0]) +
|
||||
(optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
|
||||
r |= (optidma_make_bits43(&link->device[0]) +
|
||||
(optidma_make_bits43(&link->device[0]) << 2)) << nybble;
|
||||
pci_write_config_byte(pdev, 0x43, r);
|
||||
}
|
||||
return rc;
|
||||
|
@ -366,7 +368,6 @@ static struct scsi_host_template optidma_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations optidma_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = optidma_set_pio_mode,
|
||||
.set_dmamode = optidma_set_dma_mode,
|
||||
|
||||
|
@ -396,13 +397,11 @@ static struct ata_port_operations optidma_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations optiplus_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = optiplus_set_pio_mode,
|
||||
.set_dmamode = optiplus_set_dma_mode,
|
||||
|
||||
|
@ -432,9 +431,8 @@ static struct ata_port_operations optiplus_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,7 +56,7 @@ struct ata_pcmcia_info {
|
|||
|
||||
/**
|
||||
* pcmcia_set_mode - PCMCIA specific mode setup
|
||||
* @ap: Port
|
||||
* @link: link
|
||||
* @r_failed_dev: Return pointer for failed device
|
||||
*
|
||||
* Perform the tuning and setup of the devices and timings, which
|
||||
|
@ -65,13 +65,13 @@ struct ata_pcmcia_info {
|
|||
* decode, which alas is embarrassingly common in the PC world
|
||||
*/
|
||||
|
||||
static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
|
||||
static int pcmcia_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
||||
{
|
||||
struct ata_device *master = &ap->device[0];
|
||||
struct ata_device *slave = &ap->device[1];
|
||||
struct ata_device *master = &link->device[0];
|
||||
struct ata_device *slave = &link->device[1];
|
||||
|
||||
if (!ata_dev_enabled(master) || !ata_dev_enabled(slave))
|
||||
return ata_do_set_mode(ap, r_failed_dev);
|
||||
return ata_do_set_mode(link, r_failed_dev);
|
||||
|
||||
if (memcmp(master->id + ATA_ID_FW_REV, slave->id + ATA_ID_FW_REV,
|
||||
ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0)
|
||||
|
@ -84,7 +84,7 @@ static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev
|
|||
ata_dev_disable(slave);
|
||||
}
|
||||
}
|
||||
return ata_do_set_mode(ap, r_failed_dev);
|
||||
return ata_do_set_mode(link, r_failed_dev);
|
||||
}
|
||||
|
||||
static struct scsi_host_template pcmcia_sht = {
|
||||
|
@ -107,7 +107,6 @@ static struct scsi_host_template pcmcia_sht = {
|
|||
|
||||
static struct ata_port_operations pcmcia_port_ops = {
|
||||
.set_mode = pcmcia_set_mode,
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -127,7 +126,6 @@ static struct ata_port_operations pcmcia_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
@ -304,6 +302,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
ap->ioaddr.ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io_base, ctl_base);
|
||||
|
||||
/* activate */
|
||||
ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt,
|
||||
IRQF_SHARED, &pcmcia_sht);
|
||||
|
|
|
@ -69,7 +69,7 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
|
|||
static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||
static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask);
|
||||
static int pdc2027x_cable_detect(struct ata_port *ap);
|
||||
static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed);
|
||||
static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed);
|
||||
|
||||
/*
|
||||
* ATA Timing Tables based on 133MHz controller clock.
|
||||
|
@ -147,7 +147,6 @@ static struct scsi_host_template pdc2027x_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations pdc2027x_pata100_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -173,13 +172,11 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations pdc2027x_pata133_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = pdc2027x_set_piomode,
|
||||
.set_dmamode = pdc2027x_set_dmamode,
|
||||
.set_mode = pdc2027x_set_mode,
|
||||
|
@ -208,9 +205,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_info pdc2027x_port_info[] = {
|
||||
|
@ -277,7 +273,7 @@ static int pdc2027x_cable_detect(struct ata_port *ap)
|
|||
u32 cgcr;
|
||||
|
||||
/* check cable detect results */
|
||||
cgcr = readl(port_mmio(ap, PDC_GLOBAL_CTL));
|
||||
cgcr = ioread32(port_mmio(ap, PDC_GLOBAL_CTL));
|
||||
if (cgcr & (1 << 26))
|
||||
goto cbl40;
|
||||
|
||||
|
@ -295,12 +291,12 @@ static int pdc2027x_cable_detect(struct ata_port *ap)
|
|||
*/
|
||||
static inline int pdc2027x_port_enabled(struct ata_port *ap)
|
||||
{
|
||||
return readb(port_mmio(ap, PDC_ATA_CTL)) & 0x02;
|
||||
return ioread8(port_mmio(ap, PDC_ATA_CTL)) & 0x02;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc2027x_prereset - prereset for PATA host controller
|
||||
* @ap: Target port
|
||||
* @link: Target link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Probeinit including cable detection.
|
||||
|
@ -309,12 +305,12 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)
|
|||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static int pdc2027x_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
/* Check whether port enabled */
|
||||
if (!pdc2027x_port_enabled(ap))
|
||||
if (!pdc2027x_port_enabled(link->ap))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,16 +383,16 @@ static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
/* Set the PIO timing registers using value table for 133MHz */
|
||||
PDPRINTK("Set pio regs... \n");
|
||||
|
||||
ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0));
|
||||
ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0));
|
||||
ctcr0 &= 0xffff0000;
|
||||
ctcr0 |= pdc2027x_pio_timing_tbl[pio].value0 |
|
||||
(pdc2027x_pio_timing_tbl[pio].value1 << 8);
|
||||
writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
|
||||
iowrite32(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
|
||||
|
||||
ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1));
|
||||
ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
|
||||
ctcr1 &= 0x00ffffff;
|
||||
ctcr1 |= (pdc2027x_pio_timing_tbl[pio].value2 << 24);
|
||||
writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
|
||||
iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
|
||||
|
||||
PDPRINTK("Set pio regs done\n");
|
||||
|
||||
|
@ -430,18 +426,18 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
* If tHOLD is '1', the hardware will add half clock for data hold time.
|
||||
* This code segment seems to be no effect. tHOLD will be overwritten below.
|
||||
*/
|
||||
ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1));
|
||||
writel(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1));
|
||||
ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
|
||||
iowrite32(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1));
|
||||
}
|
||||
|
||||
PDPRINTK("Set udma regs... \n");
|
||||
|
||||
ctcr1 = readl(dev_mmio(ap, adev, PDC_CTCR1));
|
||||
ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
|
||||
ctcr1 &= 0xff000000;
|
||||
ctcr1 |= pdc2027x_udma_timing_tbl[udma_mode].value0 |
|
||||
(pdc2027x_udma_timing_tbl[udma_mode].value1 << 8) |
|
||||
(pdc2027x_udma_timing_tbl[udma_mode].value2 << 16);
|
||||
writel(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
|
||||
iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
|
||||
|
||||
PDPRINTK("Set udma regs done\n");
|
||||
|
||||
|
@ -453,13 +449,13 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
unsigned int mdma_mode = dma_mode & 0x07;
|
||||
|
||||
PDPRINTK("Set mdma regs... \n");
|
||||
ctcr0 = readl(dev_mmio(ap, adev, PDC_CTCR0));
|
||||
ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0));
|
||||
|
||||
ctcr0 &= 0x0000ffff;
|
||||
ctcr0 |= (pdc2027x_mdma_timing_tbl[mdma_mode].value0 << 16) |
|
||||
(pdc2027x_mdma_timing_tbl[mdma_mode].value1 << 24);
|
||||
|
||||
writel(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
|
||||
iowrite32(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
|
||||
PDPRINTK("Set mdma regs done\n");
|
||||
|
||||
PDPRINTK("Set to mdma mode[%u] \n", mdma_mode);
|
||||
|
@ -470,24 +466,24 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
/**
|
||||
* pdc2027x_set_mode - Set the timing registers back to correct values.
|
||||
* @ap: Port to configure
|
||||
* @link: link to configure
|
||||
* @r_failed: Returned device for failure
|
||||
*
|
||||
* The pdc2027x hardware will look at "SET FEATURES" and change the timing registers
|
||||
* automatically. The values set by the hardware might be incorrect, under 133Mhz PLL.
|
||||
* This function overwrites the possibly incorrect values set by the hardware to be correct.
|
||||
*/
|
||||
static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed)
|
||||
static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed)
|
||||
{
|
||||
int i;
|
||||
struct ata_port *ap = link->ap;
|
||||
struct ata_device *dev;
|
||||
int rc;
|
||||
|
||||
i = ata_do_set_mode(ap, r_failed);
|
||||
if (i < 0)
|
||||
return i;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
rc = ata_do_set_mode(link, r_failed);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
|
||||
pdc2027x_set_piomode(ap, dev);
|
||||
|
@ -496,9 +492,9 @@ static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed)
|
|||
* Enable prefetch if the device support PIO only.
|
||||
*/
|
||||
if (dev->xfer_shift == ATA_SHIFT_PIO) {
|
||||
u32 ctcr1 = readl(dev_mmio(ap, dev, PDC_CTCR1));
|
||||
u32 ctcr1 = ioread32(dev_mmio(ap, dev, PDC_CTCR1));
|
||||
ctcr1 |= (1 << 25);
|
||||
writel(ctcr1, dev_mmio(ap, dev, PDC_CTCR1));
|
||||
iowrite32(ctcr1, dev_mmio(ap, dev, PDC_CTCR1));
|
||||
|
||||
PDPRINTK("Turn on prefetch\n");
|
||||
} else {
|
||||
|
@ -563,14 +559,12 @@ static long pdc_read_counter(struct ata_host *host)
|
|||
u32 bccrl, bccrh, bccrlv, bccrhv;
|
||||
|
||||
retry:
|
||||
bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
|
||||
bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
|
||||
rmb();
|
||||
bccrl = ioread32(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
|
||||
bccrh = ioread32(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
|
||||
|
||||
/* Read the counter values again for verification */
|
||||
bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
|
||||
bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
|
||||
rmb();
|
||||
bccrlv = ioread32(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
|
||||
bccrhv = ioread32(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
|
||||
|
||||
counter = (bccrh << 15) | bccrl;
|
||||
|
||||
|
@ -619,7 +613,7 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b
|
|||
/* Show the current clock value of PLL control register
|
||||
* (maybe already configured by the firmware)
|
||||
*/
|
||||
pll_ctl = readw(mmio_base + PDC_PLL_CTL);
|
||||
pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
|
||||
|
||||
PDPRINTK("pll_ctl[%X]\n", pll_ctl);
|
||||
#endif
|
||||
|
@ -659,8 +653,8 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b
|
|||
|
||||
PDPRINTK("Writing pll_ctl[%X]\n", pll_ctl);
|
||||
|
||||
writew(pll_ctl, mmio_base + PDC_PLL_CTL);
|
||||
readw(mmio_base + PDC_PLL_CTL); /* flush */
|
||||
iowrite16(pll_ctl, mmio_base + PDC_PLL_CTL);
|
||||
ioread16(mmio_base + PDC_PLL_CTL); /* flush */
|
||||
|
||||
/* Wait the PLL circuit to be stable */
|
||||
mdelay(30);
|
||||
|
@ -670,7 +664,7 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b
|
|||
* Show the current clock value of PLL control register
|
||||
* (maybe configured by the firmware)
|
||||
*/
|
||||
pll_ctl = readw(mmio_base + PDC_PLL_CTL);
|
||||
pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
|
||||
|
||||
PDPRINTK("pll_ctl[%X]\n", pll_ctl);
|
||||
#endif
|
||||
|
@ -693,10 +687,10 @@ static long pdc_detect_pll_input_clock(struct ata_host *host)
|
|||
long pll_clock, usec_elapsed;
|
||||
|
||||
/* Start the test mode */
|
||||
scr = readl(mmio_base + PDC_SYS_CTL);
|
||||
scr = ioread32(mmio_base + PDC_SYS_CTL);
|
||||
PDPRINTK("scr[%X]\n", scr);
|
||||
writel(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL);
|
||||
readl(mmio_base + PDC_SYS_CTL); /* flush */
|
||||
iowrite32(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL);
|
||||
ioread32(mmio_base + PDC_SYS_CTL); /* flush */
|
||||
|
||||
/* Read current counter value */
|
||||
start_count = pdc_read_counter(host);
|
||||
|
@ -710,10 +704,10 @@ static long pdc_detect_pll_input_clock(struct ata_host *host)
|
|||
do_gettimeofday(&end_time);
|
||||
|
||||
/* Stop the test mode */
|
||||
scr = readl(mmio_base + PDC_SYS_CTL);
|
||||
scr = ioread32(mmio_base + PDC_SYS_CTL);
|
||||
PDPRINTK("scr[%X]\n", scr);
|
||||
writel(scr & ~(0x01 << 14), mmio_base + PDC_SYS_CTL);
|
||||
readl(mmio_base + PDC_SYS_CTL); /* flush */
|
||||
iowrite32(scr & ~(0x01 << 14), mmio_base + PDC_SYS_CTL);
|
||||
ioread32(mmio_base + PDC_SYS_CTL); /* flush */
|
||||
|
||||
/* calculate the input clock in Hz */
|
||||
usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +
|
||||
|
@ -745,9 +739,6 @@ static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx)
|
|||
*/
|
||||
pll_clock = pdc_detect_pll_input_clock(host);
|
||||
|
||||
if (pll_clock < 0) /* counter overflow? Try again. */
|
||||
pll_clock = pdc_detect_pll_input_clock(host);
|
||||
|
||||
dev_printk(KERN_INFO, host->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
|
||||
|
||||
/* Adjust PLL control register */
|
||||
|
@ -791,12 +782,14 @@ static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
|
|||
static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
static const unsigned long cmd_offset[] = { 0x17c0, 0x15c0 };
|
||||
static const unsigned long bmdma_offset[] = { 0x1000, 0x1008 };
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
const struct ata_port_info *ppi[] =
|
||||
{ &pdc2027x_port_info[board_idx], NULL };
|
||||
struct ata_host *host;
|
||||
void __iomem *mmio_base;
|
||||
int rc;
|
||||
int i, rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
@ -826,10 +819,15 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
|
|||
|
||||
mmio_base = host->iomap[PDC_MMIO_BAR];
|
||||
|
||||
pdc_ata_setup_port(&host->ports[0]->ioaddr, mmio_base + 0x17c0);
|
||||
host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x1000;
|
||||
pdc_ata_setup_port(&host->ports[1]->ioaddr, mmio_base + 0x15c0);
|
||||
host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x1008;
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
|
||||
pdc_ata_setup_port(&ap->ioaddr, mmio_base + cmd_offset[i]);
|
||||
ap->ioaddr.bmdma_addr = mmio_base + bmdma_offset[i];
|
||||
|
||||
ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, PDC_MMIO_BAR, cmd_offset[i], "cmd");
|
||||
}
|
||||
|
||||
//pci_enable_intx(pdev);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* First cut with LBA48/ATAPI
|
||||
*
|
||||
* TODO:
|
||||
* Channel interlock/reset on both required
|
||||
* Channel interlock/reset on both required ?
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -22,7 +22,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_pdc202xx_old"
|
||||
#define DRV_VERSION "0.4.2"
|
||||
#define DRV_VERSION "0.4.3"
|
||||
|
||||
static int pdc2026x_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
|
@ -106,9 +106,9 @@ static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
{ 0x20, 0x01 }
|
||||
};
|
||||
static u8 mdma_timing[3][2] = {
|
||||
{ 0x60, 0x03 },
|
||||
{ 0x60, 0x04 },
|
||||
{ 0xe0, 0x0f },
|
||||
{ 0x60, 0x04 },
|
||||
{ 0x60, 0x03 },
|
||||
};
|
||||
u8 r_bp, r_cp;
|
||||
|
||||
|
@ -139,6 +139,9 @@ static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
*
|
||||
* In UDMA3 or higher we have to clock switch for the duration of the
|
||||
* DMA transfer sequence.
|
||||
*
|
||||
* Note: The host lock held by the libata layer protects
|
||||
* us from two channels both trying to set DMA bits at once
|
||||
*/
|
||||
|
||||
static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
|
||||
|
@ -187,6 +190,9 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
|
|||
*
|
||||
* After a DMA completes we need to put the clock back to 33MHz for
|
||||
* PIO timings.
|
||||
*
|
||||
* Note: The host lock held by the libata layer protects
|
||||
* us from two channels both trying to set DMA bits at once
|
||||
*/
|
||||
|
||||
static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
|
@ -206,7 +212,6 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
|
|||
iowrite32(0, atapi_reg);
|
||||
iowrite8(ioread8(clock) & ~sel66, clock);
|
||||
}
|
||||
/* Check we keep host level locking here */
|
||||
/* Flip back to 33Mhz for PIO */
|
||||
if (adev->dma_mode >= XFER_UDMA_2)
|
||||
iowrite8(ioread8(clock) & ~sel66, clock);
|
||||
|
@ -247,7 +252,6 @@ static struct scsi_host_template pdc202xx_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations pdc2024x_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = pdc202xx_set_piomode,
|
||||
.set_dmamode = pdc202xx_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -275,13 +279,11 @@ static struct ata_port_operations pdc2024x_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations pdc2026x_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = pdc202xx_set_piomode,
|
||||
.set_dmamode = pdc202xx_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -310,9 +312,8 @@ static struct ata_port_operations pdc2026x_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
|
|
@ -30,13 +30,11 @@ static int pio_mask = 1;
|
|||
* Provide our own set_mode() as we don't want to change anything that has
|
||||
* already been configured..
|
||||
*/
|
||||
static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused)
|
||||
static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unused)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
|
||||
|
@ -71,7 +69,6 @@ static struct scsi_host_template pata_platform_sht = {
|
|||
static struct ata_port_operations pata_platform_port_ops = {
|
||||
.set_mode = pata_platform_set_mode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -91,7 +88,6 @@ static struct ata_port_operations pata_platform_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_dummy_ret0,
|
||||
};
|
||||
|
@ -209,9 +205,13 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
|
|||
|
||||
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
|
||||
|
||||
pp_info = (struct pata_platform_info *)(pdev->dev.platform_data);
|
||||
pp_info = pdev->dev.platform_data;
|
||||
pata_platform_setup_port(&ap->ioaddr, pp_info);
|
||||
|
||||
ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport",
|
||||
(unsigned long long)io_res->start,
|
||||
(unsigned long long)ctl_res->start);
|
||||
|
||||
/* activate */
|
||||
return ata_host_activate(host, platform_get_irq(pdev, 0),
|
||||
ata_interrupt, pp_info ? pp_info->irq_flags
|
||||
|
|
|
@ -126,7 +126,7 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
|
|||
|
||||
static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
|
||||
{
|
||||
struct ata_port *ap = adev->ap;
|
||||
struct ata_port *ap = adev->link->ap;
|
||||
int slop = buflen & 3;
|
||||
|
||||
if (ata_id_has_dword_io(adev->id)) {
|
||||
|
@ -170,7 +170,6 @@ static struct scsi_host_template qdi_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations qdi6500_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = qdi6500_set_piomode,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -192,13 +191,11 @@ static struct ata_port_operations qdi6500_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations qdi6580_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = qdi6580_set_piomode,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -220,9 +217,8 @@ static struct ata_port_operations qdi6580_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -238,6 +234,7 @@ static struct ata_port_operations qdi6580_port_ops = {
|
|||
|
||||
static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast)
|
||||
{
|
||||
unsigned long ctl = io + 0x206;
|
||||
struct platform_device *pdev;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
|
@ -254,7 +251,7 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
|
|||
|
||||
ret = -ENOMEM;
|
||||
io_addr = devm_ioport_map(&pdev->dev, io, 8);
|
||||
ctl_addr = devm_ioport_map(&pdev->dev, io + 0x206, 1);
|
||||
ctl_addr = devm_ioport_map(&pdev->dev, ctl, 1);
|
||||
if (!io_addr || !ctl_addr)
|
||||
goto fail;
|
||||
|
||||
|
@ -279,6 +276,8 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
|
|||
ap->ioaddr.ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
ata_port_desc(ap, "cmd %lx ctl %lx", io, ctl);
|
||||
|
||||
/*
|
||||
* Hook in a private data structure per channel
|
||||
*/
|
||||
|
|
|
@ -203,7 +203,6 @@ static struct scsi_host_template radisys_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations radisys_pata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = radisys_set_piomode,
|
||||
.set_dmamode = radisys_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -231,9 +230,8 @@ static const struct ata_port_operations radisys_pata_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
/**
|
||||
* rz1000_set_mode - mode setting function
|
||||
* @ap: ATA interface
|
||||
* @link: ATA link
|
||||
* @unused: returned device on set_mode failure
|
||||
*
|
||||
* Use a non standard set_mode function. We don't want to be tuned. We
|
||||
|
@ -34,12 +34,11 @@
|
|||
* whacked out.
|
||||
*/
|
||||
|
||||
static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused)
|
||||
static int rz1000_set_mode(struct ata_link *link, struct ata_device **unused)
|
||||
{
|
||||
int i;
|
||||
struct ata_device *dev;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
|
@ -74,7 +73,6 @@ static struct scsi_host_template rz1000_sht = {
|
|||
static struct ata_port_operations rz1000_port_ops = {
|
||||
.set_mode = rz1000_set_mode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -100,9 +98,8 @@ static struct ata_port_operations rz1000_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int rz1000_fifo_disable(struct pci_dev *pdev)
|
||||
|
|
|
@ -197,7 +197,6 @@ static struct scsi_host_template sc1200_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations sc1200_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sc1200_set_piomode,
|
||||
.set_dmamode = sc1200_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -227,9 +226,8 @@ static struct ata_port_operations sc1200_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -603,16 +603,17 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
|
|||
* Note: Original code is ata_std_softreset().
|
||||
*/
|
||||
|
||||
static int scc_std_softreset (struct ata_port *ap, unsigned int *classes,
|
||||
unsigned long deadline)
|
||||
static int scc_std_softreset(struct ata_link *link, unsigned int *classes,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
|
||||
unsigned int devmask = 0, err_mask;
|
||||
u8 err;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
if (ata_port_offline(ap)) {
|
||||
if (ata_link_offline(link)) {
|
||||
classes[0] = ATA_DEV_NONE;
|
||||
goto out;
|
||||
}
|
||||
|
@ -636,9 +637,11 @@ static int scc_std_softreset (struct ata_port *ap, unsigned int *classes,
|
|||
}
|
||||
|
||||
/* determine by signature whether we have ATA or ATAPI devices */
|
||||
classes[0] = ata_dev_try_classify(ap, 0, &err);
|
||||
classes[0] = ata_dev_try_classify(&ap->link.device[0],
|
||||
devmask & (1 << 0), &err);
|
||||
if (slave_possible && err != 0x81)
|
||||
classes[1] = ata_dev_try_classify(ap, 1, &err);
|
||||
classes[1] = ata_dev_try_classify(&ap->link.device[1],
|
||||
devmask & (1 << 1), &err);
|
||||
|
||||
out:
|
||||
DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
|
||||
|
@ -701,7 +704,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
|
|||
printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
|
||||
out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
|
||||
/* TBD: SW reset */
|
||||
scc_std_softreset(ap, &classes, deadline);
|
||||
scc_std_softreset(&ap->link, &classes, deadline);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -740,7 +743,7 @@ static u8 scc_bmdma_status (struct ata_port *ap)
|
|||
void __iomem *mmio = ap->ioaddr.bmdma_addr;
|
||||
u8 host_stat = in_be32(mmio + SCC_DMA_STATUS);
|
||||
u32 int_status = in_be32(mmio + SCC_DMA_INTST);
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
static int retry = 0;
|
||||
|
||||
/* return if IOS_SS is cleared */
|
||||
|
@ -785,7 +788,7 @@ static u8 scc_bmdma_status (struct ata_port *ap)
|
|||
static void scc_data_xfer (struct ata_device *adev, unsigned char *buf,
|
||||
unsigned int buflen, int write_data)
|
||||
{
|
||||
struct ata_port *ap = adev->ap;
|
||||
struct ata_port *ap = adev->link->ap;
|
||||
unsigned int words = buflen >> 1;
|
||||
unsigned int i;
|
||||
u16 *buf16 = (u16 *) buf;
|
||||
|
@ -838,38 +841,6 @@ static u8 scc_irq_on (struct ata_port *ap)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_irq_ack - Acknowledge a device interrupt.
|
||||
* @ap: Port on which interrupts are enabled.
|
||||
*
|
||||
* Note: Original code is ata_irq_ack().
|
||||
*/
|
||||
|
||||
static u8 scc_irq_ack (struct ata_port *ap, unsigned int chk_drq)
|
||||
{
|
||||
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
|
||||
u8 host_stat, post_stat, status;
|
||||
|
||||
status = ata_busy_wait(ap, bits, 1000);
|
||||
if (status & bits)
|
||||
if (ata_msg_err(ap))
|
||||
printk(KERN_ERR "abnormal status 0x%X\n", status);
|
||||
|
||||
/* get controller status; clear intr, err bits */
|
||||
host_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS);
|
||||
out_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS,
|
||||
host_stat | ATA_DMA_INTR | ATA_DMA_ERR);
|
||||
|
||||
post_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS);
|
||||
|
||||
if (ata_msg_intr(ap))
|
||||
printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
|
||||
__FUNCTION__,
|
||||
host_stat, post_stat, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_bmdma_freeze - Freeze BMDMA controller port
|
||||
* @ap: port to freeze
|
||||
|
@ -901,10 +872,10 @@ static void scc_bmdma_freeze (struct ata_port *ap)
|
|||
* @deadline: deadline jiffies for the operation
|
||||
*/
|
||||
|
||||
static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
static int scc_pata_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap, deadline);
|
||||
link->ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -915,8 +886,10 @@ static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline)
|
|||
* Note: Original code is ata_std_postreset().
|
||||
*/
|
||||
|
||||
static void scc_std_postreset (struct ata_port *ap, unsigned int *classes)
|
||||
static void scc_std_postreset(struct ata_link *link, unsigned int *classes)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
/* is double-select really necessary? */
|
||||
|
@ -1020,7 +993,6 @@ static struct scsi_host_template scc_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations scc_pata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = scc_set_piomode,
|
||||
.set_dmamode = scc_set_dmamode,
|
||||
.mode_filter = scc_mode_filter,
|
||||
|
@ -1047,7 +1019,6 @@ static const struct ata_port_operations scc_pata_ops = {
|
|||
|
||||
.irq_clear = scc_bmdma_irq_clear,
|
||||
.irq_on = scc_irq_on,
|
||||
.irq_ack = scc_irq_ack,
|
||||
|
||||
.port_start = scc_port_start,
|
||||
.port_stop = scc_port_stop,
|
||||
|
@ -1193,6 +1164,9 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
ata_port_pbar_desc(host->ports[0], SCC_CTRL_BAR, -1, "ctrl");
|
||||
ata_port_pbar_desc(host->ports[0], SCC_BMID_BAR, -1, "bmid");
|
||||
|
||||
rc = scc_host_init(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
|
|
@ -318,7 +318,6 @@ static struct scsi_host_template serverworks_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations serverworks_osb4_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = serverworks_set_piomode,
|
||||
.set_dmamode = serverworks_set_dmamode,
|
||||
.mode_filter = serverworks_osb4_filter,
|
||||
|
@ -348,13 +347,11 @@ static struct ata_port_operations serverworks_osb4_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations serverworks_csb_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = serverworks_set_piomode,
|
||||
.set_dmamode = serverworks_set_dmamode,
|
||||
.mode_filter = serverworks_csb_filter,
|
||||
|
@ -384,9 +381,8 @@ static struct ata_port_operations serverworks_csb_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int serverworks_fixup_osb4(struct pci_dev *pdev)
|
||||
|
|
|
@ -95,15 +95,16 @@ static int sil680_cable_detect(struct ata_port *ap) {
|
|||
|
||||
/**
|
||||
* sil680_bus_reset - reset the SIL680 bus
|
||||
* @ap: ATA port to reset
|
||||
* @link: ATA link to reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the SIL680 housekeeping when doing an ATA bus reset
|
||||
*/
|
||||
|
||||
static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes,
|
||||
static int sil680_bus_reset(struct ata_link *link, unsigned int *classes,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
unsigned long addr = sil680_selreg(ap, 0);
|
||||
u8 reset;
|
||||
|
@ -112,7 +113,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes,
|
|||
pci_write_config_byte(pdev, addr, reset | 0x03);
|
||||
udelay(25);
|
||||
pci_write_config_byte(pdev, addr, reset);
|
||||
return ata_std_softreset(ap, classes, deadline);
|
||||
return ata_std_softreset(link, classes, deadline);
|
||||
}
|
||||
|
||||
static void sil680_error_handler(struct ata_port *ap)
|
||||
|
@ -237,7 +238,6 @@ static struct scsi_host_template sil680_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations sil680_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sil680_set_piomode,
|
||||
.set_dmamode = sil680_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -266,9 +266,8 @@ static struct ata_port_operations sil680_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,7 +84,7 @@ static int sis_short_ata40(struct pci_dev *dev)
|
|||
|
||||
static int sis_old_port_base(struct ata_device *adev)
|
||||
{
|
||||
return 0x40 + (4 * adev->ap->port_no) + (2 * adev->devno);
|
||||
return 0x40 + (4 * adev->link->ap->port_no) + (2 * adev->devno);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,19 +133,20 @@ static int sis_66_cable_detect(struct ata_port *ap)
|
|||
|
||||
/**
|
||||
* sis_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int sis_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int sis_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits sis_enable_bits[] = {
|
||||
{ 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
{ 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */
|
||||
};
|
||||
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
|
||||
|
@ -154,7 +155,7 @@ static int sis_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
/* Clear the FIFO settings. We can't enable the FIFO until
|
||||
we know we are poking at a disk */
|
||||
pci_write_config_byte(pdev, 0x4B, 0);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
@ -530,7 +531,6 @@ static struct scsi_host_template sis_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations sis_133_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sis_133_set_piomode,
|
||||
.set_dmamode = sis_133_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -558,13 +558,11 @@ static const struct ata_port_operations sis_133_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations sis_133_for_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sis_133_set_piomode,
|
||||
.set_dmamode = sis_133_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -592,13 +590,11 @@ static const struct ata_port_operations sis_133_for_sata_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations sis_133_early_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sis_100_set_piomode,
|
||||
.set_dmamode = sis_133_early_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -626,13 +622,11 @@ static const struct ata_port_operations sis_133_early_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations sis_100_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sis_100_set_piomode,
|
||||
.set_dmamode = sis_100_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -660,13 +654,11 @@ static const struct ata_port_operations sis_100_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations sis_66_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sis_old_set_piomode,
|
||||
.set_dmamode = sis_66_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -694,13 +686,11 @@ static const struct ata_port_operations sis_66_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations sis_old_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sis_old_set_piomode,
|
||||
.set_dmamode = sis_old_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -728,9 +718,8 @@ static const struct ata_port_operations sis_old_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_info sis_info = {
|
||||
|
|
|
@ -43,23 +43,24 @@ enum {
|
|||
|
||||
/**
|
||||
* sl82c105_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int sl82c105_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int sl82c105_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits sl82c105_enable_bits[] = {
|
||||
{ 0x40, 1, 0x01, 0x01 },
|
||||
{ 0x40, 1, 0x10, 0x10 }
|
||||
};
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
@ -224,7 +225,6 @@ static struct scsi_host_template sl82c105_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations sl82c105_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = sl82c105_set_piomode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
|
@ -253,9 +253,8 @@ static struct ata_port_operations sl82c105_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,25 +47,26 @@
|
|||
|
||||
/**
|
||||
* triflex_prereset - probe begin
|
||||
* @ap: ATA port
|
||||
* @link: ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int triflex_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
static int triflex_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits triflex_enable_bits[] = {
|
||||
{ 0x80, 1, 0x01, 0x01 },
|
||||
{ 0x80, 1, 0x02, 0x02 }
|
||||
};
|
||||
|
||||
struct ata_port *ap = link->ap;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,7 +198,6 @@ static struct scsi_host_template triflex_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations triflex_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = triflex_set_piomode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
|
@ -226,9 +226,8 @@ static struct ata_port_operations triflex_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
|
|
@ -184,11 +184,15 @@ static int via_cable_detect(struct ata_port *ap) {
|
|||
two drives */
|
||||
if (ata66 & (0x10100000 >> (16 * ap->port_no)))
|
||||
return ATA_CBL_PATA80;
|
||||
/* Check with ACPI so we can spot BIOS reported SATA bridges */
|
||||
if (ata_acpi_cbl_80wire(ap))
|
||||
return ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
static int via_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
static int via_pre_reset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
const struct via_isa_bridge *config = ap->host->private_data;
|
||||
|
||||
if (!(config->flags & VIA_NO_ENABLES)) {
|
||||
|
@ -201,7 +205,7 @@ static int via_pre_reset(struct ata_port *ap, unsigned long deadline)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
@ -344,7 +348,6 @@ static struct scsi_host_template via_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations via_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = via_set_piomode,
|
||||
.set_dmamode = via_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -374,13 +377,11 @@ static struct ata_port_operations via_port_ops = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_operations via_port_ops_noirq = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = via_set_piomode,
|
||||
.set_dmamode = via_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
@ -410,9 +411,8 @@ static struct ata_port_operations via_port_ops_noirq = {
|
|||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -94,7 +94,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
|
||||
{
|
||||
struct ata_port *ap = adev->ap;
|
||||
struct ata_port *ap = adev->link->ap;
|
||||
int slop = buflen & 3;
|
||||
|
||||
if (ata_id_has_dword_io(adev->id)) {
|
||||
|
@ -138,7 +138,6 @@ static struct scsi_host_template winbond_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations winbond_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = winbond_set_piomode,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
|
@ -160,9 +159,8 @@ static struct ata_port_operations winbond_port_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -199,6 +197,7 @@ static __init int winbond_init_one(unsigned long port)
|
|||
|
||||
for (i = 0; i < 2 ; i ++) {
|
||||
unsigned long cmd_port = 0x1F0 - (0x80 * i);
|
||||
unsigned long ctl_port = cmd_port + 0x206;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
void __iomem *cmd_addr, *ctl_addr;
|
||||
|
@ -214,14 +213,16 @@ static __init int winbond_init_one(unsigned long port)
|
|||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
if (!host)
|
||||
goto err_unregister;
|
||||
ap = host->ports[0];
|
||||
|
||||
rc = -ENOMEM;
|
||||
cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
|
||||
ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
|
||||
ctl_addr = devm_ioport_map(&pdev->dev, ctl_port, 1);
|
||||
if (!cmd_addr || !ctl_addr)
|
||||
goto err_unregister;
|
||||
|
||||
ap = host->ports[0];
|
||||
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port);
|
||||
|
||||
ap->ops = &winbond_port_ops;
|
||||
ap->pio_mask = 0x1F;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
|
|
|
@ -92,6 +92,8 @@ enum {
|
|||
|
||||
/* CPB bits */
|
||||
cDONE = (1 << 0),
|
||||
cATERR = (1 << 3),
|
||||
|
||||
cVLD = (1 << 0),
|
||||
cDAT = (1 << 2),
|
||||
cIEN = (1 << 3),
|
||||
|
@ -131,14 +133,15 @@ static int adma_ata_init_one (struct pci_dev *pdev,
|
|||
static int adma_port_start(struct ata_port *ap);
|
||||
static void adma_host_stop(struct ata_host *host);
|
||||
static void adma_port_stop(struct ata_port *ap);
|
||||
static void adma_phy_reset(struct ata_port *ap);
|
||||
static void adma_qc_prep(struct ata_queued_cmd *qc);
|
||||
static unsigned int adma_qc_issue(struct ata_queued_cmd *qc);
|
||||
static int adma_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||
static void adma_bmdma_stop(struct ata_queued_cmd *qc);
|
||||
static u8 adma_bmdma_status(struct ata_port *ap);
|
||||
static void adma_irq_clear(struct ata_port *ap);
|
||||
static void adma_eng_timeout(struct ata_port *ap);
|
||||
static void adma_freeze(struct ata_port *ap);
|
||||
static void adma_thaw(struct ata_port *ap);
|
||||
static void adma_error_handler(struct ata_port *ap);
|
||||
|
||||
static struct scsi_host_template adma_ata_sht = {
|
||||
.module = THIS_MODULE,
|
||||
|
@ -159,21 +162,20 @@ static struct scsi_host_template adma_ata_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations adma_ata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.exec_command = ata_exec_command,
|
||||
.check_status = ata_check_status,
|
||||
.dev_select = ata_std_dev_select,
|
||||
.phy_reset = adma_phy_reset,
|
||||
.check_atapi_dma = adma_check_atapi_dma,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.qc_prep = adma_qc_prep,
|
||||
.qc_issue = adma_qc_issue,
|
||||
.eng_timeout = adma_eng_timeout,
|
||||
.freeze = adma_freeze,
|
||||
.thaw = adma_thaw,
|
||||
.error_handler = adma_error_handler,
|
||||
.irq_clear = adma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.port_start = adma_port_start,
|
||||
.port_stop = adma_port_stop,
|
||||
.host_stop = adma_host_stop,
|
||||
|
@ -184,7 +186,7 @@ static const struct ata_port_operations adma_ata_ops = {
|
|||
static struct ata_port_info adma_port_info[] = {
|
||||
/* board_1841_idx */
|
||||
{
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
|
||||
.flags = ATA_FLAG_SLAVE_POSS |
|
||||
ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
|
||||
ATA_FLAG_PIO_POLLING,
|
||||
.pio_mask = 0x10, /* pio4 */
|
||||
|
@ -273,24 +275,42 @@ static inline void adma_enter_reg_mode(struct ata_port *ap)
|
|||
readb(chan + ADMA_STATUS); /* flush */
|
||||
}
|
||||
|
||||
static void adma_phy_reset(struct ata_port *ap)
|
||||
static void adma_freeze(struct ata_port *ap)
|
||||
{
|
||||
struct adma_port_priv *pp = ap->private_data;
|
||||
void __iomem *chan = ADMA_PORT_REGS(ap);
|
||||
|
||||
pp->state = adma_state_idle;
|
||||
adma_reinit_engine(ap);
|
||||
ata_port_probe(ap);
|
||||
ata_bus_reset(ap);
|
||||
/* mask/clear ATA interrupts */
|
||||
writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
|
||||
ata_check_status(ap);
|
||||
|
||||
/* reset ADMA to idle state */
|
||||
writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
|
||||
udelay(2);
|
||||
writew(aPIOMD4 | aNIEN, chan + ADMA_CONTROL);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
static void adma_eng_timeout(struct ata_port *ap)
|
||||
static void adma_thaw(struct ata_port *ap)
|
||||
{
|
||||
adma_reinit_engine(ap);
|
||||
}
|
||||
|
||||
static int adma_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct adma_port_priv *pp = ap->private_data;
|
||||
|
||||
if (pp->state != adma_state_idle) /* healthy paranoia */
|
||||
pp->state = adma_state_mmio;
|
||||
adma_reinit_engine(ap);
|
||||
ata_eng_timeout(ap);
|
||||
|
||||
return ata_std_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static void adma_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_do_eh(ap, adma_prereset, ata_std_softreset, NULL,
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
static int adma_fill_sg(struct ata_queued_cmd *qc)
|
||||
|
@ -464,14 +484,33 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host)
|
|||
pp = ap->private_data;
|
||||
if (!pp || pp->state != adma_state_pkt)
|
||||
continue;
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
|
||||
if ((status & (aPERR | aPSD | aUIRQ)))
|
||||
if (status & aPERR)
|
||||
qc->err_mask |= AC_ERR_HOST_BUS;
|
||||
else if ((status & (aPSD | aUIRQ)))
|
||||
qc->err_mask |= AC_ERR_OTHER;
|
||||
|
||||
if (pp->pkt[0] & cATERR)
|
||||
qc->err_mask |= AC_ERR_DEV;
|
||||
else if (pp->pkt[0] != cDONE)
|
||||
qc->err_mask |= AC_ERR_OTHER;
|
||||
|
||||
ata_qc_complete(qc);
|
||||
if (!qc->err_mask)
|
||||
ata_qc_complete(qc);
|
||||
else {
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
ata_ehi_clear_desc(ehi);
|
||||
ata_ehi_push_desc(ehi,
|
||||
"ADMA-status 0x%02X", status);
|
||||
ata_ehi_push_desc(ehi,
|
||||
"pkt[0] 0x%02X", pp->pkt[0]);
|
||||
|
||||
if (qc->err_mask == AC_ERR_DEV)
|
||||
ata_port_abort(ap);
|
||||
else
|
||||
ata_port_freeze(ap);
|
||||
}
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
|
@ -489,7 +528,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host)
|
|||
struct adma_port_priv *pp = ap->private_data;
|
||||
if (!pp || pp->state != adma_state_mmio)
|
||||
continue;
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
|
||||
|
||||
/* check main status, clearing INTRQ */
|
||||
|
@ -502,7 +541,20 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host)
|
|||
/* complete taskfile transaction */
|
||||
pp->state = adma_state_idle;
|
||||
qc->err_mask |= ac_err_mask(status);
|
||||
ata_qc_complete(qc);
|
||||
if (!qc->err_mask)
|
||||
ata_qc_complete(qc);
|
||||
else {
|
||||
struct ata_eh_info *ehi =
|
||||
&ap->link.eh_info;
|
||||
ata_ehi_clear_desc(ehi);
|
||||
ata_ehi_push_desc(ehi,
|
||||
"status 0x%02X", status);
|
||||
|
||||
if (qc->err_mask == AC_ERR_DEV)
|
||||
ata_port_abort(ap);
|
||||
else
|
||||
ata_port_freeze(ap);
|
||||
}
|
||||
handled = 1;
|
||||
}
|
||||
}
|
||||
|
@ -652,9 +704,16 @@ static int adma_ata_init_one(struct pci_dev *pdev,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
|
||||
adma_ata_setup_port(&host->ports[port_no]->ioaddr,
|
||||
ADMA_ATA_REGS(mmio_base, port_no));
|
||||
for (port_no = 0; port_no < ADMA_PORTS; ++port_no) {
|
||||
struct ata_port *ap = host->ports[port_no];
|
||||
void __iomem *port_base = ADMA_ATA_REGS(mmio_base, port_no);
|
||||
unsigned int offset = port_base - mmio_base;
|
||||
|
||||
adma_ata_setup_port(&ap->ioaddr, port_base);
|
||||
|
||||
ata_port_pbar_desc(ap, ADMA_MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, ADMA_MMIO_BAR, offset, "port");
|
||||
}
|
||||
|
||||
/* initialize adapter */
|
||||
adma_host_init(host, board_idx);
|
||||
|
|
|
@ -285,7 +285,7 @@ static void inic_irq_clear(struct ata_port *ap)
|
|||
static void inic_host_intr(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_base = inic_port_base(ap);
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
u8 irq_stat;
|
||||
|
||||
/* fetch and clear irq */
|
||||
|
@ -293,7 +293,8 @@ static void inic_host_intr(struct ata_port *ap)
|
|||
writeb(irq_stat, port_base + PORT_IRQ_STAT);
|
||||
|
||||
if (likely(!(irq_stat & PIRQ_ERR))) {
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
struct ata_queued_cmd *qc =
|
||||
ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
|
||||
if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
|
||||
ata_chk_status(ap); /* clear ATA interrupt */
|
||||
|
@ -416,12 +417,13 @@ static void inic_thaw(struct ata_port *ap)
|
|||
* SRST and SControl hardreset don't give valid signature on this
|
||||
* controller. Only controller specific hardreset mechanism works.
|
||||
*/
|
||||
static int inic_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
static int inic_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
void __iomem *port_base = inic_port_base(ap);
|
||||
void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
|
||||
const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
|
||||
const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
|
||||
u16 val;
|
||||
int rc;
|
||||
|
||||
|
@ -434,15 +436,15 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
msleep(1);
|
||||
writew(val & ~IDMA_CTL_RST_ATA, idma_ctl);
|
||||
|
||||
rc = sata_phy_resume(ap, timing, deadline);
|
||||
rc = sata_link_resume(link, timing, deadline);
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_WARNING, "failed to resume "
|
||||
ata_link_printk(link, KERN_WARNING, "failed to resume "
|
||||
"link after reset (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*class = ATA_DEV_NONE;
|
||||
if (ata_port_online(ap)) {
|
||||
if (ata_link_online(link)) {
|
||||
struct ata_taskfile tf;
|
||||
|
||||
/* wait a while before checking status */
|
||||
|
@ -451,7 +453,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
rc = ata_wait_ready(ap, deadline);
|
||||
/* link occupied, -ENODEV too is an error */
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_WARNING, "device not ready "
|
||||
ata_link_printk(link, KERN_WARNING, "device not ready "
|
||||
"after hardreset (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
@ -550,7 +552,6 @@ static int inic_port_start(struct ata_port *ap)
|
|||
}
|
||||
|
||||
static struct ata_port_operations inic_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -567,7 +568,6 @@ static struct ata_port_operations inic_port_ops = {
|
|||
|
||||
.irq_clear = inic_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = inic_qc_issue,
|
||||
|
@ -693,16 +693,24 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
host->iomap = iomap = pcim_iomap_table(pdev);
|
||||
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
struct ata_ioports *port = &host->ports[i]->ioaddr;
|
||||
void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
|
||||
struct ata_port *ap = host->ports[i];
|
||||
struct ata_ioports *port = &ap->ioaddr;
|
||||
unsigned int offset = i * PORT_SIZE;
|
||||
|
||||
port->cmd_addr = iomap[2 * i];
|
||||
port->altstatus_addr =
|
||||
port->ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
|
||||
port->scr_addr = port_base + PORT_SCR;
|
||||
port->scr_addr = iomap[MMIO_BAR] + offset + PORT_SCR;
|
||||
|
||||
ata_std_ports(port);
|
||||
|
||||
ata_port_pbar_desc(ap, MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, MMIO_BAR, offset, "port");
|
||||
ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
|
||||
(unsigned long long)pci_resource_start(pdev, 2 * i),
|
||||
(unsigned long long)pci_resource_start(pdev, (2 * i + 1)) |
|
||||
ATA_PCI_CTL_OFS);
|
||||
}
|
||||
|
||||
hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
|
||||
|
|
|
@ -483,8 +483,6 @@ static struct scsi_host_template mv6_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations mv5_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -499,7 +497,6 @@ static const struct ata_port_operations mv5_ops = {
|
|||
|
||||
.irq_clear = mv_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.error_handler = mv_error_handler,
|
||||
.post_internal_cmd = mv_post_int_cmd,
|
||||
|
@ -514,8 +511,6 @@ static const struct ata_port_operations mv5_ops = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations mv6_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -530,7 +525,6 @@ static const struct ata_port_operations mv6_ops = {
|
|||
|
||||
.irq_clear = mv_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.error_handler = mv_error_handler,
|
||||
.post_internal_cmd = mv_post_int_cmd,
|
||||
|
@ -545,8 +539,6 @@ static const struct ata_port_operations mv6_ops = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations mv_iie_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -561,7 +553,6 @@ static const struct ata_port_operations mv_iie_ops = {
|
|||
|
||||
.irq_clear = mv_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.error_handler = mv_error_handler,
|
||||
.post_internal_cmd = mv_post_int_cmd,
|
||||
|
@ -1415,7 +1406,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
|
|||
struct mv_host_priv *hpriv = ap->host->private_data;
|
||||
unsigned int edma_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN);
|
||||
unsigned int action = 0, err_mask = 0;
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
|
||||
ata_ehi_clear_desc(ehi);
|
||||
|
||||
|
@ -1423,8 +1414,8 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
|
|||
/* just a guess: do we need to do this? should we
|
||||
* expand this, and do it in all cases?
|
||||
*/
|
||||
sata_scr_read(ap, SCR_ERROR, &serr);
|
||||
sata_scr_write_flush(ap, SCR_ERROR, serr);
|
||||
sata_scr_read(&ap->link, SCR_ERROR, &serr);
|
||||
sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
|
||||
}
|
||||
|
||||
edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
|
||||
|
@ -1468,8 +1459,8 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
|
|||
}
|
||||
|
||||
if (edma_err_cause & EDMA_ERR_SERR) {
|
||||
sata_scr_read(ap, SCR_ERROR, &serr);
|
||||
sata_scr_write_flush(ap, SCR_ERROR, serr);
|
||||
sata_scr_read(&ap->link, SCR_ERROR, &serr);
|
||||
sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
|
||||
err_mask = AC_ERR_ATA_BUS;
|
||||
action |= ATA_EH_HARDRESET;
|
||||
}
|
||||
|
@ -1508,7 +1499,7 @@ static void mv_intr_pio(struct ata_port *ap)
|
|||
return;
|
||||
|
||||
/* get active ATA command */
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (unlikely(!qc)) /* no active tag */
|
||||
return;
|
||||
if (qc->tf.flags & ATA_TFLAG_POLLING) /* polling; we don't own qc */
|
||||
|
@ -1543,7 +1534,7 @@ static void mv_intr_edma(struct ata_port *ap)
|
|||
|
||||
/* 50xx: get active ATA command */
|
||||
if (IS_GEN_I(hpriv))
|
||||
tag = ap->active_tag;
|
||||
tag = ap->link.active_tag;
|
||||
|
||||
/* Gen II/IIE: get active ATA command via tag, to enable
|
||||
* support for queueing. this works transparently for
|
||||
|
@ -1646,7 +1637,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
|
|||
if (unlikely(have_err_bits)) {
|
||||
struct ata_queued_cmd *qc;
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
|
||||
continue;
|
||||
|
||||
|
@ -1687,15 +1678,15 @@ static void mv_pci_error(struct ata_host *host, void __iomem *mmio)
|
|||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
ap = host->ports[i];
|
||||
if (!ata_port_offline(ap)) {
|
||||
ehi = &ap->eh_info;
|
||||
if (!ata_link_offline(&ap->link)) {
|
||||
ehi = &ap->link.eh_info;
|
||||
ata_ehi_clear_desc(ehi);
|
||||
if (!printed++)
|
||||
ata_ehi_push_desc(ehi,
|
||||
"PCI err cause 0x%08x", err_cause);
|
||||
err_mask = AC_ERR_HOST_BUS;
|
||||
ehi->action = ATA_EH_HARDRESET;
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc)
|
||||
qc->err_mask |= err_mask;
|
||||
else
|
||||
|
@ -2198,14 +2189,14 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
|
|||
|
||||
/* Issue COMRESET via SControl */
|
||||
comreset_retry:
|
||||
sata_scr_write_flush(ap, SCR_CONTROL, 0x301);
|
||||
sata_scr_write_flush(&ap->link, SCR_CONTROL, 0x301);
|
||||
msleep(1);
|
||||
|
||||
sata_scr_write_flush(ap, SCR_CONTROL, 0x300);
|
||||
sata_scr_write_flush(&ap->link, SCR_CONTROL, 0x300);
|
||||
msleep(20);
|
||||
|
||||
do {
|
||||
sata_scr_read(ap, SCR_STATUS, &sstatus);
|
||||
sata_scr_read(&ap->link, SCR_STATUS, &sstatus);
|
||||
if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0))
|
||||
break;
|
||||
|
||||
|
@ -2230,7 +2221,7 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (ata_port_offline(ap)) {
|
||||
if (ata_link_offline(&ap->link)) {
|
||||
*class = ATA_DEV_NONE;
|
||||
return;
|
||||
}
|
||||
|
@ -2257,7 +2248,7 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
|
|||
*/
|
||||
|
||||
/* finally, read device signature from TF registers */
|
||||
*class = ata_dev_try_classify(ap, 0, NULL);
|
||||
*class = ata_dev_try_classify(ap->link.device, 1, NULL);
|
||||
|
||||
writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
|
||||
|
||||
|
@ -2266,10 +2257,11 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
|
|||
VPRINTK("EXIT\n");
|
||||
}
|
||||
|
||||
static int mv_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
static int mv_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct mv_port_priv *pp = ap->private_data;
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
int rc;
|
||||
|
||||
rc = mv_stop_dma(ap);
|
||||
|
@ -2285,7 +2277,7 @@ static int mv_prereset(struct ata_port *ap, unsigned long deadline)
|
|||
if (ehc->i.action & ATA_EH_HARDRESET)
|
||||
return 0;
|
||||
|
||||
if (ata_port_online(ap))
|
||||
if (ata_link_online(link))
|
||||
rc = ata_wait_ready(ap, deadline);
|
||||
else
|
||||
rc = -ENODEV;
|
||||
|
@ -2293,9 +2285,10 @@ static int mv_prereset(struct ata_port *ap, unsigned long deadline)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int mv_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
static int mv_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct mv_host_priv *hpriv = ap->host->private_data;
|
||||
void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
|
||||
|
||||
|
@ -2308,16 +2301,17 @@ static int mv_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mv_postreset(struct ata_port *ap, unsigned int *classes)
|
||||
static void mv_postreset(struct ata_link *link, unsigned int *classes)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
u32 serr;
|
||||
|
||||
/* print link status */
|
||||
sata_print_link_status(ap);
|
||||
sata_print_link_status(link);
|
||||
|
||||
/* clear SError */
|
||||
sata_scr_read(ap, SCR_ERROR, &serr);
|
||||
sata_scr_write_flush(ap, SCR_ERROR, serr);
|
||||
sata_scr_read(link, SCR_ERROR, &serr);
|
||||
sata_scr_write_flush(link, SCR_ERROR, serr);
|
||||
|
||||
/* bail out if no device is present */
|
||||
if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
|
||||
|
@ -2590,8 +2584,14 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
|
|||
}
|
||||
|
||||
for (port = 0; port < host->n_ports; port++) {
|
||||
struct ata_port *ap = host->ports[port];
|
||||
void __iomem *port_mmio = mv_port_base(mmio, port);
|
||||
mv_port_init(&host->ports[port]->ioaddr, port_mmio);
|
||||
unsigned int offset = port_mmio - mmio;
|
||||
|
||||
mv_port_init(&ap->ioaddr, port_mmio);
|
||||
|
||||
ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
|
||||
}
|
||||
|
||||
for (hc = 0; hc < n_hc; hc++) {
|
||||
|
|
|
@ -340,7 +340,6 @@ static struct scsi_host_template nv_adma_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations nv_generic_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.exec_command = ata_exec_command,
|
||||
|
@ -359,14 +358,12 @@ static const struct ata_port_operations nv_generic_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = nv_scr_read,
|
||||
.scr_write = nv_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations nv_nf2_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.exec_command = ata_exec_command,
|
||||
|
@ -385,14 +382,12 @@ static const struct ata_port_operations nv_nf2_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = nv_scr_read,
|
||||
.scr_write = nv_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations nv_ck804_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.exec_command = ata_exec_command,
|
||||
|
@ -411,7 +406,6 @@ static const struct ata_port_operations nv_ck804_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = nv_scr_read,
|
||||
.scr_write = nv_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
|
@ -419,7 +413,6 @@ static const struct ata_port_operations nv_ck804_ops = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations nv_adma_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = nv_adma_tf_read,
|
||||
.check_atapi_dma = nv_adma_check_atapi_dma,
|
||||
|
@ -430,6 +423,7 @@ static const struct ata_port_operations nv_adma_ops = {
|
|||
.bmdma_start = ata_bmdma_start,
|
||||
.bmdma_stop = ata_bmdma_stop,
|
||||
.bmdma_status = ata_bmdma_status,
|
||||
.qc_defer = ata_std_qc_defer,
|
||||
.qc_prep = nv_adma_qc_prep,
|
||||
.qc_issue = nv_adma_qc_issue,
|
||||
.freeze = nv_adma_freeze,
|
||||
|
@ -439,7 +433,6 @@ static const struct ata_port_operations nv_adma_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = nv_adma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = nv_scr_read,
|
||||
.scr_write = nv_scr_write,
|
||||
.port_start = nv_adma_port_start,
|
||||
|
@ -455,8 +448,8 @@ static const struct ata_port_info nv_port_info[] = {
|
|||
/* generic */
|
||||
{
|
||||
.sht = &nv_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_HRST_TO_RESUME,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
|
||||
.link_flags = ATA_LFLAG_HRST_TO_RESUME,
|
||||
.pio_mask = NV_PIO_MASK,
|
||||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
|
@ -466,8 +459,8 @@ static const struct ata_port_info nv_port_info[] = {
|
|||
/* nforce2/3 */
|
||||
{
|
||||
.sht = &nv_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_HRST_TO_RESUME,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
|
||||
.link_flags = ATA_LFLAG_HRST_TO_RESUME,
|
||||
.pio_mask = NV_PIO_MASK,
|
||||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
|
@ -477,8 +470,8 @@ static const struct ata_port_info nv_port_info[] = {
|
|||
/* ck804 */
|
||||
{
|
||||
.sht = &nv_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_HRST_TO_RESUME,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
|
||||
.link_flags = ATA_LFLAG_HRST_TO_RESUME,
|
||||
.pio_mask = NV_PIO_MASK,
|
||||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
|
@ -489,8 +482,8 @@ static const struct ata_port_info nv_port_info[] = {
|
|||
{
|
||||
.sht = &nv_adma_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_HRST_TO_RESUME |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_NCQ,
|
||||
.link_flags = ATA_LFLAG_HRST_TO_RESUME,
|
||||
.pio_mask = NV_PIO_MASK,
|
||||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
|
@ -594,7 +587,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
|
|||
/* Not a proper libata device, ignore */
|
||||
return rc;
|
||||
|
||||
if (ap->device[sdev->id].class == ATA_DEV_ATAPI) {
|
||||
if (ap->link.device[sdev->id].class == ATA_DEV_ATAPI) {
|
||||
/*
|
||||
* NVIDIA reports that ADMA mode does not support ATAPI commands.
|
||||
* Therefore ATAPI commands are sent through the legacy interface.
|
||||
|
@ -711,7 +704,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
|
|||
flags & (NV_CPB_RESP_ATA_ERR |
|
||||
NV_CPB_RESP_CMD_ERR |
|
||||
NV_CPB_RESP_CPB_ERR)))) {
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
int freeze = 0;
|
||||
|
||||
ata_ehi_clear_desc(ehi);
|
||||
|
@ -747,7 +740,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
|
|||
DPRINTK("Completing qc from tag %d\n",cpb_num);
|
||||
ata_qc_complete(qc);
|
||||
} else {
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
/* Notifier bits set without a command may indicate the drive
|
||||
is misbehaving. Raise host state machine violation on this
|
||||
condition. */
|
||||
|
@ -764,7 +757,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
|
|||
|
||||
static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
|
||||
{
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
|
||||
/* freeze if hotplugged */
|
||||
if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) {
|
||||
|
@ -817,7 +810,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
|
|||
if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
|
||||
u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804)
|
||||
>> (NV_INT_PORT_SHIFT * i);
|
||||
if(ata_tag_valid(ap->active_tag))
|
||||
if(ata_tag_valid(ap->link.active_tag))
|
||||
/** NV_INT_DEV indication seems unreliable at times
|
||||
at least in ADMA mode. Force it on always when a
|
||||
command is active, to prevent losing interrupts. */
|
||||
|
@ -852,7 +845,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
|
|||
NV_ADMA_STAT_HOTUNPLUG |
|
||||
NV_ADMA_STAT_TIMEOUT |
|
||||
NV_ADMA_STAT_SERROR))) {
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
|
||||
ata_ehi_clear_desc(ehi);
|
||||
__ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status );
|
||||
|
@ -879,10 +872,10 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
|
|||
u32 check_commands;
|
||||
int pos, error = 0;
|
||||
|
||||
if(ata_tag_valid(ap->active_tag))
|
||||
check_commands = 1 << ap->active_tag;
|
||||
if(ata_tag_valid(ap->link.active_tag))
|
||||
check_commands = 1 << ap->link.active_tag;
|
||||
else
|
||||
check_commands = ap->sactive;
|
||||
check_commands = ap->link.sactive;
|
||||
|
||||
/** Check CPBs for completed commands */
|
||||
while ((pos = ffs(check_commands)) && !error) {
|
||||
|
@ -1333,7 +1326,7 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
|
|||
!(ap->flags & ATA_FLAG_DISABLED)) {
|
||||
struct ata_queued_cmd *qc;
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
|
||||
handled += ata_host_intr(ap, qc);
|
||||
else
|
||||
|
@ -1459,7 +1452,7 @@ static void nv_ck804_thaw(struct ata_port *ap)
|
|||
writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
|
||||
}
|
||||
|
||||
static int nv_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
static int nv_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
unsigned int dummy;
|
||||
|
@ -1468,7 +1461,7 @@ static int nv_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
* some controllers. Don't classify on hardreset. For more
|
||||
* info, see http://bugme.osdl.org/show_bug.cgi?id=3352
|
||||
*/
|
||||
return sata_std_hardreset(ap, &dummy, deadline);
|
||||
return sata_std_hardreset(link, &dummy, deadline);
|
||||
}
|
||||
|
||||
static void nv_error_handler(struct ata_port *ap)
|
||||
|
@ -1485,7 +1478,7 @@ static void nv_adma_error_handler(struct ata_port *ap)
|
|||
int i;
|
||||
u16 tmp;
|
||||
|
||||
if(ata_tag_valid(ap->active_tag) || ap->sactive) {
|
||||
if(ata_tag_valid(ap->link.active_tag) || ap->link.sactive) {
|
||||
u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
|
||||
u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
|
||||
u32 gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL);
|
||||
|
@ -1501,8 +1494,8 @@ static void nv_adma_error_handler(struct ata_port *ap)
|
|||
|
||||
for( i=0;i<NV_ADMA_MAX_CPBS;i++) {
|
||||
struct nv_adma_cpb *cpb = &pp->cpb[i];
|
||||
if( (ata_tag_valid(ap->active_tag) && i == ap->active_tag) ||
|
||||
ap->sactive & (1 << i) )
|
||||
if( (ata_tag_valid(ap->link.active_tag) && i == ap->link.active_tag) ||
|
||||
ap->link.sactive & (1 << i) )
|
||||
ata_port_printk(ap, KERN_ERR,
|
||||
"CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n",
|
||||
i, cpb->ctl_flags, cpb->resp_flags);
|
||||
|
|
|
@ -167,7 +167,6 @@ static struct scsi_host_template pdc_ata_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations pdc_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = pdc_tf_load_mmio,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -185,7 +184,6 @@ static const struct ata_port_operations pdc_sata_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = pdc_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.scr_read = pdc_sata_scr_read,
|
||||
.scr_write = pdc_sata_scr_write,
|
||||
|
@ -194,7 +192,6 @@ static const struct ata_port_operations pdc_sata_ops = {
|
|||
|
||||
/* First-generation chips need a more restrictive ->check_atapi_dma op */
|
||||
static const struct ata_port_operations pdc_old_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = pdc_tf_load_mmio,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -212,7 +209,6 @@ static const struct ata_port_operations pdc_old_sata_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = pdc_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.scr_read = pdc_sata_scr_read,
|
||||
.scr_write = pdc_sata_scr_write,
|
||||
|
@ -220,7 +216,6 @@ static const struct ata_port_operations pdc_old_sata_ops = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations pdc_pata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = pdc_tf_load_mmio,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -238,7 +233,6 @@ static const struct ata_port_operations pdc_pata_ops = {
|
|||
.data_xfer = ata_data_xfer,
|
||||
.irq_clear = pdc_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = pdc_common_port_start,
|
||||
};
|
||||
|
@ -475,7 +469,7 @@ static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
|
|||
buf32[2] = 0; /* no next-packet */
|
||||
|
||||
/* select drive */
|
||||
if (sata_scr_valid(ap)) {
|
||||
if (sata_scr_valid(&ap->link)) {
|
||||
dev_sel = PDC_DEVICE_SATA;
|
||||
} else {
|
||||
dev_sel = ATA_DEVICE_OBS;
|
||||
|
@ -626,7 +620,7 @@ static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
|
|||
static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
|
||||
u32 port_status, u32 err_mask)
|
||||
{
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
unsigned int ac_err_mask = 0;
|
||||
|
||||
ata_ehi_clear_desc(ehi);
|
||||
|
@ -643,7 +637,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
|
|||
| PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR))
|
||||
ac_err_mask |= AC_ERR_HOST_BUS;
|
||||
|
||||
if (sata_scr_valid(ap)) {
|
||||
if (sata_scr_valid(&ap->link)) {
|
||||
u32 serror;
|
||||
|
||||
pdc_sata_scr_read(ap, SCR_ERROR, &serror);
|
||||
|
@ -773,7 +767,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
|
|||
tmp = hotplug_status & (0x11 << ata_no);
|
||||
if (tmp && ap &&
|
||||
!(ap->flags & ATA_FLAG_DISABLED)) {
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
ata_ehi_clear_desc(ehi);
|
||||
ata_ehi_hotplugged(ehi);
|
||||
ata_ehi_push_desc(ehi, "hotplug_status %#x", tmp);
|
||||
|
@ -788,7 +782,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
|
|||
!(ap->flags & ATA_FLAG_DISABLED)) {
|
||||
struct ata_queued_cmd *qc;
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
|
||||
handled += pdc_host_intr(ap, qc);
|
||||
}
|
||||
|
@ -1009,10 +1003,15 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
|
||||
is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags);
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
|
||||
pdc_ata_setup_port(host->ports[i],
|
||||
base + 0x200 + ata_no * 0x80,
|
||||
base + 0x400 + ata_no * 0x100);
|
||||
unsigned int port_offset = 0x200 + ata_no * 0x80;
|
||||
unsigned int scr_offset = 0x400 + ata_no * 0x100;
|
||||
|
||||
pdc_ata_setup_port(ap, base + port_offset, base + scr_offset);
|
||||
|
||||
ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, PDC_MMIO_BAR, port_offset, "port");
|
||||
}
|
||||
|
||||
/* initialize adapter */
|
||||
|
|
|
@ -145,7 +145,6 @@ static struct scsi_host_template qs_ata_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations qs_ata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -159,7 +158,6 @@ static const struct ata_port_operations qs_ata_ops = {
|
|||
.eng_timeout = qs_eng_timeout,
|
||||
.irq_clear = qs_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = qs_scr_read,
|
||||
.scr_write = qs_scr_write,
|
||||
.port_start = qs_port_start,
|
||||
|
@ -404,7 +402,7 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)
|
|||
struct qs_port_priv *pp = ap->private_data;
|
||||
if (!pp || pp->state != qs_state_pkt)
|
||||
continue;
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
|
||||
switch (sHST) {
|
||||
case 0: /* successful CPB */
|
||||
|
@ -437,7 +435,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
|
|||
struct qs_port_priv *pp = ap->private_data;
|
||||
if (!pp || pp->state != qs_state_mmio)
|
||||
continue;
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
|
||||
|
||||
/* check main status, clearing INTRQ */
|
||||
|
@ -637,9 +635,14 @@ static int qs_ata_init_one(struct pci_dev *pdev,
|
|||
return rc;
|
||||
|
||||
for (port_no = 0; port_no < host->n_ports; ++port_no) {
|
||||
void __iomem *chan =
|
||||
host->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
|
||||
qs_ata_setup_port(&host->ports[port_no]->ioaddr, chan);
|
||||
struct ata_port *ap = host->ports[port_no];
|
||||
unsigned int offset = port_no * 0x4000;
|
||||
void __iomem *chan = host->iomap[QS_MMIO_BAR] + offset;
|
||||
|
||||
qs_ata_setup_port(&ap->ioaddr, chan);
|
||||
|
||||
ata_port_pbar_desc(ap, QS_MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, QS_MMIO_BAR, offset, "port");
|
||||
}
|
||||
|
||||
/* initialize adapter */
|
||||
|
|
|
@ -59,7 +59,8 @@ enum {
|
|||
SIL_FLAG_MOD15WRITE = (1 << 30),
|
||||
|
||||
SIL_DFL_PORT_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_HRST_TO_RESUME,
|
||||
ATA_FLAG_MMIO,
|
||||
SIL_DFL_LINK_FLAGS = ATA_LFLAG_HRST_TO_RESUME,
|
||||
|
||||
/*
|
||||
* Controller IDs
|
||||
|
@ -117,7 +118,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev);
|
|||
static void sil_dev_config(struct ata_device *dev);
|
||||
static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
|
||||
static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
|
||||
static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed);
|
||||
static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed);
|
||||
static void sil_freeze(struct ata_port *ap);
|
||||
static void sil_thaw(struct ata_port *ap);
|
||||
|
||||
|
@ -185,7 +186,6 @@ static struct scsi_host_template sil_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations sil_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.dev_config = sil_dev_config,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -206,7 +206,6 @@ static const struct ata_port_operations sil_ops = {
|
|||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = sil_scr_read,
|
||||
.scr_write = sil_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
|
@ -216,6 +215,7 @@ static const struct ata_port_info sil_port_info[] = {
|
|||
/* sil_3112 */
|
||||
{
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
|
||||
.link_flags = SIL_DFL_LINK_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = ATA_UDMA5,
|
||||
|
@ -225,6 +225,7 @@ static const struct ata_port_info sil_port_info[] = {
|
|||
{
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
|
||||
SIL_FLAG_NO_SATA_IRQ,
|
||||
.link_flags = SIL_DFL_LINK_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = ATA_UDMA5,
|
||||
|
@ -233,6 +234,7 @@ static const struct ata_port_info sil_port_info[] = {
|
|||
/* sil_3512 */
|
||||
{
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
|
||||
.link_flags = SIL_DFL_LINK_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = ATA_UDMA5,
|
||||
|
@ -241,6 +243,7 @@ static const struct ata_port_info sil_port_info[] = {
|
|||
/* sil_3114 */
|
||||
{
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
|
||||
.link_flags = SIL_DFL_LINK_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = ATA_UDMA5,
|
||||
|
@ -290,35 +293,33 @@ static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
|
|||
|
||||
/**
|
||||
* sil_set_mode - wrap set_mode functions
|
||||
* @ap: port to set up
|
||||
* @link: link to set up
|
||||
* @r_failed: returned device when we fail
|
||||
*
|
||||
* Wrap the libata method for device setup as after the setup we need
|
||||
* to inspect the results and do some configuration work
|
||||
*/
|
||||
|
||||
static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed)
|
||||
static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed)
|
||||
{
|
||||
struct ata_host *host = ap->host;
|
||||
struct ata_device *dev;
|
||||
void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
|
||||
struct ata_port *ap = link->ap;
|
||||
void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
|
||||
void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
|
||||
u32 tmp, dev_mode[2];
|
||||
unsigned int i;
|
||||
struct ata_device *dev;
|
||||
u32 tmp, dev_mode[2] = { };
|
||||
int rc;
|
||||
|
||||
rc = ata_do_set_mode(ap, r_failed);
|
||||
rc = ata_do_set_mode(link, r_failed);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
dev = &ap->device[i];
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
dev_mode[i] = 0; /* PIO0/1/2 */
|
||||
dev_mode[dev->devno] = 0; /* PIO0/1/2 */
|
||||
else if (dev->flags & ATA_DFLAG_PIO)
|
||||
dev_mode[i] = 1; /* PIO3/4 */
|
||||
dev_mode[dev->devno] = 1; /* PIO3/4 */
|
||||
else
|
||||
dev_mode[i] = 3; /* UDMA */
|
||||
dev_mode[dev->devno] = 3; /* UDMA */
|
||||
/* value 2 indicates MDMA */
|
||||
}
|
||||
|
||||
|
@ -374,8 +375,8 @@ static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
|
|||
|
||||
static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
|
||||
{
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
u8 status;
|
||||
|
||||
if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) {
|
||||
|
@ -394,8 +395,8 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
|
|||
* repeat probing needlessly.
|
||||
*/
|
||||
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
|
||||
ata_ehi_hotplugged(&ap->eh_info);
|
||||
ap->eh_info.serror |= serror;
|
||||
ata_ehi_hotplugged(&ap->link.eh_info);
|
||||
ap->link.eh_info.serror |= serror;
|
||||
}
|
||||
|
||||
goto freeze;
|
||||
|
@ -562,8 +563,8 @@ static void sil_thaw(struct ata_port *ap)
|
|||
*/
|
||||
static void sil_dev_config(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
int print_info = ap->link.eh_context.i.flags & ATA_EHI_PRINTINFO;
|
||||
unsigned int n, quirks = 0;
|
||||
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
||||
|
||||
|
@ -686,7 +687,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
mmio_base = host->iomap[SIL_MMIO_BAR];
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
|
||||
struct ata_port *ap = host->ports[i];
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
ioaddr->cmd_addr = mmio_base + sil_port[i].tf;
|
||||
ioaddr->altstatus_addr =
|
||||
|
@ -694,6 +696,9 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
|
||||
ioaddr->scr_addr = mmio_base + sil_port[i].scr;
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
ata_port_pbar_desc(ap, SIL_MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, SIL_MMIO_BAR, sil_port[i].tf, "tf");
|
||||
}
|
||||
|
||||
/* initialize and activate */
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "sata_sil24"
|
||||
#define DRV_VERSION "1.0"
|
||||
#define DRV_VERSION "1.1"
|
||||
|
||||
/*
|
||||
* Port request block (PRB) 32 bytes
|
||||
|
@ -168,7 +168,7 @@ enum {
|
|||
|
||||
DEF_PORT_IRQ = PORT_IRQ_COMPLETE | PORT_IRQ_ERROR |
|
||||
PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG |
|
||||
PORT_IRQ_UNK_FIS,
|
||||
PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_NOTIFY,
|
||||
|
||||
/* bits[27:16] are unmasked (raw) */
|
||||
PORT_IRQ_RAW_SHIFT = 16,
|
||||
|
@ -237,8 +237,9 @@ enum {
|
|||
/* host flags */
|
||||
SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY |
|
||||
ATA_FLAG_ACPI_SATA,
|
||||
ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA |
|
||||
ATA_FLAG_AN | ATA_FLAG_PMP,
|
||||
SIL24_COMMON_LFLAGS = ATA_LFLAG_SKIP_D2H_BSY,
|
||||
SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
|
||||
|
||||
IRQ_STAT_4PORTS = 0xf,
|
||||
|
@ -322,6 +323,7 @@ struct sil24_port_priv {
|
|||
union sil24_cmd_block *cmd_block; /* 32 cmd blocks */
|
||||
dma_addr_t cmd_block_dma; /* DMA base addr for them */
|
||||
struct ata_taskfile tf; /* Cached taskfile registers */
|
||||
int do_port_rst;
|
||||
};
|
||||
|
||||
static void sil24_dev_config(struct ata_device *dev);
|
||||
|
@ -329,9 +331,12 @@ static u8 sil24_check_status(struct ata_port *ap);
|
|||
static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val);
|
||||
static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
|
||||
static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
|
||||
static int sil24_qc_defer(struct ata_queued_cmd *qc);
|
||||
static void sil24_qc_prep(struct ata_queued_cmd *qc);
|
||||
static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
|
||||
static void sil24_irq_clear(struct ata_port *ap);
|
||||
static void sil24_pmp_attach(struct ata_port *ap);
|
||||
static void sil24_pmp_detach(struct ata_port *ap);
|
||||
static void sil24_freeze(struct ata_port *ap);
|
||||
static void sil24_thaw(struct ata_port *ap);
|
||||
static void sil24_error_handler(struct ata_port *ap);
|
||||
|
@ -340,6 +345,7 @@ static int sil24_port_start(struct ata_port *ap);
|
|||
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
#ifdef CONFIG_PM
|
||||
static int sil24_pci_device_resume(struct pci_dev *pdev);
|
||||
static int sil24_port_resume(struct ata_port *ap);
|
||||
#endif
|
||||
|
||||
static const struct pci_device_id sil24_pci_tbl[] = {
|
||||
|
@ -384,8 +390,6 @@ static struct scsi_host_template sil24_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations sil24_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.dev_config = sil24_dev_config,
|
||||
|
||||
.check_status = sil24_check_status,
|
||||
|
@ -394,22 +398,28 @@ static const struct ata_port_operations sil24_ops = {
|
|||
|
||||
.tf_read = sil24_tf_read,
|
||||
|
||||
.qc_defer = sil24_qc_defer,
|
||||
.qc_prep = sil24_qc_prep,
|
||||
.qc_issue = sil24_qc_issue,
|
||||
|
||||
.irq_clear = sil24_irq_clear,
|
||||
.irq_on = ata_dummy_irq_on,
|
||||
.irq_ack = ata_dummy_irq_ack,
|
||||
|
||||
.scr_read = sil24_scr_read,
|
||||
.scr_write = sil24_scr_write,
|
||||
|
||||
.pmp_attach = sil24_pmp_attach,
|
||||
.pmp_detach = sil24_pmp_detach,
|
||||
|
||||
.freeze = sil24_freeze,
|
||||
.thaw = sil24_thaw,
|
||||
.error_handler = sil24_error_handler,
|
||||
.post_internal_cmd = sil24_post_internal_cmd,
|
||||
|
||||
.port_start = sil24_port_start,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
.port_resume = sil24_port_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -424,6 +434,7 @@ static const struct ata_port_info sil24_port_info[] = {
|
|||
{
|
||||
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
|
||||
SIL24_FLAG_PCIX_IRQ_WOC,
|
||||
.link_flags = SIL24_COMMON_LFLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = ATA_UDMA5, /* udma0-5 */
|
||||
|
@ -432,6 +443,7 @@ static const struct ata_port_info sil24_port_info[] = {
|
|||
/* sil_3132 */
|
||||
{
|
||||
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
|
||||
.link_flags = SIL24_COMMON_LFLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = ATA_UDMA5, /* udma0-5 */
|
||||
|
@ -440,6 +452,7 @@ static const struct ata_port_info sil24_port_info[] = {
|
|||
/* sil_3131/sil_3531 */
|
||||
{
|
||||
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
|
||||
.link_flags = SIL24_COMMON_LFLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = ATA_UDMA5, /* udma0-5 */
|
||||
|
@ -456,7 +469,7 @@ static int sil24_tag(int tag)
|
|||
|
||||
static void sil24_dev_config(struct ata_device *dev)
|
||||
{
|
||||
void __iomem *port = dev->ap->ioaddr.cmd_addr;
|
||||
void __iomem *port = dev->link->ap->ioaddr.cmd_addr;
|
||||
|
||||
if (dev->cdb_len == 16)
|
||||
writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
|
||||
|
@ -520,19 +533,78 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
*tf = pp->tf;
|
||||
}
|
||||
|
||||
static void sil24_config_port(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
|
||||
/* configure IRQ WoC */
|
||||
if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
|
||||
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
|
||||
else
|
||||
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
|
||||
|
||||
/* zero error counters. */
|
||||
writel(0x8000, port + PORT_DECODE_ERR_THRESH);
|
||||
writel(0x8000, port + PORT_CRC_ERR_THRESH);
|
||||
writel(0x8000, port + PORT_HSHK_ERR_THRESH);
|
||||
writel(0x0000, port + PORT_DECODE_ERR_CNT);
|
||||
writel(0x0000, port + PORT_CRC_ERR_CNT);
|
||||
writel(0x0000, port + PORT_HSHK_ERR_CNT);
|
||||
|
||||
/* always use 64bit activation */
|
||||
writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
|
||||
|
||||
/* clear port multiplier enable and resume bits */
|
||||
writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
|
||||
}
|
||||
|
||||
static void sil24_config_pmp(struct ata_port *ap, int attached)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
|
||||
if (attached)
|
||||
writel(PORT_CS_PMP_EN, port + PORT_CTRL_STAT);
|
||||
else
|
||||
writel(PORT_CS_PMP_EN, port + PORT_CTRL_CLR);
|
||||
}
|
||||
|
||||
static void sil24_clear_pmp(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
int i;
|
||||
|
||||
writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
|
||||
|
||||
for (i = 0; i < SATA_PMP_MAX_PORTS; i++) {
|
||||
void __iomem *pmp_base = port + PORT_PMP + i * PORT_PMP_SIZE;
|
||||
|
||||
writel(0, pmp_base + PORT_PMP_STATUS);
|
||||
writel(0, pmp_base + PORT_PMP_QACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
static int sil24_init_port(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
struct sil24_port_priv *pp = ap->private_data;
|
||||
u32 tmp;
|
||||
|
||||
/* clear PMP error status */
|
||||
if (ap->nr_pmp_links)
|
||||
sil24_clear_pmp(ap);
|
||||
|
||||
writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
|
||||
ata_wait_register(port + PORT_CTRL_STAT,
|
||||
PORT_CS_INIT, PORT_CS_INIT, 10, 100);
|
||||
tmp = ata_wait_register(port + PORT_CTRL_STAT,
|
||||
PORT_CS_RDY, 0, 10, 100);
|
||||
|
||||
if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY)
|
||||
if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY) {
|
||||
pp->do_port_rst = 1;
|
||||
ap->link.eh_context.i.action |= ATA_EH_HARDRESET;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -583,9 +655,10 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int sil24_do_softreset(struct ata_port *ap, unsigned int *class,
|
||||
static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
|
||||
int pmp, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
unsigned long timeout_msec = 0;
|
||||
struct ata_taskfile tf;
|
||||
const char *reason;
|
||||
|
@ -593,7 +666,7 @@ static int sil24_do_softreset(struct ata_port *ap, unsigned int *class,
|
|||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
if (ata_port_offline(ap)) {
|
||||
if (ata_link_offline(link)) {
|
||||
DPRINTK("PHY reports no device\n");
|
||||
*class = ATA_DEV_NONE;
|
||||
goto out;
|
||||
|
@ -609,7 +682,7 @@ static int sil24_do_softreset(struct ata_port *ap, unsigned int *class,
|
|||
if (time_after(deadline, jiffies))
|
||||
timeout_msec = jiffies_to_msecs(deadline - jiffies);
|
||||
|
||||
ata_tf_init(ap->device, &tf); /* doesn't really matter */
|
||||
ata_tf_init(link->device, &tf); /* doesn't really matter */
|
||||
rc = sil24_exec_polled_cmd(ap, pmp, &tf, 0, PRB_CTRL_SRST,
|
||||
timeout_msec);
|
||||
if (rc == -EBUSY) {
|
||||
|
@ -631,29 +704,54 @@ static int sil24_do_softreset(struct ata_port *ap, unsigned int *class,
|
|||
return 0;
|
||||
|
||||
err:
|
||||
ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
|
||||
ata_link_printk(link, KERN_ERR, "softreset failed (%s)\n", reason);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int sil24_softreset(struct ata_port *ap, unsigned int *class,
|
||||
static int sil24_softreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
return sil24_do_softreset(ap, class, 0, deadline);
|
||||
return sil24_do_softreset(link, class, SATA_PMP_CTRL_PORT, deadline);
|
||||
}
|
||||
|
||||
static int sil24_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
static int sil24_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
struct sil24_port_priv *pp = ap->private_data;
|
||||
int did_port_rst = 0;
|
||||
const char *reason;
|
||||
int tout_msec, rc;
|
||||
u32 tmp;
|
||||
|
||||
retry:
|
||||
/* Sometimes, DEV_RST is not enough to recover the controller.
|
||||
* This happens often after PM DMA CS errata.
|
||||
*/
|
||||
if (pp->do_port_rst) {
|
||||
ata_port_printk(ap, KERN_WARNING, "controller in dubious "
|
||||
"state, performing PORT_RST\n");
|
||||
|
||||
writel(PORT_CS_PORT_RST, port + PORT_CTRL_STAT);
|
||||
msleep(10);
|
||||
writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
|
||||
ata_wait_register(port + PORT_CTRL_STAT, PORT_CS_RDY, 0,
|
||||
10, 5000);
|
||||
|
||||
/* restore port configuration */
|
||||
sil24_config_port(ap);
|
||||
sil24_config_pmp(ap, ap->nr_pmp_links);
|
||||
|
||||
pp->do_port_rst = 0;
|
||||
did_port_rst = 1;
|
||||
}
|
||||
|
||||
/* sil24 does the right thing(tm) without any protection */
|
||||
sata_set_spd(ap);
|
||||
sata_set_spd(link);
|
||||
|
||||
tout_msec = 100;
|
||||
if (ata_port_online(ap))
|
||||
if (ata_link_online(link))
|
||||
tout_msec = 5000;
|
||||
|
||||
writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
|
||||
|
@ -663,14 +761,14 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
/* SStatus oscillates between zero and valid status after
|
||||
* DEV_RST, debounce it.
|
||||
*/
|
||||
rc = sata_phy_debounce(ap, sata_deb_timing_long, deadline);
|
||||
rc = sata_link_debounce(link, sata_deb_timing_long, deadline);
|
||||
if (rc) {
|
||||
reason = "PHY debouncing failed";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tmp & PORT_CS_DEV_RST) {
|
||||
if (ata_port_offline(ap))
|
||||
if (ata_link_offline(link))
|
||||
return 0;
|
||||
reason = "link not ready";
|
||||
goto err;
|
||||
|
@ -685,7 +783,12 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class,
|
|||
return -EAGAIN;
|
||||
|
||||
err:
|
||||
ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason);
|
||||
if (!did_port_rst) {
|
||||
pp->do_port_rst = 1;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
ata_link_printk(link, KERN_ERR, "hardreset failed (%s)\n", reason);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -705,6 +808,38 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
|
|||
}
|
||||
}
|
||||
|
||||
static int sil24_qc_defer(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_link *link = qc->dev->link;
|
||||
struct ata_port *ap = link->ap;
|
||||
u8 prot = qc->tf.protocol;
|
||||
int is_atapi = (prot == ATA_PROT_ATAPI ||
|
||||
prot == ATA_PROT_ATAPI_NODATA ||
|
||||
prot == ATA_PROT_ATAPI_DMA);
|
||||
|
||||
/* ATAPI commands completing with CHECK_SENSE cause various
|
||||
* weird problems if other commands are active. PMP DMA CS
|
||||
* errata doesn't cover all and HSM violation occurs even with
|
||||
* only one other device active. Always run an ATAPI command
|
||||
* by itself.
|
||||
*/
|
||||
if (unlikely(ap->excl_link)) {
|
||||
if (link == ap->excl_link) {
|
||||
if (ap->nr_active_links)
|
||||
return ATA_DEFER_PORT;
|
||||
qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
|
||||
} else
|
||||
return ATA_DEFER_PORT;
|
||||
} else if (unlikely(is_atapi)) {
|
||||
ap->excl_link = link;
|
||||
if (ap->nr_active_links)
|
||||
return ATA_DEFER_PORT;
|
||||
qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
|
||||
}
|
||||
|
||||
return ata_std_qc_defer(qc);
|
||||
}
|
||||
|
||||
static void sil24_qc_prep(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
|
@ -748,7 +883,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
|
|||
}
|
||||
|
||||
prb->ctrl = cpu_to_le16(ctrl);
|
||||
ata_tf_to_fis(&qc->tf, 0, 1, prb->fis);
|
||||
ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, prb->fis);
|
||||
|
||||
if (qc->flags & ATA_QCFLAG_DMAMAP)
|
||||
sil24_fill_sg(qc, sge);
|
||||
|
@ -777,6 +912,39 @@ static void sil24_irq_clear(struct ata_port *ap)
|
|||
/* unused */
|
||||
}
|
||||
|
||||
static void sil24_pmp_attach(struct ata_port *ap)
|
||||
{
|
||||
sil24_config_pmp(ap, 1);
|
||||
sil24_init_port(ap);
|
||||
}
|
||||
|
||||
static void sil24_pmp_detach(struct ata_port *ap)
|
||||
{
|
||||
sil24_init_port(ap);
|
||||
sil24_config_pmp(ap, 0);
|
||||
}
|
||||
|
||||
static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
return sil24_do_softreset(link, class, link->pmp, deadline);
|
||||
}
|
||||
|
||||
static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = sil24_init_port(link->ap);
|
||||
if (rc) {
|
||||
ata_link_printk(link, KERN_ERR,
|
||||
"hardreset failed (port not ready)\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return sata_pmp_std_hardreset(link, class, deadline);
|
||||
}
|
||||
|
||||
static void sil24_freeze(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
|
@ -804,8 +972,10 @@ static void sil24_error_intr(struct ata_port *ap)
|
|||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
struct sil24_port_priv *pp = ap->private_data;
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
int freeze = 0;
|
||||
struct ata_queued_cmd *qc = NULL;
|
||||
struct ata_link *link;
|
||||
struct ata_eh_info *ehi;
|
||||
int abort = 0, freeze = 0;
|
||||
u32 irq_stat;
|
||||
|
||||
/* on error, we need to clear IRQ explicitly */
|
||||
|
@ -813,10 +983,17 @@ static void sil24_error_intr(struct ata_port *ap)
|
|||
writel(irq_stat, port + PORT_IRQ_STAT);
|
||||
|
||||
/* first, analyze and record host port events */
|
||||
link = &ap->link;
|
||||
ehi = &link->eh_info;
|
||||
ata_ehi_clear_desc(ehi);
|
||||
|
||||
ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat);
|
||||
|
||||
if (irq_stat & PORT_IRQ_SDB_NOTIFY) {
|
||||
ata_ehi_push_desc(ehi, "SDB notify");
|
||||
sata_async_notification(ap);
|
||||
}
|
||||
|
||||
if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) {
|
||||
ata_ehi_hotplugged(ehi);
|
||||
ata_ehi_push_desc(ehi, "%s",
|
||||
|
@ -836,8 +1013,44 @@ static void sil24_error_intr(struct ata_port *ap)
|
|||
if (irq_stat & PORT_IRQ_ERROR) {
|
||||
struct sil24_cerr_info *ci = NULL;
|
||||
unsigned int err_mask = 0, action = 0;
|
||||
struct ata_queued_cmd *qc;
|
||||
u32 cerr;
|
||||
u32 context, cerr;
|
||||
int pmp;
|
||||
|
||||
abort = 1;
|
||||
|
||||
/* DMA Context Switch Failure in Port Multiplier Mode
|
||||
* errata. If we have active commands to 3 or more
|
||||
* devices, any error condition on active devices can
|
||||
* corrupt DMA context switching.
|
||||
*/
|
||||
if (ap->nr_active_links >= 3) {
|
||||
ehi->err_mask |= AC_ERR_OTHER;
|
||||
ehi->action |= ATA_EH_HARDRESET;
|
||||
ata_ehi_push_desc(ehi, "PMP DMA CS errata");
|
||||
pp->do_port_rst = 1;
|
||||
freeze = 1;
|
||||
}
|
||||
|
||||
/* find out the offending link and qc */
|
||||
if (ap->nr_pmp_links) {
|
||||
context = readl(port + PORT_CONTEXT);
|
||||
pmp = (context >> 5) & 0xf;
|
||||
|
||||
if (pmp < ap->nr_pmp_links) {
|
||||
link = &ap->pmp_link[pmp];
|
||||
ehi = &link->eh_info;
|
||||
qc = ata_qc_from_tag(ap, link->active_tag);
|
||||
|
||||
ata_ehi_clear_desc(ehi);
|
||||
ata_ehi_push_desc(ehi, "irq_stat 0x%08x",
|
||||
irq_stat);
|
||||
} else {
|
||||
err_mask |= AC_ERR_HSM;
|
||||
action |= ATA_EH_HARDRESET;
|
||||
freeze = 1;
|
||||
}
|
||||
} else
|
||||
qc = ata_qc_from_tag(ap, link->active_tag);
|
||||
|
||||
/* analyze CMD_ERR */
|
||||
cerr = readl(port + PORT_CMD_ERR);
|
||||
|
@ -856,7 +1069,6 @@ static void sil24_error_intr(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/* record error info */
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
if (qc) {
|
||||
sil24_read_tf(ap, qc->tag, &pp->tf);
|
||||
qc->err_mask |= err_mask;
|
||||
|
@ -864,13 +1076,21 @@ static void sil24_error_intr(struct ata_port *ap)
|
|||
ehi->err_mask |= err_mask;
|
||||
|
||||
ehi->action |= action;
|
||||
|
||||
/* if PMP, resume */
|
||||
if (ap->nr_pmp_links)
|
||||
writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_STAT);
|
||||
}
|
||||
|
||||
/* freeze or abort */
|
||||
if (freeze)
|
||||
ata_port_freeze(ap);
|
||||
else
|
||||
ata_port_abort(ap);
|
||||
else if (abort) {
|
||||
if (qc)
|
||||
ata_link_abort(qc->dev->link);
|
||||
else
|
||||
ata_port_abort(ap);
|
||||
}
|
||||
}
|
||||
|
||||
static void sil24_finish_qc(struct ata_queued_cmd *qc)
|
||||
|
@ -910,7 +1130,7 @@ static inline void sil24_host_intr(struct ata_port *ap)
|
|||
if (rc > 0)
|
||||
return;
|
||||
if (rc < 0) {
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
ehi->err_mask |= AC_ERR_HSM;
|
||||
ehi->action |= ATA_EH_SOFTRESET;
|
||||
ata_port_freeze(ap);
|
||||
|
@ -921,7 +1141,7 @@ static inline void sil24_host_intr(struct ata_port *ap)
|
|||
if (!(ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) && ata_ratelimit())
|
||||
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
|
||||
"(slot_stat 0x%x active_tag %d sactive 0x%x)\n",
|
||||
slot_stat, ap->active_tag, ap->sactive);
|
||||
slot_stat, ap->link.active_tag, ap->link.sactive);
|
||||
}
|
||||
|
||||
static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
|
||||
|
@ -963,16 +1183,18 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
|
|||
|
||||
static void sil24_error_handler(struct ata_port *ap)
|
||||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
struct sil24_port_priv *pp = ap->private_data;
|
||||
|
||||
if (sil24_init_port(ap)) {
|
||||
if (sil24_init_port(ap))
|
||||
ata_eh_freeze_port(ap);
|
||||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
}
|
||||
|
||||
/* perform recovery */
|
||||
ata_do_eh(ap, ata_std_prereset, sil24_softreset, sil24_hardreset,
|
||||
ata_std_postreset);
|
||||
sata_pmp_do_eh(ap, ata_std_prereset, sil24_softreset, sil24_hardreset,
|
||||
ata_std_postreset, sata_pmp_std_prereset,
|
||||
sil24_pmp_softreset, sil24_pmp_hardreset,
|
||||
sata_pmp_std_postreset);
|
||||
|
||||
pp->do_port_rst = 0;
|
||||
}
|
||||
|
||||
static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
|
||||
|
@ -980,8 +1202,8 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
|
|||
struct ata_port *ap = qc->ap;
|
||||
|
||||
/* make DMA engine forget about the failed command */
|
||||
if (qc->flags & ATA_QCFLAG_FAILED)
|
||||
sil24_init_port(ap);
|
||||
if ((qc->flags & ATA_QCFLAG_FAILED) && sil24_init_port(ap))
|
||||
ata_eh_freeze_port(ap);
|
||||
}
|
||||
|
||||
static int sil24_port_start(struct ata_port *ap)
|
||||
|
@ -1019,7 +1241,6 @@ static int sil24_port_start(struct ata_port *ap)
|
|||
static void sil24_init_controller(struct ata_host *host)
|
||||
{
|
||||
void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
|
||||
void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
|
||||
u32 tmp;
|
||||
int i;
|
||||
|
||||
|
@ -1031,7 +1252,8 @@ static void sil24_init_controller(struct ata_host *host)
|
|||
|
||||
/* init ports */
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
void __iomem *port = port_base + i * PORT_REGS_SIZE;
|
||||
struct ata_port *ap = host->ports[i];
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
|
||||
/* Initial PHY setting */
|
||||
writel(0x20c, port + PORT_PHY_CFG);
|
||||
|
@ -1048,26 +1270,8 @@ static void sil24_init_controller(struct ata_host *host)
|
|||
"failed to clear port RST\n");
|
||||
}
|
||||
|
||||
/* Configure IRQ WoC */
|
||||
if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC)
|
||||
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
|
||||
else
|
||||
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
|
||||
|
||||
/* Zero error counters. */
|
||||
writel(0x8000, port + PORT_DECODE_ERR_THRESH);
|
||||
writel(0x8000, port + PORT_CRC_ERR_THRESH);
|
||||
writel(0x8000, port + PORT_HSHK_ERR_THRESH);
|
||||
writel(0x0000, port + PORT_DECODE_ERR_CNT);
|
||||
writel(0x0000, port + PORT_CRC_ERR_CNT);
|
||||
writel(0x0000, port + PORT_HSHK_ERR_CNT);
|
||||
|
||||
/* Always use 64bit activation */
|
||||
writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
|
||||
|
||||
/* Clear port multiplier enable and resume bits */
|
||||
writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME,
|
||||
port + PORT_CTRL_CLR);
|
||||
/* configure port */
|
||||
sil24_config_port(ap);
|
||||
}
|
||||
|
||||
/* Turn on interrupts */
|
||||
|
@ -1118,12 +1322,15 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
host->iomap = iomap;
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE;
|
||||
struct ata_port *ap = host->ports[i];
|
||||
size_t offset = ap->port_no * PORT_REGS_SIZE;
|
||||
void __iomem *port = iomap[SIL24_PORT_BAR] + offset;
|
||||
|
||||
host->ports[i]->ioaddr.cmd_addr = port;
|
||||
host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
|
||||
|
||||
ata_std_ports(&host->ports[i]->ioaddr);
|
||||
ata_port_pbar_desc(ap, SIL24_HOST_BAR, -1, "host");
|
||||
ata_port_pbar_desc(ap, SIL24_PORT_BAR, offset, "port");
|
||||
}
|
||||
|
||||
/* configure and activate the device */
|
||||
|
@ -1179,6 +1386,12 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sil24_port_resume(struct ata_port *ap)
|
||||
{
|
||||
sil24_config_pmp(ap, ap->nr_pmp_links);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init sil24_init(void)
|
||||
|
|
|
@ -104,7 +104,6 @@ static struct scsi_host_template sis_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations sis_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -123,7 +122,6 @@ static const struct ata_port_operations sis_ops = {
|
|||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = sis_scr_read,
|
||||
.scr_write = sis_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
|
|
|
@ -329,7 +329,6 @@ static struct scsi_host_template k2_sata_sht = {
|
|||
|
||||
|
||||
static const struct ata_port_operations k2_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = k2_sata_tf_load,
|
||||
.tf_read = k2_sata_tf_read,
|
||||
.check_status = k2_stat_check_status,
|
||||
|
@ -349,7 +348,6 @@ static const struct ata_port_operations k2_sata_ops = {
|
|||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = k2_sata_scr_read,
|
||||
.scr_write = k2_sata_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
|
@ -445,9 +443,15 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
/* different controllers have different number of ports - currently 4 or 8 */
|
||||
/* All ports are on the same function. Multi-function device is no
|
||||
* longer available. This should not be seen in any system. */
|
||||
for (i = 0; i < host->n_ports; i++)
|
||||
k2_sata_setup_port(&host->ports[i]->ioaddr,
|
||||
mmio_base + i * K2_SATA_PORT_OFFSET);
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
unsigned int offset = i * K2_SATA_PORT_OFFSET;
|
||||
|
||||
k2_sata_setup_port(&ap->ioaddr, mmio_base + offset);
|
||||
|
||||
ata_port_pbar_desc(ap, 5, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, 5, offset, "port");
|
||||
}
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
|
|
|
@ -254,7 +254,6 @@ static struct scsi_host_template pdc_sata_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations pdc_20621_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = pdc_tf_load_mmio,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -267,7 +266,6 @@ static const struct ata_port_operations pdc_20621_ops = {
|
|||
.eng_timeout = pdc_eng_timeout,
|
||||
.irq_clear = pdc20621_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.port_start = pdc_port_start,
|
||||
};
|
||||
|
||||
|
@ -854,7 +852,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
|
|||
!(ap->flags & ATA_FLAG_DISABLED)) {
|
||||
struct ata_queued_cmd *qc;
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
|
||||
handled += pdc20621_host_intr(ap, qc, (i > 4),
|
||||
mmio_base);
|
||||
|
@ -881,7 +879,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
|
|||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
|
||||
switch (qc->tf.protocol) {
|
||||
case ATA_PROT_DMA:
|
||||
|
@ -1383,9 +1381,8 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
|
|||
const struct ata_port_info *ppi[] =
|
||||
{ &pdc_port_info[ent->driver_data], NULL };
|
||||
struct ata_host *host;
|
||||
void __iomem *base;
|
||||
struct pdc_host_priv *hpriv;
|
||||
int rc;
|
||||
int i, rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
@ -1411,11 +1408,17 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
|
|||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
base = host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
|
||||
pdc_sata_setup_port(&host->ports[0]->ioaddr, base + 0x200);
|
||||
pdc_sata_setup_port(&host->ports[1]->ioaddr, base + 0x280);
|
||||
pdc_sata_setup_port(&host->ports[2]->ioaddr, base + 0x300);
|
||||
pdc_sata_setup_port(&host->ports[3]->ioaddr, base + 0x380);
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
void __iomem *base = host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
|
||||
unsigned int offset = 0x200 + i * 0x80;
|
||||
|
||||
pdc_sata_setup_port(&ap->ioaddr, base + offset);
|
||||
|
||||
ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, PDC_DIMM_BAR, -1, "dimm");
|
||||
ata_port_pbar_desc(ap, PDC_MMIO_BAR, offset, "port");
|
||||
}
|
||||
|
||||
/* configure and activate */
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
|
|
|
@ -94,8 +94,6 @@ static struct scsi_host_template uli_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations uli_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -117,7 +115,6 @@ static const struct ata_port_operations uli_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.scr_read = uli_scr_read,
|
||||
.scr_write = uli_scr_write,
|
||||
|
@ -242,6 +239,12 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
ata_port_desc(host->ports[2],
|
||||
"cmd 0x%llx ctl 0x%llx bmdma 0x%llx",
|
||||
(unsigned long long)pci_resource_start(pdev, 0) + 8,
|
||||
((unsigned long long)pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4,
|
||||
(unsigned long long)pci_resource_start(pdev, 4) + 16);
|
||||
|
||||
ioaddr = &host->ports[3]->ioaddr;
|
||||
ioaddr->cmd_addr = iomap[2] + 8;
|
||||
ioaddr->altstatus_addr =
|
||||
|
@ -250,6 +253,13 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
ioaddr->bmdma_addr = iomap[4] + 24;
|
||||
hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
ata_port_desc(host->ports[2],
|
||||
"cmd 0x%llx ctl 0x%llx bmdma 0x%llx",
|
||||
(unsigned long long)pci_resource_start(pdev, 2) + 9,
|
||||
((unsigned long long)pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4,
|
||||
(unsigned long long)pci_resource_start(pdev, 4) + 24);
|
||||
|
||||
break;
|
||||
|
||||
case uli_5289:
|
||||
|
|
|
@ -57,7 +57,6 @@ enum {
|
|||
SATA_CHAN_ENAB = 0x40, /* SATA channel enable */
|
||||
SATA_INT_GATE = 0x41, /* SATA interrupt gating */
|
||||
SATA_NATIVE_MODE = 0x42, /* Native mode enable */
|
||||
SATA_PATA_SHARING = 0x49, /* PATA/SATA sharing func ctrl */
|
||||
PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */
|
||||
PATA_PIO_TIMING = 0xAB, /* PATA timing register */
|
||||
|
||||
|
@ -68,7 +67,6 @@ enum {
|
|||
NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
|
||||
|
||||
SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */
|
||||
SATA_2DEV = (1 << 5), /* SATA is master/slave */
|
||||
};
|
||||
|
||||
static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
|
@ -122,8 +120,6 @@ static struct scsi_host_template svia_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations vt6420_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -146,14 +142,11 @@ static const struct ata_port_operations vt6420_sata_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations vt6421_pata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.set_piomode = vt6421_set_pio_mode,
|
||||
.set_dmamode = vt6421_set_dma_mode,
|
||||
|
||||
|
@ -180,14 +173,11 @@ static const struct ata_port_operations vt6421_pata_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations vt6421_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -211,7 +201,6 @@ static const struct ata_port_operations vt6421_sata_ops = {
|
|||
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.scr_read = svia_scr_read,
|
||||
.scr_write = svia_scr_write,
|
||||
|
@ -276,7 +265,7 @@ static void svia_noop_freeze(struct ata_port *ap)
|
|||
|
||||
/**
|
||||
* vt6420_prereset - prereset for vt6420
|
||||
* @ap: target ATA port
|
||||
* @link: target ATA link
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* SCR registers on vt6420 are pieces of shit and may hang the
|
||||
|
@ -294,9 +283,10 @@ static void svia_noop_freeze(struct ata_port *ap)
|
|||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
struct ata_port *ap = link->ap;
|
||||
struct ata_eh_context *ehc = &ap->link.eh_context;
|
||||
unsigned long timeout = jiffies + (HZ * 5);
|
||||
u32 sstatus, scontrol;
|
||||
int online;
|
||||
|
@ -407,6 +397,9 @@ static void vt6421_init_addrs(struct ata_port *ap)
|
|||
ioaddr->scr_addr = vt6421_scr_addr(iomap[5], ap->port_no);
|
||||
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
ata_port_pbar_desc(ap, ap->port_no, -1, "port");
|
||||
ata_port_pbar_desc(ap, 4, ap->port_no * 8, "bmdma");
|
||||
}
|
||||
|
||||
static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
|
||||
|
@ -513,7 +506,6 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
struct ata_host *host;
|
||||
int board_id = (int) ent->driver_data;
|
||||
const int *bar_sizes;
|
||||
u8 tmp8;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
@ -522,19 +514,10 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (board_id == vt6420) {
|
||||
pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
|
||||
if (tmp8 & SATA_2DEV) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"SATA master/slave not supported (0x%x)\n",
|
||||
(int) tmp8);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (board_id == vt6420)
|
||||
bar_sizes = &svia_bar_sizes[0];
|
||||
} else {
|
||||
else
|
||||
bar_sizes = &vt6421_bar_sizes[0];
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
|
||||
if ((pci_resource_start(pdev, i) == 0) ||
|
||||
|
|
|
@ -240,7 +240,7 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap)
|
|||
return;
|
||||
}
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING)))
|
||||
handled = ata_host_intr(ap, qc);
|
||||
|
||||
|
@ -317,7 +317,6 @@ static struct scsi_host_template vsc_sata_sht = {
|
|||
|
||||
|
||||
static const struct ata_port_operations vsc_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = vsc_sata_tf_load,
|
||||
.tf_read = vsc_sata_tf_read,
|
||||
.exec_command = ata_exec_command,
|
||||
|
@ -336,7 +335,6 @@ static const struct ata_port_operations vsc_sata_ops = {
|
|||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.scr_read = vsc_sata_scr_read,
|
||||
.scr_write = vsc_sata_scr_write,
|
||||
.port_start = ata_port_start,
|
||||
|
@ -408,9 +406,15 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
|
|||
|
||||
mmio_base = host->iomap[VSC_MMIO_BAR];
|
||||
|
||||
for (i = 0; i < host->n_ports; i++)
|
||||
vsc_sata_setup_port(&host->ports[i]->ioaddr,
|
||||
mmio_base + (i + 1) * VSC_SATA_PORT_OFFSET);
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
unsigned int offset = (i + 1) * VSC_SATA_PORT_OFFSET;
|
||||
|
||||
vsc_sata_setup_port(&ap->ioaddr, mmio_base + offset);
|
||||
|
||||
ata_port_pbar_desc(ap, VSC_MMIO_BAR, -1, "mmio");
|
||||
ata_port_pbar_desc(ap, VSC_MMIO_BAR, offset, "port");
|
||||
}
|
||||
|
||||
/*
|
||||
* Use 32 bit DMA mask, because 64 bit address support is poor.
|
||||
|
|
|
@ -3829,18 +3829,18 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
|
|||
|
||||
/**
|
||||
* ipr_sata_reset - Reset the SATA port
|
||||
* @ap: SATA port to reset
|
||||
* @link: SATA link to reset
|
||||
* @classes: class of the attached device
|
||||
*
|
||||
* This function issues a SATA phy reset to the affected ATA port.
|
||||
* This function issues a SATA phy reset to the affected ATA link.
|
||||
*
|
||||
* Return value:
|
||||
* 0 on success / non-zero on failure
|
||||
**/
|
||||
static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes,
|
||||
static int ipr_sata_reset(struct ata_link *link, unsigned int *classes,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ipr_sata_port *sata_port = ap->private_data;
|
||||
struct ipr_sata_port *sata_port = link->ap->private_data;
|
||||
struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
|
||||
struct ipr_resource_entry *res;
|
||||
unsigned long lock_flags = 0;
|
||||
|
@ -4981,22 +4981,22 @@ static void ipr_ata_phy_reset(struct ata_port *ap)
|
|||
rc = ipr_device_reset(ioa_cfg, res);
|
||||
|
||||
if (rc) {
|
||||
ap->ops->port_disable(ap);
|
||||
ata_port_disable(ap);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
switch(res->cfgte.proto) {
|
||||
case IPR_PROTO_SATA:
|
||||
case IPR_PROTO_SAS_STP:
|
||||
ap->device[0].class = ATA_DEV_ATA;
|
||||
ap->link.device[0].class = ATA_DEV_ATA;
|
||||
break;
|
||||
case IPR_PROTO_SATA_ATAPI:
|
||||
case IPR_PROTO_SAS_STP_ATAPI:
|
||||
ap->device[0].class = ATA_DEV_ATAPI;
|
||||
ap->link.device[0].class = ATA_DEV_ATAPI;
|
||||
break;
|
||||
default:
|
||||
ap->device[0].class = ATA_DEV_UNKNOWN;
|
||||
ap->ops->port_disable(ap);
|
||||
ap->link.device[0].class = ATA_DEV_UNKNOWN;
|
||||
ata_port_disable(ap);
|
||||
break;
|
||||
};
|
||||
|
||||
|
@ -5262,7 +5262,6 @@ static u8 ipr_ata_check_altstatus(struct ata_port *ap)
|
|||
}
|
||||
|
||||
static struct ata_port_operations ipr_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.check_status = ipr_ata_check_status,
|
||||
.check_altstatus = ipr_ata_check_altstatus,
|
||||
.dev_select = ata_noop_dev_select,
|
||||
|
|
|
@ -249,17 +249,17 @@ static void sas_ata_phy_reset(struct ata_port *ap)
|
|||
switch (dev->sata_dev.command_set) {
|
||||
case ATA_COMMAND_SET:
|
||||
SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__);
|
||||
ap->device[0].class = ATA_DEV_ATA;
|
||||
ap->link.device[0].class = ATA_DEV_ATA;
|
||||
break;
|
||||
case ATAPI_COMMAND_SET:
|
||||
SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__);
|
||||
ap->device[0].class = ATA_DEV_ATAPI;
|
||||
ap->link.device[0].class = ATA_DEV_ATAPI;
|
||||
break;
|
||||
default:
|
||||
SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
|
||||
__FUNCTION__,
|
||||
dev->sata_dev.command_set);
|
||||
ap->device[0].class = ATA_DEV_UNKNOWN;
|
||||
ap->link.device[0].class = ATA_DEV_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
|
|||
dev->sata_dev.serror = val;
|
||||
break;
|
||||
case SCR_ACTIVE:
|
||||
dev->sata_dev.ap->sactive = val;
|
||||
dev->sata_dev.ap->link.sactive = val;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -342,7 +342,7 @@ static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
|
|||
*val = dev->sata_dev.serror;
|
||||
return 0;
|
||||
case SCR_ACTIVE:
|
||||
*val = dev->sata_dev.ap->sactive;
|
||||
*val = dev->sata_dev.ap->link.sactive;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -350,7 +350,6 @@ static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
|
|||
}
|
||||
|
||||
static struct ata_port_operations sas_sata_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.check_status = sas_ata_check_status,
|
||||
.check_altstatus = sas_ata_check_status,
|
||||
.dev_select = ata_noop_dev_select,
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
|
||||
#define __ASM_GENERIC_LIBATA_PORTMAP_H
|
||||
|
||||
#define ATA_PRIMARY_CMD 0x1F0
|
||||
#define ATA_PRIMARY_CTL 0x3F6
|
||||
#define ATA_PRIMARY_IRQ(dev) 14
|
||||
|
||||
#define ATA_SECONDARY_CMD 0x170
|
||||
#define ATA_SECONDARY_CTL 0x376
|
||||
#define ATA_SECONDARY_IRQ(dev) 15
|
||||
|
||||
#endif
|
||||
|
|
|
@ -230,6 +230,12 @@ enum {
|
|||
|
||||
SETFEATURES_SPINUP = 0x07, /* Spin-up drive */
|
||||
|
||||
SETFEATURES_SATA_ENABLE = 0x10, /* Enable use of SATA feature */
|
||||
SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */
|
||||
|
||||
/* SETFEATURE Sector counts for SATA features */
|
||||
SATA_AN = 0x05, /* Asynchronous Notification */
|
||||
|
||||
/* ATAPI stuff */
|
||||
ATAPI_PKT_DMA = (1 << 0),
|
||||
ATAPI_DMADIR = (1 << 2), /* ATAPI data dir:
|
||||
|
@ -281,6 +287,15 @@ enum {
|
|||
SERR_PROTOCOL = (1 << 10), /* protocol violation */
|
||||
SERR_INTERNAL = (1 << 11), /* host internal error */
|
||||
SERR_PHYRDY_CHG = (1 << 16), /* PHY RDY changed */
|
||||
SERR_PHY_INT_ERR = (1 << 17), /* PHY internal error */
|
||||
SERR_COMM_WAKE = (1 << 18), /* Comm wake */
|
||||
SERR_10B_8B_ERR = (1 << 19), /* 10b to 8b decode error */
|
||||
SERR_DISPARITY = (1 << 20), /* Disparity */
|
||||
SERR_CRC = (1 << 21), /* CRC error */
|
||||
SERR_HANDSHAKE = (1 << 22), /* Handshake error */
|
||||
SERR_LINK_SEQ_ERR = (1 << 23), /* Link sequence error */
|
||||
SERR_TRANS_ST_ERROR = (1 << 24), /* Transport state trans. error */
|
||||
SERR_UNRECOG_FIS = (1 << 25), /* Unrecognized FIS */
|
||||
SERR_DEV_XCHG = (1 << 26), /* device exchanged */
|
||||
|
||||
/* struct ata_taskfile flags */
|
||||
|
@ -341,24 +356,17 @@ struct ata_taskfile {
|
|||
};
|
||||
|
||||
#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
|
||||
#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
|
||||
#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
|
||||
#define ata_id_hpa_enabled(id) ((id)[85] & (1 << 10))
|
||||
#define ata_id_has_fua(id) ((id)[84] & (1 << 6))
|
||||
#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
|
||||
#define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
|
||||
#define ata_id_has_lba48(id) ((id)[83] & (1 << 10))
|
||||
#define ata_id_has_hpa(id) ((id)[82] & (1 << 10))
|
||||
#define ata_id_has_wcache(id) ((id)[82] & (1 << 5))
|
||||
#define ata_id_has_pm(id) ((id)[82] & (1 << 3))
|
||||
#define ata_id_has_lba(id) ((id)[49] & (1 << 9))
|
||||
#define ata_id_has_dma(id) ((id)[49] & (1 << 8))
|
||||
#define ata_id_has_ncq(id) ((id)[76] & (1 << 8))
|
||||
#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
|
||||
#define ata_id_removeable(id) ((id)[0] & (1 << 7))
|
||||
#define ata_id_has_dword_io(id) ((id)[50] & (1 << 0))
|
||||
#define ata_id_has_dword_io(id) ((id)[48] & (1 << 0))
|
||||
#define ata_id_has_atapi_AN(id) \
|
||||
( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
|
||||
((id)[78] & (1 << 5)) )
|
||||
#define ata_id_iordy_disable(id) ((id)[49] & (1 << 10))
|
||||
#define ata_id_has_iordy(id) ((id)[49] & (1 << 9))
|
||||
#define ata_id_has_iordy(id) ((id)[49] & (1 << 11))
|
||||
#define ata_id_u32(id,n) \
|
||||
(((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)]))
|
||||
#define ata_id_u64(id,n) \
|
||||
|
@ -369,6 +377,90 @@ struct ata_taskfile {
|
|||
|
||||
#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20)
|
||||
|
||||
static inline int ata_id_has_fua(const u16 *id)
|
||||
{
|
||||
if ((id[84] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[84] & (1 << 6);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_flush(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[83] & (1 << 12);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_flush_ext(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[83] & (1 << 13);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_lba48(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[83] & (1 << 10);
|
||||
}
|
||||
|
||||
static inline int ata_id_hpa_enabled(const u16 *id)
|
||||
{
|
||||
/* Yes children, word 83 valid bits cover word 82 data */
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
/* And 87 covers 85-87 */
|
||||
if ((id[87] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
/* Check command sets enabled as well as supported */
|
||||
if ((id[85] & ( 1 << 10)) == 0)
|
||||
return 0;
|
||||
return id[82] & (1 << 10);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_wcache(const u16 *id)
|
||||
{
|
||||
/* Yes children, word 83 valid bits cover word 82 data */
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[82] & (1 << 5);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_pm(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[82] & (1 << 3);
|
||||
}
|
||||
|
||||
static inline int ata_id_rahead_enabled(const u16 *id)
|
||||
{
|
||||
if ((id[87] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[85] & (1 << 6);
|
||||
}
|
||||
|
||||
static inline int ata_id_wcache_enabled(const u16 *id)
|
||||
{
|
||||
if ((id[87] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[85] & (1 << 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_id_major_version - get ATA level of drive
|
||||
* @id: Identify data
|
||||
*
|
||||
* Caveats:
|
||||
* ATA-1 considers identify optional
|
||||
* ATA-2 introduces mandatory identify
|
||||
* ATA-3 introduces word 80 and accurate reporting
|
||||
*
|
||||
* The practical impact of this is that ata_id_major_version cannot
|
||||
* reliably report on drives below ATA3.
|
||||
*/
|
||||
|
||||
static inline unsigned int ata_id_major_version(const u16 *id)
|
||||
{
|
||||
unsigned int mver;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/scatterlist.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -107,12 +106,6 @@ static inline u32 ata_msg_init(int dval, int default_msg_enable_bits)
|
|||
/* defines only for the constants which don't work well as enums */
|
||||
#define ATA_TAG_POISON 0xfafbfcfdU
|
||||
|
||||
/* move to PCI layer? */
|
||||
static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
|
||||
{
|
||||
return &pdev->dev;
|
||||
}
|
||||
|
||||
enum {
|
||||
/* various global constants */
|
||||
LIBATA_MAX_PRD = ATA_MAX_PRD / 2,
|
||||
|
@ -139,11 +132,12 @@ enum {
|
|||
ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */
|
||||
ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */
|
||||
ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */
|
||||
ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
|
||||
ATA_DFLAG_AN = (1 << 7), /* AN configured */
|
||||
ATA_DFLAG_CFG_MASK = (1 << 12) - 1,
|
||||
|
||||
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
|
||||
ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */
|
||||
ATA_DFLAG_SPUNDOWN = (1 << 10), /* XXX: for spindown_compat */
|
||||
ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */
|
||||
ATA_DFLAG_NCQ_OFF = (1 << 13), /* device limited to non-NCQ mode */
|
||||
ATA_DFLAG_SPUNDOWN = (1 << 14), /* XXX: for spindown_compat */
|
||||
ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
|
||||
|
||||
ATA_DFLAG_DETACH = (1 << 16),
|
||||
|
@ -154,7 +148,22 @@ enum {
|
|||
ATA_DEV_ATA_UNSUP = 2, /* ATA device (unsupported) */
|
||||
ATA_DEV_ATAPI = 3, /* ATAPI device */
|
||||
ATA_DEV_ATAPI_UNSUP = 4, /* ATAPI device (unsupported) */
|
||||
ATA_DEV_NONE = 5, /* no device */
|
||||
ATA_DEV_PMP = 5, /* SATA port multiplier */
|
||||
ATA_DEV_PMP_UNSUP = 6, /* SATA port multiplier (unsupported) */
|
||||
ATA_DEV_SEMB = 7, /* SEMB */
|
||||
ATA_DEV_SEMB_UNSUP = 8, /* SEMB (unsupported) */
|
||||
ATA_DEV_NONE = 9, /* no device */
|
||||
|
||||
/* struct ata_link flags */
|
||||
ATA_LFLAG_HRST_TO_RESUME = (1 << 0), /* hardreset to resume link */
|
||||
ATA_LFLAG_SKIP_D2H_BSY = (1 << 1), /* can't wait for the first D2H
|
||||
* Register FIS clearing BSY */
|
||||
ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */
|
||||
ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */
|
||||
ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */
|
||||
ATA_LFLAG_ASSUME_CLASS = ATA_LFLAG_ASSUME_ATA | ATA_LFLAG_ASSUME_SEMB,
|
||||
ATA_LFLAG_NO_RETRY = (1 << 5), /* don't retry this link */
|
||||
ATA_LFLAG_DISABLED = (1 << 6), /* link is disabled */
|
||||
|
||||
/* struct ata_port flags */
|
||||
ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
|
||||
|
@ -170,13 +179,12 @@ enum {
|
|||
ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD
|
||||
* doesn't handle PIO interrupts */
|
||||
ATA_FLAG_NCQ = (1 << 10), /* host supports NCQ */
|
||||
ATA_FLAG_HRST_TO_RESUME = (1 << 11), /* hardreset to resume phy */
|
||||
ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H
|
||||
* Register FIS clearing BSY */
|
||||
ATA_FLAG_DEBUGMSG = (1 << 13),
|
||||
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
|
||||
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
|
||||
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
|
||||
ATA_FLAG_AN = (1 << 18), /* controller supports AN */
|
||||
ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */
|
||||
|
||||
/* The following flag belongs to ap->pflags but is kept in
|
||||
* ap->flags because it's referenced in many LLDs and will be
|
||||
|
@ -195,6 +203,7 @@ enum {
|
|||
ATA_PFLAG_UNLOADING = (1 << 5), /* module is unloading */
|
||||
ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */
|
||||
ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */
|
||||
ATA_PFLAG_RESETTING = (1 << 8), /* reset in progress */
|
||||
|
||||
ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
|
||||
ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
|
||||
|
@ -207,6 +216,7 @@ enum {
|
|||
ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
|
||||
ATA_QCFLAG_IO = (1 << 3), /* standard IO command */
|
||||
ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */
|
||||
ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */
|
||||
|
||||
ATA_QCFLAG_FAILED = (1 << 16), /* cmd failed and is owned by EH */
|
||||
ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */
|
||||
|
@ -263,6 +273,10 @@ enum {
|
|||
/* ering size */
|
||||
ATA_ERING_SIZE = 32,
|
||||
|
||||
/* return values for ->qc_defer */
|
||||
ATA_DEFER_LINK = 1,
|
||||
ATA_DEFER_PORT = 2,
|
||||
|
||||
/* desc_len for ata_eh_info and context */
|
||||
ATA_EH_DESC_LEN = 80,
|
||||
|
||||
|
@ -270,6 +284,7 @@ enum {
|
|||
ATA_EH_REVALIDATE = (1 << 0),
|
||||
ATA_EH_SOFTRESET = (1 << 1),
|
||||
ATA_EH_HARDRESET = (1 << 2),
|
||||
ATA_EH_ENABLE_LINK = (1 << 3),
|
||||
|
||||
ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
|
||||
ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE,
|
||||
|
@ -289,12 +304,16 @@ enum {
|
|||
ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
|
||||
ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
|
||||
|
||||
/* max repeat if error condition is still set after ->error_handler */
|
||||
ATA_EH_MAX_REPEAT = 5,
|
||||
/* max tries if error condition is still set after ->error_handler */
|
||||
ATA_EH_MAX_TRIES = 5,
|
||||
|
||||
/* how hard are we gonna try to probe/recover devices */
|
||||
ATA_PROBE_MAX_TRIES = 3,
|
||||
ATA_EH_DEV_TRIES = 3,
|
||||
ATA_EH_PMP_TRIES = 5,
|
||||
ATA_EH_PMP_LINK_TRIES = 3,
|
||||
|
||||
SATA_PMP_SCR_TIMEOUT = 250,
|
||||
|
||||
/* Horkage types. May be set by libata or controller on drives
|
||||
(some horkage may be drive/controller pair dependant */
|
||||
|
@ -304,6 +323,14 @@ enum {
|
|||
ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */
|
||||
ATA_HORKAGE_MAX_SEC_128 = (1 << 3), /* Limit max sects to 128 */
|
||||
ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */
|
||||
ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */
|
||||
ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */
|
||||
|
||||
/* DMA mask for user DMA control: User visible values; DO NOT
|
||||
renumber */
|
||||
ATA_DMA_MASK_ATA = (1 << 0), /* DMA on ATA Disk */
|
||||
ATA_DMA_MASK_ATAPI = (1 << 1), /* DMA on ATAPI */
|
||||
ATA_DMA_MASK_CFA = (1 << 2), /* DMA on CF Card */
|
||||
};
|
||||
|
||||
enum hsm_task_states {
|
||||
|
@ -333,14 +360,15 @@ enum ata_completion_errors {
|
|||
struct scsi_device;
|
||||
struct ata_port_operations;
|
||||
struct ata_port;
|
||||
struct ata_link;
|
||||
struct ata_queued_cmd;
|
||||
|
||||
/* typedefs */
|
||||
typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
|
||||
typedef int (*ata_prereset_fn_t)(struct ata_port *ap, unsigned long deadline);
|
||||
typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes,
|
||||
typedef int (*ata_prereset_fn_t)(struct ata_link *link, unsigned long deadline);
|
||||
typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes,
|
||||
unsigned long deadline);
|
||||
typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *classes);
|
||||
typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes);
|
||||
|
||||
struct ata_ioports {
|
||||
void __iomem *cmd_addr;
|
||||
|
@ -363,8 +391,6 @@ struct ata_ioports {
|
|||
struct ata_host {
|
||||
spinlock_t lock;
|
||||
struct device *dev;
|
||||
unsigned long irq;
|
||||
unsigned long irq2;
|
||||
void __iomem * const *iomap;
|
||||
unsigned int n_ports;
|
||||
void *private_data;
|
||||
|
@ -436,7 +462,7 @@ struct ata_ering {
|
|||
};
|
||||
|
||||
struct ata_device {
|
||||
struct ata_port *ap;
|
||||
struct ata_link *link;
|
||||
unsigned int devno; /* 0 or 1 */
|
||||
unsigned long flags; /* ATA_DFLAG_xxx */
|
||||
unsigned int horkage; /* List of broken features */
|
||||
|
@ -447,7 +473,12 @@ struct ata_device {
|
|||
/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
|
||||
u64 n_sectors; /* size of device, if ATA */
|
||||
unsigned int class; /* ATA_DEV_xxx */
|
||||
u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
|
||||
|
||||
union {
|
||||
u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
|
||||
u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
|
||||
};
|
||||
|
||||
u8 pio_mode;
|
||||
u8 dma_mode;
|
||||
u8 xfer_mode;
|
||||
|
@ -510,6 +541,27 @@ struct ata_acpi_gtm {
|
|||
u32 flags;
|
||||
} __packed;
|
||||
|
||||
struct ata_link {
|
||||
struct ata_port *ap;
|
||||
int pmp; /* port multiplier port # */
|
||||
|
||||
unsigned int active_tag; /* active tag on this link */
|
||||
u32 sactive; /* active NCQ commands */
|
||||
|
||||
unsigned int flags; /* ATA_LFLAG_xxx */
|
||||
|
||||
unsigned int hw_sata_spd_limit;
|
||||
unsigned int sata_spd_limit;
|
||||
unsigned int sata_spd; /* current SATA PHY speed */
|
||||
|
||||
/* record runtime error info, protected by host_set lock */
|
||||
struct ata_eh_info eh_info;
|
||||
/* EH context */
|
||||
struct ata_eh_context eh_context;
|
||||
|
||||
struct ata_device device[ATA_MAX_DEVICES];
|
||||
};
|
||||
|
||||
struct ata_port {
|
||||
struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
|
||||
const struct ata_port_operations *ops;
|
||||
|
@ -533,23 +585,17 @@ struct ata_port {
|
|||
unsigned int mwdma_mask;
|
||||
unsigned int udma_mask;
|
||||
unsigned int cbl; /* cable type; ATA_CBL_xxx */
|
||||
unsigned int hw_sata_spd_limit;
|
||||
unsigned int sata_spd_limit; /* SATA PHY speed limit */
|
||||
unsigned int sata_spd; /* current SATA PHY speed */
|
||||
|
||||
/* record runtime error info, protected by host lock */
|
||||
struct ata_eh_info eh_info;
|
||||
/* EH context owned by EH */
|
||||
struct ata_eh_context eh_context;
|
||||
|
||||
struct ata_device device[ATA_MAX_DEVICES];
|
||||
|
||||
struct ata_queued_cmd qcmd[ATA_MAX_QUEUE];
|
||||
unsigned long qc_allocated;
|
||||
unsigned int qc_active;
|
||||
int nr_active_links; /* #links with active qcs */
|
||||
|
||||
unsigned int active_tag;
|
||||
u32 sactive;
|
||||
struct ata_link link; /* host default link */
|
||||
|
||||
int nr_pmp_links; /* nr of available PMP links */
|
||||
struct ata_link *pmp_link; /* array of PMP links */
|
||||
struct ata_link *excl_link; /* for PMP qc exclusion */
|
||||
|
||||
struct ata_port_stats stats;
|
||||
struct ata_host *host;
|
||||
|
@ -565,6 +611,7 @@ struct ata_port {
|
|||
u32 msg_enable;
|
||||
struct list_head eh_done_q;
|
||||
wait_queue_head_t eh_wait_q;
|
||||
int eh_tries;
|
||||
|
||||
pm_message_t pm_mesg;
|
||||
int *pm_result;
|
||||
|
@ -582,8 +629,6 @@ struct ata_port {
|
|||
};
|
||||
|
||||
struct ata_port_operations {
|
||||
void (*port_disable) (struct ata_port *);
|
||||
|
||||
void (*dev_config) (struct ata_device *);
|
||||
|
||||
void (*set_piomode) (struct ata_port *, struct ata_device *);
|
||||
|
@ -599,7 +644,7 @@ struct ata_port_operations {
|
|||
void (*dev_select)(struct ata_port *ap, unsigned int device);
|
||||
|
||||
void (*phy_reset) (struct ata_port *ap); /* obsolete */
|
||||
int (*set_mode) (struct ata_port *ap, struct ata_device **r_failed_dev);
|
||||
int (*set_mode) (struct ata_link *link, struct ata_device **r_failed_dev);
|
||||
|
||||
int (*cable_detect) (struct ata_port *ap);
|
||||
|
||||
|
@ -610,9 +655,14 @@ struct ata_port_operations {
|
|||
|
||||
void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
|
||||
|
||||
int (*qc_defer) (struct ata_queued_cmd *qc);
|
||||
void (*qc_prep) (struct ata_queued_cmd *qc);
|
||||
unsigned int (*qc_issue) (struct ata_queued_cmd *qc);
|
||||
|
||||
/* port multiplier */
|
||||
void (*pmp_attach) (struct ata_port *ap);
|
||||
void (*pmp_detach) (struct ata_port *ap);
|
||||
|
||||
/* Error handlers. ->error_handler overrides ->eng_timeout and
|
||||
* indicates that new-style EH is in place.
|
||||
*/
|
||||
|
@ -626,7 +676,6 @@ struct ata_port_operations {
|
|||
irq_handler_t irq_handler;
|
||||
void (*irq_clear) (struct ata_port *);
|
||||
u8 (*irq_on) (struct ata_port *);
|
||||
u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq);
|
||||
|
||||
int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val);
|
||||
int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val);
|
||||
|
@ -646,6 +695,7 @@ struct ata_port_operations {
|
|||
struct ata_port_info {
|
||||
struct scsi_host_template *sht;
|
||||
unsigned long flags;
|
||||
unsigned long link_flags;
|
||||
unsigned long pio_mask;
|
||||
unsigned long mwdma_mask;
|
||||
unsigned long udma_mask;
|
||||
|
@ -689,38 +739,27 @@ static inline int ata_port_is_dummy(struct ata_port *ap)
|
|||
return ap->ops == &ata_dummy_port_ops;
|
||||
}
|
||||
|
||||
extern void sata_print_link_status(struct ata_port *ap);
|
||||
extern void sata_print_link_status(struct ata_link *link);
|
||||
extern void ata_port_probe(struct ata_port *);
|
||||
extern void __sata_phy_reset(struct ata_port *ap);
|
||||
extern void sata_phy_reset(struct ata_port *ap);
|
||||
extern void ata_bus_reset(struct ata_port *ap);
|
||||
extern int sata_set_spd(struct ata_port *ap);
|
||||
extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param,
|
||||
extern int sata_set_spd(struct ata_link *link);
|
||||
extern int sata_link_debounce(struct ata_link *link,
|
||||
const unsigned long *params, unsigned long deadline);
|
||||
extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
||||
unsigned long deadline);
|
||||
extern int ata_std_prereset(struct ata_link *link, unsigned long deadline);
|
||||
extern int ata_std_softreset(struct ata_link *link, unsigned int *classes,
|
||||
unsigned long deadline);
|
||||
extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param,
|
||||
unsigned long deadline);
|
||||
extern int ata_std_prereset(struct ata_port *ap, unsigned long deadline);
|
||||
extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
|
||||
unsigned long deadline);
|
||||
extern int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,
|
||||
unsigned long deadline);
|
||||
extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
extern int sata_link_hardreset(struct ata_link *link,
|
||||
const unsigned long *timing, unsigned long deadline);
|
||||
extern int sata_std_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline);
|
||||
extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
|
||||
extern void ata_std_postreset(struct ata_link *link, unsigned int *classes);
|
||||
extern void ata_port_disable(struct ata_port *);
|
||||
extern void ata_std_ports(struct ata_ioports *ioaddr);
|
||||
#ifdef CONFIG_PCI
|
||||
extern int ata_pci_init_one (struct pci_dev *pdev,
|
||||
const struct ata_port_info * const * ppi);
|
||||
extern void ata_pci_remove_one (struct pci_dev *pdev);
|
||||
#ifdef CONFIG_PM
|
||||
extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg);
|
||||
extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev);
|
||||
extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
|
||||
extern int ata_pci_device_resume(struct pci_dev *pdev);
|
||||
#endif
|
||||
extern int ata_pci_clear_simplex(struct pci_dev *pdev);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports);
|
||||
extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
|
||||
const struct ata_port_info * const * ppi, int n_ports);
|
||||
|
@ -746,12 +785,12 @@ extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);
|
|||
extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
|
||||
struct ata_port *ap);
|
||||
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
|
||||
extern int sata_scr_valid(struct ata_port *ap);
|
||||
extern int sata_scr_read(struct ata_port *ap, int reg, u32 *val);
|
||||
extern int sata_scr_write(struct ata_port *ap, int reg, u32 val);
|
||||
extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val);
|
||||
extern int ata_port_online(struct ata_port *ap);
|
||||
extern int ata_port_offline(struct ata_port *ap);
|
||||
extern int sata_scr_valid(struct ata_link *link);
|
||||
extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
|
||||
extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
|
||||
extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val);
|
||||
extern int ata_link_online(struct ata_link *link);
|
||||
extern int ata_link_offline(struct ata_link *link);
|
||||
#ifdef CONFIG_PM
|
||||
extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
|
||||
extern void ata_host_resume(struct ata_host *host);
|
||||
|
@ -765,7 +804,8 @@ extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn,
|
|||
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
|
||||
unsigned long interval_msec,
|
||||
unsigned long timeout_msec);
|
||||
extern unsigned int ata_dev_try_classify(struct ata_port *, unsigned int, u8 *);
|
||||
extern unsigned int ata_dev_try_classify(struct ata_device *dev, int present,
|
||||
u8 *r_err);
|
||||
|
||||
/*
|
||||
* Default driver ops implementations
|
||||
|
@ -787,6 +827,7 @@ extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
|
|||
unsigned int buflen, int write_data);
|
||||
extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
|
||||
unsigned int buflen, int write_data);
|
||||
extern int ata_std_qc_defer(struct ata_queued_cmd *qc);
|
||||
extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc);
|
||||
extern void ata_qc_prep(struct ata_queued_cmd *qc);
|
||||
extern void ata_noop_qc_prep(struct ata_queued_cmd *qc);
|
||||
|
@ -830,11 +871,8 @@ extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
|
|||
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
|
||||
int queue_depth);
|
||||
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
|
||||
extern int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
|
||||
extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
|
||||
extern u8 ata_irq_on(struct ata_port *ap);
|
||||
extern u8 ata_dummy_irq_on(struct ata_port *ap);
|
||||
extern u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq);
|
||||
extern u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq);
|
||||
|
||||
extern int ata_cable_40wire(struct ata_port *ap);
|
||||
extern int ata_cable_80wire(struct ata_port *ap);
|
||||
|
@ -869,8 +907,29 @@ enum {
|
|||
ATA_TIMING_CYCLE | ATA_TIMING_UDMA,
|
||||
};
|
||||
|
||||
/* libata-acpi.c */
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
extern int ata_acpi_cbl_80wire(struct ata_port *ap);
|
||||
int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm);
|
||||
int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *stm);
|
||||
#else
|
||||
static inline int ata_acpi_cbl_80wire(struct ata_port *ap) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_dev;
|
||||
|
||||
extern int ata_pci_init_one (struct pci_dev *pdev,
|
||||
const struct ata_port_info * const * ppi);
|
||||
extern void ata_pci_remove_one (struct pci_dev *pdev);
|
||||
#ifdef CONFIG_PM
|
||||
extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg);
|
||||
extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev);
|
||||
extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
|
||||
extern int ata_pci_device_resume(struct pci_dev *pdev);
|
||||
#endif
|
||||
extern int ata_pci_clear_simplex(struct pci_dev *pdev);
|
||||
|
||||
struct pci_bits {
|
||||
unsigned int reg; /* PCI config register to read */
|
||||
unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
|
||||
|
@ -887,14 +946,30 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit
|
|||
extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
* PMP
|
||||
*/
|
||||
extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc);
|
||||
extern int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline);
|
||||
extern int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline);
|
||||
extern void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class);
|
||||
extern void sata_pmp_do_eh(struct ata_port *ap,
|
||||
ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
|
||||
ata_reset_fn_t hardreset, ata_postreset_fn_t postreset,
|
||||
ata_prereset_fn_t pmp_prereset, ata_reset_fn_t pmp_softreset,
|
||||
ata_reset_fn_t pmp_hardreset, ata_postreset_fn_t pmp_postreset);
|
||||
|
||||
/*
|
||||
* EH
|
||||
*/
|
||||
extern void ata_eng_timeout(struct ata_port *ap);
|
||||
|
||||
extern void ata_port_schedule_eh(struct ata_port *ap);
|
||||
extern int ata_link_abort(struct ata_link *link);
|
||||
extern int ata_port_abort(struct ata_port *ap);
|
||||
extern int ata_port_freeze(struct ata_port *ap);
|
||||
extern int sata_async_notification(struct ata_port *ap);
|
||||
|
||||
extern void ata_eh_freeze_port(struct ata_port *ap);
|
||||
extern void ata_eh_thaw_port(struct ata_port *ap);
|
||||
|
@ -912,14 +987,25 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
#define ata_port_printk(ap, lv, fmt, args...) \
|
||||
printk(lv"ata%u: "fmt, (ap)->print_id , ##args)
|
||||
|
||||
#define ata_link_printk(link, lv, fmt, args...) do { \
|
||||
if ((link)->ap->nr_pmp_links) \
|
||||
printk(lv"ata%u.%02u: "fmt, (link)->ap->print_id, \
|
||||
(link)->pmp , ##args); \
|
||||
else \
|
||||
printk(lv"ata%u: "fmt, (link)->ap->print_id , ##args); \
|
||||
} while(0)
|
||||
|
||||
#define ata_dev_printk(dev, lv, fmt, args...) \
|
||||
printk(lv"ata%u.%02u: "fmt, (dev)->ap->print_id, (dev)->devno , ##args)
|
||||
printk(lv"ata%u.%02u: "fmt, (dev)->link->ap->print_id, \
|
||||
(dev)->link->pmp + (dev)->devno , ##args)
|
||||
|
||||
/*
|
||||
* ata_eh_info helpers
|
||||
*/
|
||||
extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...);
|
||||
extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...);
|
||||
extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
extern void ata_ehi_clear_desc(struct ata_eh_info *ehi);
|
||||
|
||||
static inline void ata_ehi_schedule_probe(struct ata_eh_info *ehi)
|
||||
|
@ -933,9 +1019,20 @@ static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi)
|
|||
{
|
||||
ata_ehi_schedule_probe(ehi);
|
||||
ehi->flags |= ATA_EHI_HOTPLUGGED;
|
||||
ehi->action |= ATA_EH_ENABLE_LINK;
|
||||
ehi->err_mask |= AC_ERR_ATA_BUS;
|
||||
}
|
||||
|
||||
/*
|
||||
* port description helpers
|
||||
*/
|
||||
extern void ata_port_desc(struct ata_port *ap, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
#ifdef CONFIG_PCI
|
||||
extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
|
||||
const char *name);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* qc helpers
|
||||
*/
|
||||
|
@ -991,12 +1088,14 @@ static inline unsigned int ata_tag_internal(unsigned int tag)
|
|||
*/
|
||||
static inline unsigned int ata_class_enabled(unsigned int class)
|
||||
{
|
||||
return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI;
|
||||
return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI ||
|
||||
class == ATA_DEV_PMP || class == ATA_DEV_SEMB;
|
||||
}
|
||||
|
||||
static inline unsigned int ata_class_disabled(unsigned int class)
|
||||
{
|
||||
return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP;
|
||||
return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP ||
|
||||
class == ATA_DEV_PMP_UNSUP || class == ATA_DEV_SEMB_UNSUP;
|
||||
}
|
||||
|
||||
static inline unsigned int ata_class_absent(unsigned int class)
|
||||
|
@ -1020,15 +1119,62 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
|
|||
}
|
||||
|
||||
/*
|
||||
* port helpers
|
||||
* link helpers
|
||||
*/
|
||||
static inline int ata_port_max_devices(const struct ata_port *ap)
|
||||
static inline int ata_is_host_link(const struct ata_link *link)
|
||||
{
|
||||
if (ap->flags & ATA_FLAG_SLAVE_POSS)
|
||||
return link == &link->ap->link;
|
||||
}
|
||||
|
||||
static inline int ata_link_max_devices(const struct ata_link *link)
|
||||
{
|
||||
if (ata_is_host_link(link) && link->ap->flags & ATA_FLAG_SLAVE_POSS)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int ata_link_active(struct ata_link *link)
|
||||
{
|
||||
return ata_tag_valid(link->active_tag) || link->sactive;
|
||||
}
|
||||
|
||||
static inline struct ata_link *ata_port_first_link(struct ata_port *ap)
|
||||
{
|
||||
if (ap->nr_pmp_links)
|
||||
return ap->pmp_link;
|
||||
return &ap->link;
|
||||
}
|
||||
|
||||
static inline struct ata_link *ata_port_next_link(struct ata_link *link)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
|
||||
if (link == &ap->link) {
|
||||
if (!ap->nr_pmp_links)
|
||||
return NULL;
|
||||
return ap->pmp_link;
|
||||
}
|
||||
|
||||
if (++link - ap->pmp_link < ap->nr_pmp_links)
|
||||
return link;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define __ata_port_for_each_link(lk, ap) \
|
||||
for ((lk) = &(ap)->link; (lk); (lk) = ata_port_next_link(lk))
|
||||
|
||||
#define ata_port_for_each_link(link, ap) \
|
||||
for ((link) = ata_port_first_link(ap); (link); \
|
||||
(link) = ata_port_next_link(link))
|
||||
|
||||
#define ata_link_for_each_dev(dev, link) \
|
||||
for ((dev) = (link)->device; \
|
||||
(dev) < (link)->device + ata_link_max_devices(link) || ((dev) = NULL); \
|
||||
(dev)++)
|
||||
|
||||
#define ata_link_for_each_dev_reverse(dev, link) \
|
||||
for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \
|
||||
(dev) >= (link)->device || ((dev) = NULL); (dev)--)
|
||||
|
||||
static inline u8 ata_chk_status(struct ata_port *ap)
|
||||
{
|
||||
|
@ -1110,9 +1256,11 @@ static inline u8 ata_wait_idle(struct ata_port *ap)
|
|||
{
|
||||
u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
|
||||
|
||||
#ifdef ATA_DEBUG
|
||||
if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ)))
|
||||
DPRINTK("ATA: abnormal status 0x%X on port 0x%p\n",
|
||||
status, ap->ioaddr.status_addr);
|
||||
ata_port_printk(ap, KERN_DEBUG, "abnormal Status 0x%X\n",
|
||||
status);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -1149,7 +1297,7 @@ static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf)
|
|||
{
|
||||
memset(tf, 0, sizeof(*tf));
|
||||
|
||||
tf->ctl = dev->ap->ctl;
|
||||
tf->ctl = dev->link->ap->ctl;
|
||||
if (dev->devno == 0)
|
||||
tf->device = ATA_DEVICE_OBS;
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue