FreeBSD Bugzilla – Attachment 15482 Details for
Bug 28692
[sound] ICH sound driver hangs kernel
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 5.95 KB, created by
SAKIYAMA Nobuo
on 2001-07-04 18:00:14 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
SAKIYAMA Nobuo
Created:
2001-07-04 18:00:14 UTC
Size:
5.95 KB
patch
obsolete
>Index: ich.c >=================================================================== >RCS file: /home/ncvs/src/sys/dev/sound/pci/ich.c,v >retrieving revision 1.1 >diff -u -r1.1 ich.c >--- ich.c 2001/07/01 19:38:56 1.1 >+++ ich.c 2001/07/04 16:26:26 >@@ -108,6 +108,7 @@ > #define AC97_POWER_PINREADY 0x0001 > #define AC97_POWER_POUTPOWER 0x0200 > #define AC97_POWER_POUTREADY 0x0002 >+#define AC97_POWER_D3 0xFF00 > > /* play/record buffer */ > #define ICH_FIFOINDEX 32 >@@ -131,6 +132,7 @@ > struct ich_desc *index; > bus_dmamap_t imap; > u_int32_t lvi; >+ int run_save; > }; > > /* device private data */ >@@ -212,36 +214,45 @@ > /* -------------------------------------------------------------------- */ > /* Hardware */ > static u_int32_t >-ich_rd(struct sc_info *sc, int regno, int size) >+ich_rd_1(struct sc_info *sc, int regno) > { >- switch (size) { >- case 1: >- return bus_space_read_1(sc->nambart, sc->nambarh, regno); >- case 2: >- return bus_space_read_2(sc->nambart, sc->nambarh, regno); >- case 4: >- return bus_space_read_4(sc->nambart, sc->nambarh, regno); >- default: >- return 0xffffffff; >- } >+ return bus_space_read_1(sc->nambart, sc->nambarh, regno); > } > >+static u_int32_t >+ich_rd_2(struct sc_info *sc, int regno) >+{ >+ return bus_space_read_2(sc->nambart, sc->nambarh, regno); >+} >+ >+static u_int32_t >+ich_rd_4(struct sc_info *sc, int regno) >+{ >+ return bus_space_read_4(sc->nambart, sc->nambarh, regno); >+} >+ >+#define ich_rd(sc, regno, size) ich_rd_ ## size (sc, regno) >+ > static void >-ich_wr(struct sc_info *sc, int regno, u_int32_t data, int size) >+ich_wr_1(struct sc_info *sc, int regno, u_int32_t data) > { >- switch (size) { >- case 1: >- bus_space_write_1(sc->nambart, sc->nambarh, regno, data); >- break; >- case 2: >- bus_space_write_2(sc->nambart, sc->nambarh, regno, data); >- break; >- case 4: >- bus_space_write_4(sc->nambart, sc->nambarh, regno, data); >- break; >- } >+ bus_space_write_1(sc->nambart, sc->nambarh, regno, data); > } > >+static void >+ich_wr_2(struct sc_info *sc, int regno, u_int32_t data) >+{ >+ bus_space_write_2(sc->nambart, sc->nambarh, regno, data); >+} >+ >+static void >+ich_wr_4(struct sc_info *sc, int regno, u_int32_t data) >+{ >+ bus_space_write_4(sc->nambart, sc->nambarh, regno, data); >+} >+ >+#define ich_wr(sc,regno,data,size) ich_wr_ ## size (sc,regno, data) >+ > /* ac97 codec */ > static int > ich_waitcd(void *devinfo) >@@ -423,6 +434,7 @@ > ch->parent = sc; > ch->dir = PCMDIR_PLAY; > ch->run = 0; >+ ch->run_save = 0; > ch->lvi = 0; > if (ichchan_initbuf(ch)) { > device_printf(sc->dev, "cannot allocate channel buffer\n"); >@@ -555,6 +567,9 @@ > #if(0) > device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_START\n"); > #endif >+ if (ch->run > 0) { >+ return 0; >+ } > ch->run = 1; > ichpchan_power(obj, sc, 1); > bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_BDBAR, >@@ -569,6 +584,9 @@ > #if(0) > device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_STOP\n"); > #endif >+ if (ch->run <= 0) { >+ return 0; >+ } > cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, > ICH_REG_PO_CR); > bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, >@@ -580,6 +598,9 @@ > #if(0) > device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_ABORT\n"); > #endif >+ if (ch->run < 0) { >+ return 0; >+ } > bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, > 0); > bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, >@@ -591,7 +612,7 @@ > break; > } > ichpchan_power(obj, sc, 0); >- ch->run = 0; >+ ch->run = -1; > ch->lvi = 0; > break; > default: >@@ -722,6 +743,7 @@ > ch->parent = sc; > ch->dir = PCMDIR_REC; > ch->run = 0; >+ ch->run_save = 0; > ch->lvi = 0; > if (ichchan_initbuf(ch)) { > device_printf(sc->dev, "cannot allocate channel buffer\n"); >@@ -796,6 +818,9 @@ > > switch (go) { > case PCMTRIG_START: >+ if (ch->run > 0) { >+ return 0; >+ } > ch->run = 1; > ichrchan_power(obj, sc, 1); > bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_BDBAR, >@@ -808,6 +833,9 @@ > ICH_X_CR_FEIE); > break; > case PCMTRIG_STOP: >+ if (ch->run <= 0) { >+ return 0; >+ } > cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, > ICH_REG_PI_CR); > bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, >@@ -816,6 +844,9 @@ > ch->run = 0; > break; > case PCMTRIG_ABORT: >+ if (ch->run < 0) { >+ return 0; >+ } > bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, > 0); > bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, >@@ -827,7 +858,7 @@ > break; > } > ichrchan_power(obj, sc, 0); >- ch->run = 0; >+ ch->run = -1; > ch->lvi = 0; > break; > default: >@@ -984,6 +1015,8 @@ > u_int32_t stat; > u_int32_t save; > >+ bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_GLOB_CNT, 0); >+ DELAY(10); > bus_space_write_4(sc->nabmbart, sc->nabmbarh, > ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD); > DELAY(600000); >@@ -1164,6 +1197,33 @@ > } > > static int >+ich_pci_suspend(device_t dev) >+{ >+ struct sc_info *sc; >+ u_int32_t cr; >+ >+ sc = pcm_getdevinfo(dev); >+ >+ sc->po->run_save = sc->po->run; >+ sc->pi->run_save = sc->pi->run; >+ if (sc->po->run > 0) { >+ ichpchan_trigger(NULL,sc->po, PCMTRIG_STOP); >+ } >+ if (sc->pi->run > 0) { >+ ichrchan_trigger(NULL, sc->pi, PCMTRIG_STOP); >+ } >+ >+ /* CODEC power off */ >+ cr = ich_rdcd(NULL, sc, AC97_REG_POWER); >+ cr |= AC97_POWER_D3; >+ ich_wrcd(NULL, sc, AC97_REG_POWER, cr); >+ /* ACLINK shut off */ >+ ich_wr(sc,ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_SHUT, 4); >+ >+ return 0; >+} >+ >+static int > ich_pci_resume(device_t dev) > { > struct sc_info *sc; >@@ -1180,6 +1240,14 @@ > device_printf(dev, "unable to reinitialize the mixer\n"); > return ENXIO; > } >+ >+ if (sc->po->run_save > 0) { >+ ichpchan_trigger(NULL, sc->po, PCMTRIG_START); >+ } >+ if (sc->pi->run_save > 0) { >+ ichrchan_trigger(NULL, sc->pi, PCMTRIG_START); >+ } >+ > return 0; > } > >@@ -1188,6 +1256,7 @@ > DEVMETHOD(device_probe, ich_pci_probe), > DEVMETHOD(device_attach, ich_pci_attach), > DEVMETHOD(device_detach, ich_pci_detach), >+ DEVMETHOD(device_suspend, ich_pci_suspend), > DEVMETHOD(device_resume, ich_pci_resume), > { 0, 0 } > };
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 28692
: 15482