// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Promise PATA TX2 / TX4 / TX2000 / 133 IDE driver for pdc20268 to pdc20277 .
*
* Ported to libata by :
* Albert Lee < albertcc @ tw . ibm . com > IBM Corporation
*
* Copyright ( C ) 1998 - 2002 Andre Hedrick < andre @ linux - ide . org >
* Portions Copyright ( C ) 1999 Promise Technology , Inc .
*
* Author : Frank Tiernan ( frankt @ promise . com )
* Released under terms of General Public License
*
* libata documentation is available via ' make { ps | pdf } docs ' ,
* as Documentation / driver - api / libata . rst
*
* Hardware information only available under NDA .
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/ktime.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#define DRV_NAME "pata_pdc2027x"
#define DRV_VERSION "1.0"
enum {
PDC_MMIO_BAR = 5 ,
PDC_UDMA_100 = 0 ,
PDC_UDMA_133 = 1 ,
PDC_100_MHZ = 100000000 ,
PDC_133_MHZ = 133333333 ,
PDC_SYS_CTL = 0 x1100,
PDC_ATA_CTL = 0 x1104,
PDC_GLOBAL_CTL = 0 x1108,
PDC_CTCR0 = 0 x110C,
PDC_CTCR1 = 0 x1110,
PDC_BYTE_COUNT = 0 x1120,
PDC_PLL_CTL = 0 x1202,
};
static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
#ifdef CONFIG_PM_SLEEP
static int pdc2027x_reinit_one(struct pci_dev *pdev);
#endif
static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline);
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
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 int pdc2027x_mode_filter(struct ata_device *adev, unsigned int mask);
static int pdc2027x_cable_detect(struct ata_port *ap);
static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed);
/*
* ATA Timing Tables based on 133 MHz controller clock .
* These tables are only used when the controller is in 133 MHz clock .
* If the controller is in 100 MHz clock , the ASIC hardware will
* set the timing registers automatically when " set feature " command
* is issued to the device . However , if the controller clock is 133 MHz ,
* the following tables must be used .
*/
static const struct pdc2027x_pio_timing {
u8 value0, value1, value2;
} pdc2027x_pio_timing_tbl[] = {
{ 0 xfb, 0 x2b, 0 xac }, /* PIO mode 0 */
{ 0 x46, 0 x29, 0 xa4 }, /* PIO mode 1 */
{ 0 x23, 0 x26, 0 x64 }, /* PIO mode 2 */
{ 0 x27, 0 x0d, 0 x35 }, /* PIO mode 3, IORDY on, Prefetch off */
{ 0 x23, 0 x09, 0 x25 }, /* PIO mode 4, IORDY on, Prefetch off */
};
static const struct pdc2027x_mdma_timing {
u8 value0, value1;
} pdc2027x_mdma_timing_tbl[] = {
{ 0 xdf, 0 x5f }, /* MDMA mode 0 */
{ 0 x6b, 0 x27 }, /* MDMA mode 1 */
{ 0 x69, 0 x25 }, /* MDMA mode 2 */
};
static const struct pdc2027x_udma_timing {
u8 value0, value1, value2;
} pdc2027x_udma_timing_tbl[] = {
{ 0 x4a, 0 x0f, 0 xd5 }, /* UDMA mode 0 */
{ 0 x3a, 0 x0a, 0 xd0 }, /* UDMA mode 1 */
{ 0 x2a, 0 x07, 0 xcd }, /* UDMA mode 2 */
{ 0 x1a, 0 x05, 0 xcd }, /* UDMA mode 3 */
{ 0 x1a, 0 x03, 0 xcd }, /* UDMA mode 4 */
{ 0 x1a, 0 x02, 0 xcb }, /* UDMA mode 5 */
{ 0 x1a, 0 x01, 0 xcb }, /* UDMA mode 6 */
};
static const struct pci_device_id pdc2027x_pci_tbl[] = {
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), PDC_UDMA_100 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), PDC_UDMA_133 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), PDC_UDMA_100 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), PDC_UDMA_133 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), PDC_UDMA_133 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), PDC_UDMA_133 },
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), PDC_UDMA_133 },
{ } /* terminate list */
};
static struct pci_driver pdc2027x_pci_driver = {
.name = DRV_NAME,
.id_table = pdc2027x_pci_tbl,
.probe = pdc2027x_init_one,
.remove = ata_pci_remove_one,
#ifdef CONFIG_PM_SLEEP
.suspend = ata_pci_device_suspend,
.resume = pdc2027x_reinit_one,
#endif
};
static const struct scsi_host_template pdc2027x_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations pdc2027x_pata100_ops = {
.inherits = &ata_bmdma_port_ops,
.check_atapi_dma = pdc2027x_check_atapi_dma,
.cable_detect = pdc2027x_cable_detect,
.reset.prereset = pdc2027x_prereset,
};
static struct ata_port_operations pdc2027x_pata133_ops = {
.inherits = &pdc2027x_pata100_ops,
.mode_filter = pdc2027x_mode_filter,
.set_piomode = pdc2027x_set_piomode,
.set_dmamode = pdc2027x_set_dmamode,
.set_mode = pdc2027x_set_mode,
};
static struct ata_port_info pdc2027x_port_info[] = {
/* PDC_UDMA_100 */
{
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &pdc2027x_pata100_ops,
},
/* PDC_UDMA_133 */
{
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc2027x_pata133_ops,
},
};
MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Albert Lee" );
MODULE_DESCRIPTION("libata driver module for Promise PDC20268 to PDC20277" );
MODULE_LICENSE("GPL" );
MODULE_VERSION(DRV_VERSION);
MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl);
/**
* port_mmio - Get the MMIO address of PDC2027x extended registers
* @ ap : Port
* @ offset : offset from mmio base
*/
static inline void __iomem *port_mmio(struct ata_port *ap, unsigned int offset)
{
return ap->host->iomap[PDC_MMIO_BAR] + ap->port_no * 0 x100 + offset;
}
/**
* dev_mmio - Get the MMIO address of PDC2027x extended registers
* @ ap : Port
* @ adev : device
* @ offset : offset from mmio base
*/
static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *adev, unsigned int offset)
{
u8 adj = (adev->devno) ? 0 x08 : 0 x00;
return port_mmio(ap, offset) + adj;
}
/**
* pdc2027x_cable_detect - Probe host controller cable detect info
* @ ap : Port for which cable detect info is desired
*
* Read 80 c cable indicator from Promise extended register .
* This register is latched when the system is reset .
*
* LOCKING :
* None ( inherited from caller ) .
*/
static int pdc2027x_cable_detect(struct ata_port *ap)
{
u32 cgcr;
/* check cable detect results */
cgcr = ioread32(port_mmio(ap, PDC_GLOBAL_CTL));
if (cgcr & (1 << 26 ))
goto cbl40;
ata_port_dbg(ap, "No cable or 80-conductor cable\n" );
return ATA_CBL_PATA80;
cbl40:
ata_port_info(ap, DRV_NAME ":40-conductor cable detected\n" );
return ATA_CBL_PATA40;
}
/**
* pdc2027x_port_enabled - Check PDC ATA control register to see whether the port is enabled .
* @ ap : Port to check
*/
static inline int pdc2027x_port_enabled(struct ata_port *ap)
{
return ioread8(port_mmio(ap, PDC_ATA_CTL)) & 0 x02;
}
/**
* pdc2027x_prereset - prereset for PATA host controller
* @ link : Target link
* @ deadline : deadline jiffies for the operation
*
* Probeinit including cable detection .
*
* LOCKING :
* None ( inherited from caller ) .
*/
static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline)
{
/* Check whether port enabled */
if (!pdc2027x_port_enabled(link->ap))
return -ENOENT;
return ata_sff_prereset(link, deadline);
}
/**
* pdc2027x_mode_filter - mode selection filter
* @ adev : ATA device
* @ mask : list of modes proposed
*
* Block UDMA on devices that cause trouble with this controller .
*/
static unsigned int pdc2027x_mode_filter(struct ata_device *adev, unsigned int mask)
{
unsigned char model_num[ATA_ID_PROD_LEN + 1 ];
struct ata_device *pair = ata_dev_pair(adev);
if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
return mask;
/* Check for slave of a Maxtor at UDMA6 */
ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
ATA_ID_PROD_LEN + 1 );
/* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */
if (strstr(model_num, "Maxtor" ) == NULL && pair->dma_mode == XFER_UDMA_6)
mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
return mask;
}
/**
* pdc2027x_set_piomode - Initialize host controller PATA PIO timings
* @ ap : Port to configure
* @ adev : um
*
* Set PIO mode for device .
*
* LOCKING :
* None ( inherited from caller ) .
*/
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
unsigned int pio = adev->pio_mode - XFER_PIO_0;
u32 ctcr0, ctcr1;
ata_port_dbg(ap, "adev->pio_mode[%X]\n" , adev->pio_mode);
/* Sanity check */
if (pio > 4 ) {
ata_port_err(ap, "Unknown pio mode [%d] ignored\n" , pio);
return ;
}
/* Set the PIO timing registers using value table for 133MHz */
ata_port_dbg(ap, "Set PIO regs...\n" );
ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0));
ctcr0 &= 0 xffff0000;
ctcr0 |= pdc2027x_pio_timing_tbl[pio].value0 |
(pdc2027x_pio_timing_tbl[pio].value1 << 8 );
iowrite32(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
ctcr1 &= 0 x00ffffff;
ctcr1 |= (pdc2027x_pio_timing_tbl[pio].value2 << 24 );
iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
ata_port_dbg(ap, "Set to PIO mode[%u]\n" , pio);
}
/**
* pdc2027x_set_dmamode - Initialize host controller PATA UDMA timings
* @ ap : Port to configure
* @ adev : um
*
* Set UDMA mode for device .
*
* LOCKING :
* None ( inherited from caller ) .
*/
static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
unsigned int dma_mode = adev->dma_mode;
u32 ctcr0, ctcr1;
if ((dma_mode >= XFER_UDMA_0) &&
(dma_mode <= XFER_UDMA_6)) {
/* Set the UDMA timing registers with value table for 133MHz */
unsigned int udma_mode = dma_mode & 0 x07;
if (dma_mode == XFER_UDMA_2) {
/*
* Turn off tHOLD .
* 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 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
iowrite32(ctcr1 & ~(1 << 7 ), dev_mmio(ap, adev, PDC_CTCR1));
}
ata_port_dbg(ap, "Set UDMA regs...\n" );
ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1));
ctcr1 &= 0 xff000000;
ctcr1 |= pdc2027x_udma_timing_tbl[udma_mode].value0 |
(pdc2027x_udma_timing_tbl[udma_mode].value1 << 8 ) |
(pdc2027x_udma_timing_tbl[udma_mode].value2 << 16 );
iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1));
ata_port_dbg(ap, "Set to UDMA mode[%u]\n" , udma_mode);
} else if ((dma_mode >= XFER_MW_DMA_0) &&
(dma_mode <= XFER_MW_DMA_2)) {
/* Set the MDMA timing registers with value table for 133MHz */
unsigned int mdma_mode = dma_mode & 0 x07;
ata_port_dbg(ap, "Set MDMA regs...\n" );
ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0));
ctcr0 &= 0 x0000ffff;
ctcr0 |= (pdc2027x_mdma_timing_tbl[mdma_mode].value0 << 16 ) |
(pdc2027x_mdma_timing_tbl[mdma_mode].value1 << 24 );
iowrite32(ctcr0, dev_mmio(ap, adev, PDC_CTCR0));
ata_port_dbg(ap, "Set to MDMA mode[%u]\n" , mdma_mode);
} else {
ata_port_err(ap, "Unknown dma mode [%u] ignored\n" , dma_mode);
}
}
/**
* pdc2027x_set_mode - Set the timing registers back to correct values .
* @ 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 133 Mhz PLL .
* This function overwrites the possibly incorrect values set by the hardware to be correct .
*/
static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed)
{
struct ata_port *ap = link->ap;
struct ata_device *dev;
int rc;
rc = ata_set_mode(link, r_failed);
if (rc < 0 )
return rc;
ata_for_each_dev(dev, link, ENABLED) {
pdc2027x_set_piomode(ap, dev);
/*
* Enable prefetch if the device support PIO only .
*/
if (dev->xfer_shift == ATA_SHIFT_PIO) {
u32 ctcr1 = ioread32(dev_mmio(ap, dev, PDC_CTCR1));
ctcr1 |= (1 << 25 );
iowrite32(ctcr1, dev_mmio(ap, dev, PDC_CTCR1));
ata_dev_dbg(dev, "Turn on prefetch\n" );
} else {
pdc2027x_set_dmamode(ap, dev);
}
}
return 0 ;
}
/**
* pdc2027x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command
* @ qc : Metadata associated with taskfile to check
*
* LOCKING :
* None ( inherited from caller ) .
*
* RETURNS : 0 when ATAPI DMA can be used
* 1 otherwise
*/
static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *cmd = qc->scsicmd;
u8 *scsicmd = cmd->cmnd;
int rc = 1 ; /* atapi dma off by default */
/*
* This workaround is from Promise ' s GPL driver .
* If ATAPI DMA is used for commands not in the
* following white list , say MODE_SENSE and REQUEST_SENSE ,
* pdc2027x might hit the irq lost problem .
*/
switch (scsicmd[0 ]) {
case READ_10:
case WRITE_10:
case READ_12:
case WRITE_12:
case READ_6:
case WRITE_6:
case 0 xad: /* READ_DVD_STRUCTURE */
case 0 xbe: /* READ_CD */
/* ATAPI DMA is ok */
rc = 0 ;
break ;
default :
;
}
return rc;
}
/**
* pdc_read_counter - Read the ctr counter
* @ host : target ATA host
*/
static long pdc_read_counter(struct ata_host *host)
{
void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
long counter;
int retry = 1 ;
u32 bccrl, bccrh, bccrlv, bccrhv;
retry:
bccrl = ioread32(mmio_base + PDC_BYTE_COUNT) & 0 x7fff;
bccrh = ioread32(mmio_base + PDC_BYTE_COUNT + 0 x100) & 0 x7fff;
/* Read the counter values again for verification */
bccrlv = ioread32(mmio_base + PDC_BYTE_COUNT) & 0 x7fff;
bccrhv = ioread32(mmio_base + PDC_BYTE_COUNT + 0 x100) & 0 x7fff;
counter = (bccrh << 15 ) | bccrl;
dev_dbg(host->dev, "bccrh [%X] bccrl [%X]\n" , bccrh, bccrl);
dev_dbg(host->dev, "bccrhv[%X] bccrlv[%X]\n" , bccrhv, bccrlv);
/*
* The 30 - bit decreasing counter are read by 2 pieces .
* Incorrect value may be read when both bccrh and bccrl are changing .
* Ex . When 7900 decrease to 78 FF , wrong value 7800 might be read .
*/
if (retry && !(bccrh == bccrhv && bccrl >= bccrlv)) {
retry--;
dev_dbg(host->dev, "rereading counter\n" );
goto retry;
}
return counter;
}
/**
* pdc_adjust_pll - Adjust the PLL input clock in Hz .
*
* @ host : target ATA host
* @ pll_clock : The input of PLL in HZ
* @ board_idx : board identifier
*/
static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int board_idx)
{
void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
u16 pll_ctl;
long pll_clock_khz = pll_clock / 1000 ;
long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ;
long ratio = pout_required / pll_clock_khz;
int F, R;
/* Sanity check */
if (unlikely(pll_clock_khz < 5000 L || pll_clock_khz > 70000 L)) {
dev_err(host->dev, "Invalid PLL input clock %ldkHz, give up!\n" ,
pll_clock_khz);
return ;
}
dev_dbg(host->dev, "pout_required is %ld\n" , pout_required);
/* Show the current clock value of PLL control register
* ( maybe already configured by the firmware )
*/
pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
dev_dbg(host->dev, "pll_ctl[%X]\n" , pll_ctl);
/*
* Calculate the ratio of F , R and OD
* POUT = ( F + 2 ) / ( ( R + 2 ) * NO )
*/
if (ratio < 8600 L) { /* 8.6x */
/* Using NO = 0x01, R = 0x0D */
R = 0 x0d;
} else if (ratio < 12900 L) { /* 12.9x */
/* Using NO = 0x01, R = 0x08 */
R = 0 x08;
} else if (ratio < 16100 L) { /* 16.1x */
/* Using NO = 0x01, R = 0x06 */
R = 0 x06;
} else if (ratio < 64000 L) { /* 64x */
R = 0 x00;
} else {
/* Invalid ratio */
dev_err(host->dev, "Invalid ratio %ld, give up!\n" , ratio);
return ;
}
F = (ratio * (R+2 )) / 1000 - 2 ;
if (unlikely(F < 0 || F > 127 )) {
/* Invalid F */
dev_err(host->dev, "F[%d] invalid!\n" , F);
return ;
}
dev_dbg(host->dev, "F[%d] R[%d] ratio*1000[%ld]\n" , F, R, ratio);
pll_ctl = (R << 8 ) | F;
dev_dbg(host->dev, "Writing pll_ctl[%X]\n" , pll_ctl);
iowrite16(pll_ctl, mmio_base + PDC_PLL_CTL);
ioread16(mmio_base + PDC_PLL_CTL); /* flush */
/* Wait the PLL circuit to be stable */
msleep(30 );
/*
* Show the current clock value of PLL control register
* ( maybe configured by the firmware )
*/
pll_ctl = ioread16(mmio_base + PDC_PLL_CTL);
dev_dbg(host->dev, "pll_ctl[%X]\n" , pll_ctl);
return ;
}
/**
* pdc_detect_pll_input_clock - Detect the PLL input clock in Hz .
* @ host : target ATA host
* Ex . 16949000 on 33 MHz PCI bus for pdc20275 .
* Half of the PCI clock .
*/
static long pdc_detect_pll_input_clock(struct ata_host *host)
{
void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
u32 scr;
long start_count, end_count;
ktime_t start_time, end_time;
long pll_clock, usec_elapsed;
/* Start the test mode */
scr = ioread32(mmio_base + PDC_SYS_CTL);
dev_dbg(host->dev, "scr[%X]\n" , scr);
iowrite32(scr | (0 x01 << 14 ), mmio_base + PDC_SYS_CTL);
ioread32(mmio_base + PDC_SYS_CTL); /* flush */
/* Read current counter value */
start_count = pdc_read_counter(host);
start_time = ktime_get();
/* Let the counter run for 100 ms. */
msleep(100 );
/* Read the counter values again */
end_count = pdc_read_counter(host);
end_time = ktime_get();
/* Stop the test mode */
scr = ioread32(mmio_base + PDC_SYS_CTL);
dev_dbg(host->dev, "scr[%X]\n" , scr);
iowrite32(scr & ~(0 x01 << 14 ), mmio_base + PDC_SYS_CTL);
ioread32(mmio_base + PDC_SYS_CTL); /* flush */
/* calculate the input clock in Hz */
usec_elapsed = (long ) ktime_us_delta(end_time, start_time);
pll_clock = ((start_count - end_count) & 0 x3fffffff) / 100 *
(100000000 / usec_elapsed);
dev_dbg(host->dev, "start[%ld] end[%ld] PLL input clock[%ld]HZ\n" ,
start_count, end_count, pll_clock);
return pll_clock;
}
/**
* pdc_hardware_init - Initialize the hardware .
* @ host : target ATA host
* @ board_idx : board identifier
*/
static void pdc_hardware_init(struct ata_host *host, unsigned int board_idx)
{
long pll_clock;
/*
* Detect PLL input clock rate .
* On some system , where PCI bus is running at non - standard clock rate .
* Ex . 25 MHz or 40 MHz , we have to adjust the cycle_time .
* The pdc20275 controller employs PLL circuit to help correct timing registers setting .
*/
pll_clock = pdc_detect_pll_input_clock(host);
dev_info(host->dev, "PLL input clock %ld kHz\n" , pll_clock/1000 );
/* Adjust PLL control register */
pdc_adjust_pll(host, pll_clock, board_idx);
}
/**
* pdc_ata_setup_port - setup the mmio address
* @ port : ata ioports to setup
* @ base : base address
*/
static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr =
port->data_addr = base;
port->feature_addr =
port->error_addr = base + 0 x05;
port->nsect_addr = base + 0 x0a;
port->lbal_addr = base + 0 x0f;
port->lbam_addr = base + 0 x10;
port->lbah_addr = base + 0 x15;
port->device_addr = base + 0 x1a;
port->command_addr =
port->status_addr = base + 0 x1f;
port->altstatus_addr =
port->ctl_addr = base + 0 x81a;
}
/**
* pdc2027x_init_one - PCI probe function
* Called when an instance of PCI adapter is inserted .
* This function checks whether the hardware is supported ,
* initialize hardware and register an instance of ata_host to
* libata . ( implements struct pci_driver . probe ( ) )
*
* @ pdev : instance of pci_dev found
* @ ent : matching entry in the id_tbl [ ]
*/
static int pdc2027x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
static const unsigned long cmd_offset[] = { 0 x17c0, 0 x15c0 };
static const unsigned long bmdma_offset[] = { 0 x1000, 0 x1008 };
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 i, rc;
ata_print_version_once(&pdev->dev, DRV_VERSION);
/* alloc host */
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2 );
if (!host)
return -ENOMEM;
/* acquire resources and fill host */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
if (rc)
return rc;
host->iomap = pcim_iomap_table(pdev);
rc = dma_set_mask_and_coherent(&pdev->dev, ATA_DMA_MASK);
if (rc)
return rc;
mmio_base = host->iomap[PDC_MMIO_BAR];
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);
/* initialize adapter */
pdc_hardware_init(host, board_idx);
pci_set_master(pdev);
return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &pdc2027x_sht);
}
#ifdef CONFIG_PM_SLEEP
static int pdc2027x_reinit_one(struct pci_dev *pdev)
{
struct ata_host *host = pci_get_drvdata(pdev);
unsigned int board_idx;
int rc;
rc = ata_pci_device_do_resume(pdev);
if (rc)
return rc;
if (pdev->device == PCI_DEVICE_ID_PROMISE_20268 ||
pdev->device == PCI_DEVICE_ID_PROMISE_20270)
board_idx = PDC_UDMA_100;
else
board_idx = PDC_UDMA_133;
pdc_hardware_init(host, board_idx);
ata_host_resume(host);
return 0 ;
}
#endif
module_pci_driver(pdc2027x_pci_driver);
Messung V0.5 in Prozent C=90 H=98 G=94
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland