1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-11 09:50:12 +00:00

Quite mechanical ch_detach implementations for all atapci subdrivers.

Some dmainit call fixes for previous commit.
This commit is contained in:
Alexander Motin 2009-02-19 00:32:55 +00:00
parent 8a520db77d
commit 78d154163c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=188769
17 changed files with 175 additions and 35 deletions

View File

@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ata/ata-pci.h>
/* prototypes */
static void ata_dmafini(device_t dev);
static void ata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
static void ata_dmaalloc(device_t dev);
static void ata_dmafree(device_t dev);

View File

@ -100,6 +100,7 @@ ata_pci_attach(device_t dev)
ctlr->channels = 1;
ctlr->ichannels = -1;
ctlr->ch_attach = ata_pci_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->dev = dev;
/* if needed try to enable busmastering */
@ -381,6 +382,21 @@ ata_pci_ch_attach(device_t dev)
return 0;
}
int
ata_pci_ch_detach(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
ata_pci_dmafini(dev);
bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,
ch->r_io[ATA_CONTROL].res);
bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID,
ch->r_io[ATA_IDX_ADDR].res);
return (0);
}
int
ata_pci_status(device_t dev)
{
@ -477,6 +493,12 @@ ata_pci_dmainit(device_t dev)
ch->dma.reset = ata_pci_dmareset;
}
void
ata_pci_dmafini(device_t dev)
{
ata_dmafini(dev);
}
static device_method_t ata_pci_methods[] = {
/* device interface */

View File

@ -410,9 +410,11 @@ int ata_pci_release_resource(device_t dev, device_t child, int type, int rid, st
int ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *function, void *argument, void **cookiep);
int ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie);
int ata_pci_ch_attach(device_t dev);
int ata_pci_ch_detach(device_t dev);
int ata_pci_status(device_t dev);
void ata_pci_hw(device_t dev);
void ata_pci_dmainit(device_t dev);
void ata_pci_dmafini(device_t dev);
char *ata_pcivendor2str(device_t dev);
int ata_legacy(device_t);
void ata_generic_intr(void *data);
@ -435,13 +437,14 @@ void ata_pm_identify(device_t dev);
/* global prototypes from chipsets/ata-*.c */
int ata_ahci_chipinit(device_t);
int ata_ahci_ch_attach(device_t dev);
int ata_ahci_ch_detach(device_t dev);
void ata_ahci_reset(device_t dev);
void ata_ahci_dmainit(device_t dev);
int ata_marvell_edma_chipinit(device_t);
int ata_sii_chipinit(device_t);
/* global prototypes ata-dma.c */
void ata_dmainit(device_t);
void ata_dmafini(device_t dev);
/* externs */
extern devclass_t ata_pci_devclass;

View File

@ -98,6 +98,7 @@ ata_acard_chipinit(device_t dev)
return ENXIO;
ctlr->ch_attach = ata_acard_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
if (ctlr->chip->cfg1 == ATP_OLD) {
ctlr->setmode = ata_acard_850_setmode;
ctlr->locking = ata_serialize;

View File

@ -106,6 +106,7 @@ ata_ali_chipinit(device_t dev)
case ALI_SATA:
ctlr->channels = ctlr->chip->cfg1;
ctlr->ch_attach = ata_ali_sata_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_sata_setmode;
/* AHCI mode is correctly supported only on the ALi 5288. */
@ -134,6 +135,7 @@ ata_ali_chipinit(device_t dev)
"using PIO transfers above 137GB as workaround for "
"48bit DMA access bug, expect reduced performance\n");
ctlr->ch_attach = ata_ali_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_ali_reset;
ctlr->setmode = ata_ali_setmode;
break;

View File

@ -62,6 +62,7 @@ static int ata_ahci_pm_write(device_t dev, int port, int reg, u_int32_t result);
static u_int32_t ata_ahci_softreset(device_t dev, int port);
static void ata_ahci_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
static int ata_ahci_setup_fis(struct ata_ahci_cmd_tab *ctp, struct ata_request *equest);
static void ata_ahci_dmainit(device_t dev);
/*
* AHCI v1.x compliant SATA chipset support functions
@ -129,6 +130,7 @@ ata_ahci_chipinit(device_t dev)
ctlr->reset = ata_ahci_reset;
ctlr->ch_attach = ata_ahci_ch_attach;
ctlr->ch_detach = ata_ahci_ch_detach;
ctlr->setmode = ata_sata_setmode;
ctlr->suspend = ata_ahci_suspend;
ctlr->resume = ata_ahci_ctlr_reset;
@ -225,6 +227,14 @@ ata_ahci_ch_attach(device_t dev)
return 0;
}
int
ata_ahci_ch_detach(device_t dev)
{
ata_dmafini(dev);
return (0);
}
static int
ata_ahci_status(device_t dev)
{
@ -763,7 +773,7 @@ ata_ahci_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
args->nsegs = nsegs;
}
void
static void
ata_ahci_dmainit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));

View File

@ -135,6 +135,7 @@ ata_highpoint_chipinit(device_t dev)
(pci_read_config(dev, 0x5b, 1) & 0x01) | 0x20, 1);
}
ctlr->ch_attach = ata_highpoint_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_highpoint_setmode;
return 0;
}

View File

@ -59,6 +59,7 @@ static void ata_intel_old_setmode(device_t dev, int mode);
static void ata_intel_new_setmode(device_t dev, int mode);
static void ata_intel_sata_setmode(device_t dev, int mode);
static int ata_intel_31244_ch_attach(device_t dev);
static int ata_intel_31244_ch_detach(device_t dev);
static int ata_intel_31244_status(device_t dev);
static void ata_intel_31244_tf_write(struct ata_request *request);
static void ata_intel_31244_reset(device_t dev);
@ -172,6 +173,7 @@ ata_intel_chipinit(device_t dev)
return ENXIO;
ctlr->channels = 4;
ctlr->ch_attach = ata_intel_31244_ch_attach;
ctlr->ch_detach = ata_intel_31244_ch_detach;
ctlr->reset = ata_intel_31244_reset;
}
ctlr->setmode = ata_sata_setmode;
@ -181,6 +183,7 @@ ata_intel_chipinit(device_t dev)
else if (ctlr->chip->max_dma < ATA_SA150) {
ctlr->channels = ctlr->chip->cfg2;
ctlr->ch_attach = ata_intel_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_intel_new_setmode;
}
@ -190,6 +193,7 @@ ata_intel_chipinit(device_t dev)
pci_write_config(dev, 0x92, pci_read_config(dev, 0x92, 2) | 0x0f, 2);
ctlr->ch_attach = ata_intel_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_intel_reset;
/*
@ -403,6 +407,8 @@ ata_intel_31244_ch_attach(device_t dev)
int i;
int ch_offset;
ata_pci_dmainit(dev);
ch_offset = 0x200 + ch->unit * 0x200;
for (i = ATA_DATA; i < ATA_MAX_RES; i++)
@ -443,6 +449,14 @@ ata_intel_31244_ch_attach(device_t dev)
return 0;
}
static int
ata_intel_31244_ch_detach(device_t dev)
{
ata_pci_dmafini(dev);
return (0);
}
static int
ata_intel_31244_status(device_t dev)
{

View File

@ -54,11 +54,10 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_jmicron_chipinit(device_t dev);
static int ata_jmicron_ch_attach(device_t dev);
static int ata_jmicron_ch_detach(device_t dev);
static void ata_jmicron_reset(device_t dev);
static void ata_jmicron_dmainit(device_t dev);
static void ata_jmicron_setmode(device_t dev, int mode);
/*
* JMicron chipset support functions
*/
@ -113,6 +112,7 @@ ata_jmicron_chipinit(device_t dev)
/* otherwise we are on the PATA part */
ctlr->ch_attach = ata_pci_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_generic_reset;
ctlr->setmode = ata_jmicron_setmode;
ctlr->channels = ctlr->chip->cfg2;
@ -126,6 +126,7 @@ ata_jmicron_chipinit(device_t dev)
return error;
ctlr->ch_attach = ata_jmicron_ch_attach;
ctlr->ch_detach = ata_jmicron_ch_detach;
ctlr->reset = ata_jmicron_reset;
ctlr->setmode = ata_jmicron_setmode;
@ -142,8 +143,6 @@ ata_jmicron_ch_attach(device_t dev)
struct ata_channel *ch = device_get_softc(dev);
int error;
ata_jmicron_dmainit(dev);
if (ch->unit >= ctlr->chip->cfg1) {
ch->unit -= ctlr->chip->cfg1;
error = ata_pci_ch_attach(dev);
@ -154,6 +153,24 @@ ata_jmicron_ch_attach(device_t dev)
return error;
}
static int
ata_jmicron_ch_detach(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
int error;
if (ch->unit >= ctlr->chip->cfg1) {
ch->unit -= ctlr->chip->cfg1;
error = ata_pci_ch_detach(dev);
ch->unit += ctlr->chip->cfg1;
}
else
error = ata_ahci_ch_detach(dev);
return (error);
}
static void
ata_jmicron_reset(device_t dev)
{
@ -166,18 +183,6 @@ ata_jmicron_reset(device_t dev)
ata_ahci_reset(dev);
}
static void
ata_jmicron_dmainit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
if (ch->unit >= ctlr->chip->cfg1)
ata_pci_dmainit(dev);
else
ata_ahci_dmainit(dev);
}
static void
ata_jmicron_setmode(device_t dev, int mode)
{

View File

@ -56,6 +56,7 @@ static int ata_marvell_pata_chipinit(device_t dev);
static int ata_marvell_pata_ch_attach(device_t dev);
static void ata_marvell_pata_setmode(device_t dev, int mode);
static int ata_marvell_edma_ch_attach(device_t dev);
static int ata_marvell_edma_ch_detach(device_t dev);
static int ata_marvell_edma_status(device_t dev);
static int ata_marvell_edma_begin_transaction(struct ata_request *request);
static int ata_marvell_edma_end_transaction(struct ata_request *request);
@ -136,6 +137,7 @@ ata_marvell_pata_chipinit(device_t dev)
return ENXIO;
ctlr->ch_attach = ata_marvell_pata_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_marvell_pata_setmode;
ctlr->channels = ctlr->chip->cfg1;
return 0;
@ -190,6 +192,7 @@ ata_marvell_edma_chipinit(device_t dev)
ATA_OUTL(ctlr->r_res1, 0x01d5c, 0x00000000);
ctlr->ch_attach = ata_marvell_edma_ch_attach;
ctlr->ch_detach = ata_marvell_edma_ch_detach;
ctlr->reset = ata_marvell_edma_reset;
ctlr->setmode = ata_sata_setmode;
ctlr->channels = ctlr->chip->cfg1;
@ -307,6 +310,14 @@ ata_marvell_edma_ch_attach(device_t dev)
return 0;
}
static int
ata_marvell_edma_ch_detach(device_t dev)
{
ata_dmafini(dev);
return (0);
}
static int
ata_marvell_edma_status(device_t dev)
{

View File

@ -82,6 +82,7 @@ ata_netcell_chipinit(device_t dev)
return ENXIO;
ctlr->ch_attach = ata_netcell_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_netcell_setmode;
return 0;
}

View File

@ -131,6 +131,7 @@ ata_nvidia_chipinit(device_t dev)
int offset = ctlr->chip->cfg1 & NV4 ? 0x0440 : 0x0010;
ctlr->ch_attach = ata_nvidia_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_nvidia_reset;
/* enable control access */

View File

@ -58,11 +58,11 @@ static int ata_promise_status(device_t dev);
static int ata_promise_dmastart(struct ata_request *request);
static int ata_promise_dmastop(struct ata_request *request);
static void ata_promise_dmareset(device_t dev);
static void ata_promise_dmainit(device_t dev);
static void ata_promise_setmode(device_t dev, int mode);
static int ata_promise_tx2_ch_attach(device_t dev);
static int ata_promise_tx2_status(device_t dev);
static int ata_promise_mio_ch_attach(device_t dev);
static int ata_promise_mio_ch_detach(device_t dev);
static void ata_promise_mio_intr(void *data);
static int ata_promise_mio_status(device_t dev);
static int ata_promise_mio_command(struct ata_request *request);
@ -232,11 +232,13 @@ ata_promise_chipinit(device_t dev)
/* enable burst mode */
ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
ctlr->ch_attach = ata_promise_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_promise_setmode;
return 0;
case PR_TX:
ctlr->ch_attach = ata_promise_tx2_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_promise_setmode;
return 0;
@ -283,6 +285,7 @@ ata_promise_chipinit(device_t dev)
hpkt->busy = 0;
device_set_ivars(dev, hpkt);
ctlr->ch_attach = ata_promise_mio_ch_attach;
ctlr->ch_detach = ata_promise_mio_ch_detach;
ctlr->reset = ata_promise_mio_reset;
ctlr->setmode = ata_promise_setmode;
ctlr->channels = 4;
@ -335,6 +338,7 @@ ata_promise_chipinit(device_t dev)
ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000);
ctlr->ch_attach = ata_promise_mio_ch_attach;
ctlr->ch_detach = ata_promise_mio_ch_detach;
ctlr->reset = ata_promise_mio_reset;
ctlr->setmode = ata_promise_mio_setmode;
@ -355,12 +359,15 @@ ata_promise_ch_attach(device_t dev)
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
if (ctlr->chip->cfg1 == PR_NEW)
ata_promise_dmainit(dev);
if (ata_pci_ch_attach(dev))
return ENXIO;
if (ctlr->chip->cfg1 == PR_NEW) {
ch->dma.start = ata_promise_dmastart;
ch->dma.stop = ata_promise_dmastop;
ch->dma.reset = ata_promise_dmareset;
}
ch->hw.status = ata_promise_status;
return 0;
}
@ -433,17 +440,6 @@ ata_promise_dmareset(device_t dev)
ch->flags &= ~ATA_DMA_ACTIVE;
}
static void
ata_promise_dmainit(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
ata_dmainit(dev);
ch->dma.start = ata_promise_dmastart;
ch->dma.stop = ata_promise_dmastop;
ch->dma.reset = ata_promise_dmareset;
}
static void
ata_promise_setmode(device_t dev, int mode)
{
@ -588,6 +584,14 @@ ata_promise_mio_ch_attach(device_t dev)
return 0;
}
static int
ata_promise_mio_ch_detach(device_t dev)
{
ata_dmafini(dev);
return (0);
}
static void
ata_promise_mio_intr(void *data)
{

View File

@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_serverworks_chipinit(device_t dev);
static int ata_serverworks_ch_attach(device_t dev);
static int ata_serverworks_ch_detach(device_t dev);
static void ata_serverworks_tf_read(struct ata_request *request);
static void ata_serverworks_tf_write(struct ata_request *request);
static void ata_serverworks_setmode(device_t dev, int mode);
@ -114,6 +115,7 @@ ata_serverworks_chipinit(device_t dev)
ctlr->channels = ctlr->chip->cfg2;
ctlr->ch_attach = ata_serverworks_ch_attach;
ctlr->ch_detach = ata_serverworks_ch_detach;
ctlr->setmode = ata_sata_setmode;
return 0;
}
@ -151,6 +153,8 @@ ata_serverworks_ch_attach(device_t dev)
int ch_offset;
int i;
ata_pci_dmainit(dev);
ch_offset = ch->unit * 0x100;
for (i = ATA_DATA; i < ATA_MAX_RES; i++)
@ -189,6 +193,14 @@ ata_serverworks_ch_attach(device_t dev)
return 0;
}
static int
ata_serverworks_ch_detach(device_t dev)
{
ata_pci_dmafini(dev);
return (0);
}
static void
ata_serverworks_tf_read(struct ata_request *request)
{

View File

@ -56,10 +56,12 @@ static int ata_cmd_ch_attach(device_t dev);
static int ata_cmd_status(device_t dev);
static void ata_cmd_setmode(device_t dev, int mode);
static int ata_sii_ch_attach(device_t dev);
static int ata_sii_ch_detach(device_t dev);
static int ata_sii_status(device_t dev);
static void ata_sii_reset(device_t dev);
static void ata_sii_setmode(device_t dev, int mode);
static int ata_siiprb_ch_attach(device_t dev);
static int ata_siiprb_ch_detach(device_t dev);
static int ata_siiprb_status(device_t dev);
static int ata_siiprb_begin_transaction(struct ata_request *request);
static int ata_siiprb_end_transaction(struct ata_request *request);
@ -139,6 +141,7 @@ ata_sii_chipinit(device_t dev)
return ENXIO;
}
ctlr->ch_attach = ata_siiprb_ch_attach;
ctlr->ch_detach = ata_siiprb_ch_detach;
ctlr->reset = ata_siiprb_reset;
ctlr->setmode = ata_sata_setmode;
ctlr->channels = (ctlr->chip->cfg2 == SII_4CH) ? 4 : 2;
@ -185,8 +188,10 @@ ata_sii_chipinit(device_t dev)
/* enable PCI interrupt as BIOS might not */
pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1);
if (ctlr->r_res2)
if (ctlr->r_res2) {
ctlr->ch_attach = ata_sii_ch_attach;
ctlr->ch_detach = ata_sii_ch_detach;
}
if (ctlr->chip->max_dma >= ATA_SA150) {
ctlr->reset = ata_sii_reset;
@ -206,6 +211,7 @@ ata_sii_chipinit(device_t dev)
pci_write_config(dev, 0x71, 0x01, 1);
ctlr->ch_attach = ata_cmd_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_cmd_setmode;
break;
}
@ -306,6 +312,8 @@ ata_sii_ch_attach(device_t dev)
int unit01 = (ch->unit & 1), unit10 = (ch->unit & 2);
int i;
ata_pci_dmainit(dev);
for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
ch->r_io[i].res = ctlr->r_res2;
ch->r_io[i].offset = 0x80 + i + (unit01 << 6) + (unit10 << 8);
@ -346,6 +354,14 @@ ata_sii_ch_attach(device_t dev)
return 0;
}
static int
ata_sii_ch_detach(device_t dev)
{
ata_pci_dmafini(dev);
return (0);
}
static int
ata_sii_status(device_t dev)
{
@ -495,6 +511,14 @@ ata_siiprb_ch_attach(device_t dev)
return 0;
}
static int
ata_siiprb_ch_detach(device_t dev)
{
ata_dmafini(dev);
return 0;
}
static int
ata_siiprb_status(device_t dev)
{

View File

@ -187,6 +187,7 @@ ata_sis_chipinit(device_t dev)
if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
&ctlr->r_rid2, RF_ACTIVE))) {
ctlr->ch_attach = ata_sis_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_sis_reset;
/* enable PCI interrupt */

View File

@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_via_chipinit(device_t dev);
static int ata_via_ch_attach(device_t dev);
static int ata_via_ch_detach(device_t dev);
static void ata_via_reset(device_t dev);
static void ata_via_old_setmode(device_t dev, int mode);
static void ata_via_southbridge_fixup(device_t dev);
@ -140,6 +141,7 @@ ata_via_chipinit(device_t dev)
if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
&ctlr->r_rid2, RF_ACTIVE))) {
ctlr->ch_attach = ata_via_ch_attach;
ctlr->ch_detach = ata_via_ch_detach;
ctlr->reset = ata_via_reset;
/* enable PCI interrupt */
@ -194,6 +196,8 @@ ata_via_ch_attach(device_t dev)
struct resource *r_io;
int i, rid;
ata_pci_dmainit(dev);
rid = PCIR_BAR(ch->unit);
if (!(r_io = bus_alloc_resource_any(device_get_parent(dev),
SYS_RES_IOPORT,
@ -235,6 +239,31 @@ ata_via_ch_attach(device_t dev)
return 0;
}
static int
ata_via_ch_detach(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
/* newer SATA chips has resources in one BAR for each channel */
if (ctlr->chip->cfg2 & VIABAR) {
int rid;
rid = PCIR_BAR(ch->unit);
bus_release_resource(device_get_parent(dev),
SYS_RES_IOPORT, rid, ch->r_io[ATA_CONTROL].res);
ata_pci_dmafini(dev);
}
else {
/* setup the usual register normal pci style */
if (ata_pci_ch_detach(dev))
return ENXIO;
}
return 0;
}
static void
ata_via_reset(device_t dev)
{