Index: head/sys/conf/files.i386 =================================================================== --- head/sys/conf/files.i386 (revision 48522) +++ head/sys/conf/files.i386 (revision 48523) @@ -1,386 +1,386 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.250 1999/06/29 21:53:59 peter Exp $ +# $Id: files.i386,v 1.251 1999/07/03 18:26:22 peter Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # linux_genassym optional compat_linux \ dependency "$S/i386/linux/linux_genassym.c $S/i386/linux/linux.h" \ compile-with "${CC} ${CFLAGS} ${PARAM} -UKERNEL -o $@ $<" \ no-obj no-implicit-rule \ clean "linux_genassym" # linux_assym.h optional compat_linux \ dependency "linux_genassym" \ compile-with "./linux_genassym > $@" \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # font.h optional sc_dflt_font \ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "atkbdmap.h" # ukbdmap.h optional ukbd_dflt_keymap \ compile-with "kbdcontrol -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" # contrib/dev/oltr/if_oltr.c optional oltr device-driver trlld.o optional oltr device-driver \ dependency "$S/contrib/dev/oltr/i386-${KERNFORMAT}.trlld.o.uu" \ compile-with "uudecode < $S/contrib/dev/oltr/i386-${KERNFORMAT}.trlld.o.uu" \ no-implicit-rule contrib/dev/oltr/trlldbm.c optional oltr device-driver contrib/dev/oltr/trlldhm.c optional oltr device-driver contrib/dev/oltr/trlldmac.c optional oltr device-driver dev/ata/ata-all.c optional ata device-driver dev/ata/ata-disk.c optional atadisk device-driver dev/ata/ata-dma.c optional ata device-driver dev/ata/atapi-all.c optional ata device-driver dev/ata/atapi-cd.c optional atapicd device-driver dev/ata/atapi-fd.c optional atapifd device-driver dev/ata/atapi-tape.c optional atapist device-driver dev/fb/fb.c optional fb device-driver dev/fb/fb.c optional vga device-driver dev/fb/splash.c optional splash dev/fb/vga.c optional vga device-driver dev/kbd/atkbd.c optional atkbd device-driver dev/kbd/atkbdc.c optional atkbdc device-driver dev/kbd/kbd.c optional atkbd device-driver dev/kbd/kbd.c optional kbd device-driver dev/kbd/kbd.c optional ukbd device-driver dev/pccard/if_xe.c optional xe device-driver dev/syscons/schistory.c optional sc device-driver dev/syscons/scmouse.c optional sc device-driver dev/syscons/scvesactl.c optional sc device-driver dev/syscons/scvgarndr.c optional sc device-driver dev/syscons/scvidctl.c optional sc device-driver dev/syscons/scvtb.c optional sc device-driver dev/syscons/syscons.c optional sc device-driver gnu/i386/fpemul/div_small.s optional gpl_math_emulate gnu/i386/fpemul/errors.c optional gpl_math_emulate gnu/i386/fpemul/fpu_arith.c optional gpl_math_emulate gnu/i386/fpemul/fpu_aux.c optional gpl_math_emulate gnu/i386/fpemul/fpu_entry.c optional gpl_math_emulate gnu/i386/fpemul/fpu_etc.c optional gpl_math_emulate gnu/i386/fpemul/fpu_trig.c optional gpl_math_emulate gnu/i386/fpemul/get_address.c optional gpl_math_emulate gnu/i386/fpemul/load_store.c optional gpl_math_emulate gnu/i386/fpemul/poly_2xm1.c optional gpl_math_emulate gnu/i386/fpemul/poly_atan.c optional gpl_math_emulate gnu/i386/fpemul/poly_div.s optional gpl_math_emulate gnu/i386/fpemul/poly_l2.c optional gpl_math_emulate gnu/i386/fpemul/poly_mul64.s optional gpl_math_emulate gnu/i386/fpemul/poly_sin.c optional gpl_math_emulate gnu/i386/fpemul/poly_tan.c optional gpl_math_emulate gnu/i386/fpemul/polynomial.s optional gpl_math_emulate gnu/i386/fpemul/reg_add_sub.c optional gpl_math_emulate gnu/i386/fpemul/reg_compare.c optional gpl_math_emulate gnu/i386/fpemul/reg_constant.c optional gpl_math_emulate gnu/i386/fpemul/reg_div.s optional gpl_math_emulate gnu/i386/fpemul/reg_ld_str.c optional gpl_math_emulate gnu/i386/fpemul/reg_mul.c optional gpl_math_emulate gnu/i386/fpemul/reg_norm.s optional gpl_math_emulate gnu/i386/fpemul/reg_round.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_add.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_div.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_mul.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate gnu/i386/isa/dgb.c optional dgb device-driver gnu/i386/isa/dgm.c optional dgm device-driver gnu/i386/isa/sound/awe_wave.c optional awe device-driver i386/apm/apm.c optional apm device-driver i386/apm/apm_setup.s optional apm i386/eisa/3c5x9.c optional ep device-driver i386/eisa/adv_eisa.c optional adv device-driver i386/eisa/ahb.c optional ahb device-driver i386/eisa/ahc_eisa.c optional eisa ahc device-driver \ dependency "aic7xxx_reg.h $S/i386/eisa/ahc_eisa.c" i386/eisa/bt_eisa.c optional bt device-driver i386/eisa/dpt_eisa.c optional eisa dpt device-driver i386/eisa/eisaconf.c optional eisa i386/eisa/if_fea.c optional fea device-driver i386/eisa/if_vx_eisa.c optional vx device-driver i386/i386/autoconf.c standard device-driver i386/i386/bios.c standard i386/i386/bioscall.s standard i386/i386/busdma_machdep.c standard i386/i386/cons.c standard i386/i386/db_disasm.c optional ddb i386/i386/db_interface.c optional ddb i386/i386/db_trace.c optional ddb i386/i386/elf_machdep.c standard i386/i386/exception.s standard i386/i386/globals.s standard i386/i386/i386-gdbstub.c optional ddb i386/i386/i686_mem.c standard i386/i386/identcpu.c standard i386/i386/in_cksum.c optional inet i386/i386/initcpu.c standard i386/i386/k6_mem.c standard # locore.s needs to be handled in Makefile to put it first. Otherwise it's # now normal. # i386/i386/locore.s standard i386/i386/machdep.c standard i386/i386/math_emulate.c optional math_emulate i386/i386/mem.c standard i386/i386/mp_machdep.c optional smp i386/i386/mpapic.c optional smp i386/i386/mpboot.s optional smp i386/i386/mplock.s optional smp i386/i386/nexus.c standard i386/i386/perfmon.c optional perfmon i386/i386/perfmon.c optional perfmon profiling-routine i386/i386/pmap.c standard i386/i386/procfs_machdep.c standard i386/i386/simplelock.s optional smp i386/i386/support.s standard i386/i386/swtch.s standard i386/i386/sys_machdep.c standard i386/i386/trap.c standard i386/i386/userconfig.c optional userconfig i386/i386/vm86.c standard i386/i386/vm_machdep.c standard i386/ibcs2/ibcs2_errno.c optional ibcs2 i386/ibcs2/ibcs2_fcntl.c optional ibcs2 i386/ibcs2/ibcs2_ioctl.c optional ibcs2 i386/ibcs2/ibcs2_ipc.c optional ibcs2 i386/ibcs2/ibcs2_isc.c optional ibcs2 i386/ibcs2/ibcs2_isc_sysent.c optional ibcs2 i386/ibcs2/ibcs2_misc.c optional ibcs2 i386/ibcs2/ibcs2_msg.c optional ibcs2 i386/ibcs2/ibcs2_other.c optional ibcs2 i386/ibcs2/ibcs2_signal.c optional ibcs2 i386/ibcs2/ibcs2_socksys.c optional ibcs2 i386/ibcs2/ibcs2_stat.c optional ibcs2 i386/ibcs2/ibcs2_sysent.c optional ibcs2 i386/ibcs2/ibcs2_sysi86.c optional ibcs2 i386/ibcs2/ibcs2_sysvec.c optional ibcs2 i386/ibcs2/ibcs2_util.c optional ibcs2 i386/ibcs2/ibcs2_xenix.c optional ibcs2 i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2 i386/ibcs2/imgact_coff.c optional ibcs2 i386/isa/adv_isa.c optional adv device-driver i386/isa/aha_isa.c optional aha device-driver i386/isa/asc.c optional asc device-driver i386/isa/atapi-cd.c optional wcd device-driver i386/isa/atapi.c optional wdc device-driver i386/isa/clock.c standard i386/isa/cronyx.c optional cx device-driver i386/isa/ctx.c optional ctx device-driver i386/isa/cx.c optional cx device-driver i386/isa/cy.c optional cy device-driver i386/isa/diskslice_machdep.c standard i386/isa/elink.c optional ep device-driver i386/isa/elink.c optional ie device-driver isa/fd.c optional fd device-driver i386/isa/fla.c optional fla device-driver i386/isa/gpib.c optional gp device-driver i386/isa/gsc.c optional gsc device-driver i386/isa/if_ar.c optional ar device-driver i386/isa/if_cs.c optional cs device-driver i386/isa/if_cx.c optional cx device-driver i386/isa/if_ed.c optional ed device-driver i386/isa/if_el.c optional el device-driver i386/isa/if_ep.c optional ep device-driver i386/isa/if_ex.c optional ex device-driver i386/isa/if_fe.c optional fe device-driver i386/isa/if_ie.c optional ie device-driver i386/isa/if_le.c optional le device-driver i386/isa/if_lnc.c optional lnc device-driver i386/isa/if_rdp.c optional rdp device-driver i386/isa/if_sr.c optional sr device-driver i386/isa/if_wi.c optional wi device-driver i386/isa/if_wl.c optional wl device-driver i386/isa/if_ze.c optional ze device-driver i386/isa/if_zp.c optional zp device-driver i386/isa/intr_machdep.c standard i386/isa/ipl_funcs.c standard \ compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} $<" i386/isa/isa.c optional isa device-driver i386/isa/isa_compat.c optional isa device-driver i386/isa/isa_dma.c optional isa device-driver i386/isa/istallion.c optional stli device-driver i386/isa/joy.c optional joy device-driver i386/isa/labpc.c optional labpc device-driver i386/isa/loran.c optional loran device-driver i386/isa/matcd/matcd.c optional matcd device-driver i386/isa/mcd.c optional mcd device-driver i386/isa/mse.c optional mse device-driver i386/isa/npx.c mandatory npx device-driver i386/isa/pcaudio.c optional pca device-driver i386/isa/pcf.c optional pcf device-driver i386/isa/pcibus.c optional pci device-driver i386/isa/pcicx.c optional ze device-driver i386/isa/pcicx.c optional zp device-driver i386/isa/pcvt/pcvt_drv.c optional vt device-driver i386/isa/pcvt/pcvt_ext.c optional vt device-driver i386/isa/pcvt/pcvt_kbd.c optional vt device-driver i386/isa/pcvt/pcvt_out.c optional vt device-driver i386/isa/pcvt/pcvt_sup.c optional vt device-driver i386/isa/pcvt/pcvt_vtf.c optional vt device-driver i386/isa/pnp.c optional pnp device-driver i386/isa/ppc.c optional ppc device-driver i386/isa/prof_machdep.c optional profiling-routine i386/isa/random_machdep.c standard i386/isa/rc.c optional rc device-driver i386/isa/rp.c optional rp device-driver i386/isa/scd.c optional scd device-driver i386/isa/si.c optional si device-driver i386/isa/si2_z280.c optional si device-driver i386/isa/si3_t225.c optional si device-driver i386/isa/snd/ad1848.c optional pcm device-driver i386/isa/snd/clones.c optional pcm device-driver i386/isa/snd/dmabuf.c optional pcm device-driver i386/isa/snd/sb_dsp.c optional pcm device-driver i386/isa/snd/sound.c optional pcm device-driver i386/isa/sound/ad1848.c optional css device-driver i386/isa/sound/ad1848.c optional gus device-driver i386/isa/sound/ad1848.c optional gusxvi device-driver i386/isa/sound/ad1848.c optional mss device-driver i386/isa/sound/ad1848.c optional sscape device-driver i386/isa/sound/ad1848.c optional trix device-driver i386/isa/sound/ad1848.c optional sscape_mss device-driver i386/isa/sound/adlib_card.c optional opl device-driver i386/isa/sound/adlib_card.c optional trix device-driver i386/isa/sound/audio.c optional snd device-driver i386/isa/sound/cs4232.c optional css device-driver i386/isa/sound/dev_table.c optional snd device-driver i386/isa/sound/dmabuf.c optional snd device-driver i386/isa/sound/gus_card.c optional gus device-driver i386/isa/sound/gus_midi.c optional gus device-driver i386/isa/sound/gus_vol.c optional gus device-driver i386/isa/sound/gus_wave.c optional gus device-driver i386/isa/sound/ics2101.c optional gus device-driver i386/isa/sound/midi_synth.c optional css device-driver i386/isa/sound/midi_synth.c optional gus device-driver i386/isa/sound/midi_synth.c optional mpu device-driver i386/isa/sound/midi_synth.c optional mss device-driver i386/isa/sound/midi_synth.c optional pas device-driver i386/isa/sound/midi_synth.c optional sb device-driver i386/isa/sound/midi_synth.c optional sscape device-driver i386/isa/sound/midi_synth.c optional uart device-driver i386/isa/sound/midibuf.c optional css device-driver i386/isa/sound/midibuf.c optional gus device-driver i386/isa/sound/midibuf.c optional mpu device-driver i386/isa/sound/midibuf.c optional mss device-driver i386/isa/sound/midibuf.c optional pas device-driver i386/isa/sound/midibuf.c optional sb device-driver i386/isa/sound/midibuf.c optional sscape device-driver i386/isa/sound/midibuf.c optional uart device-driver i386/isa/sound/mpu401.c optional mpu device-driver i386/isa/sound/mpu401.c optional sscape device-driver i386/isa/sound/opl3.c optional opl device-driver i386/isa/sound/opl3.c optional trix device-driver i386/isa/sound/pas2_card.c optional pas device-driver i386/isa/sound/pas2_midi.c optional pas device-driver i386/isa/sound/pas2_mixer.c optional pas device-driver i386/isa/sound/pas2_pcm.c optional pas device-driver i386/isa/sound/patmgr.c optional snd device-driver i386/isa/sound/sb16_dsp.c optional sbxvi device-driver i386/isa/sound/sb16_midi.c optional sbmidi device-driver i386/isa/sound/sb_card.c optional sb device-driver i386/isa/sound/sb_dsp.c optional sb device-driver i386/isa/sound/sb_midi.c optional sb device-driver i386/isa/sound/sb_mixer.c optional sb device-driver i386/isa/sound/sequencer.c optional snd device-driver i386/isa/sound/sound_switch.c optional snd device-driver i386/isa/sound/sound_timer.c optional css device-driver i386/isa/sound/sound_timer.c optional gus device-driver i386/isa/sound/sound_timer.c optional mss device-driver i386/isa/sound/sound_timer.c optional mss device-driver i386/isa/sound/sound_timer.c optional sscape device-driver i386/isa/sound/sound_timer.c optional trix device-driver i386/isa/sound/soundcard.c optional snd device-driver i386/isa/sound/sscape.c optional sscape device-driver i386/isa/sound/sys_timer.c optional snd device-driver i386/isa/sound/trix.c optional trix device-driver i386/isa/sound/uart6850.c optional uart device-driver i386/isa/spigot.c optional spigot device-driver i386/isa/spkr.c optional speaker device-driver i386/isa/stallion.c optional stl device-driver i386/isa/tw.c optional tw device-driver i386/isa/vesa.c optional vga device-driver i386/isa/wd.c optional wd device-driver i386/isa/wd.c optional wdc device-driver i386/isa/wfd.c optional wfd device-driver i386/isa/wst.c optional wst device-driver i386/isa/wt.c optional wt device-driver i386/linux/imgact_linux.c optional compat_linux i386/linux/linux_dummy.c optional compat_linux i386/linux/linux_file.c optional compat_linux i386/linux/linux_ioctl.c optional compat_linux i386/linux/linux_ipc.c optional compat_linux i386/linux/linux_locore.s optional compat_linux \ dependency "linux_assym.h" i386/linux/linux_misc.c optional compat_linux i386/linux/linux_signal.c optional compat_linux i386/linux/linux_socket.c optional compat_linux i386/linux/linux_stats.c optional compat_linux i386/linux/linux_sysent.c optional compat_linux i386/linux/linux_sysvec.c optional compat_linux i386/linux/linux_util.c optional compat_linux i4b/layer1/i4b_avm_a1.c optional isic device-driver i4b/layer1/i4b_avm_fritz_pci.c optional isic device-driver i4b/layer1/i4b_avm_fritz_pcmcia.c optional isic device-driver i4b/layer1/i4b_bchan.c optional isic device-driver i4b/layer1/i4b_ctx_s0P.c optional isic device-driver i4b/layer1/i4b_drn_ngo.c optional isic device-driver i4b/layer1/i4b_dynalink.c optional isic device-driver i4b/layer1/i4b_elsa_qs1i.c optional isic device-driver i4b/layer1/i4b_elsa_qs1p.c optional isic device-driver i4b/layer1/i4b_hscx.c optional isic device-driver i4b/layer1/i4b_isac.c optional isic device-driver i4b/layer1/i4b_isic.c optional isic device-driver i4b/layer1/i4b_isic_isa.c optional isic device-driver i4b/layer1/i4b_isic_pci.c optional isic device-driver i4b/layer1/i4b_isic_pcmcia.c optional isic device-driver i4b/layer1/i4b_isic_pnp.c optional isic device-driver i4b/layer1/i4b_itk_ix1.c optional isic device-driver i4b/layer1/i4b_l1.c optional isic device-driver i4b/layer1/i4b_l1fsm.c optional isic device-driver i4b/layer1/i4b_sws.c optional isic device-driver i4b/layer1/i4b_tel_s016.c optional isic device-driver i4b/layer1/i4b_tel_s0163.c optional isic device-driver i4b/layer1/i4b_tel_s08.c optional isic device-driver i4b/layer1/i4b_tel_s0P.c optional isic device-driver i4b/layer1/i4b_usr_sti.c optional isic device-driver isa/atkbd_isa.c optional atkbd device-driver isa/atkbdc_isa.c optional atkbdc device-driver isa/psm.c optional psm device-driver isa/sio.c optional sio device-driver isa/syscons_isa.c optional sc device-driver isa/vga_isa.c optional vga device-driver libkern/bcd.c standard libkern/divdi3.c standard libkern/index.c standard libkern/inet_ntoa.c standard libkern/mcount.c optional profiling-routine libkern/moddi3.c standard libkern/qdivrem.c standard libkern/qsort.c standard libkern/random.c standard libkern/rindex.c standard libkern/scanc.c standard libkern/skpc.c standard libkern/strcat.c standard libkern/strcmp.c standard libkern/strcpy.c standard libkern/strlen.c standard libkern/strncmp.c standard libkern/strncpy.c standard libkern/udivdi3.c standard libkern/umoddi3.c standard -pci/es1370.c optional pcm device-driver -pci/ide_pci.c optional wd device-driver +pci/es1370.c optional pcm pci device-driver +pci/ide_pci.c optional wd pci device-driver Index: head/sys/i386/conf/files.i386 =================================================================== --- head/sys/i386/conf/files.i386 (revision 48522) +++ head/sys/i386/conf/files.i386 (revision 48523) @@ -1,386 +1,386 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.250 1999/06/29 21:53:59 peter Exp $ +# $Id: files.i386,v 1.251 1999/07/03 18:26:22 peter Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # linux_genassym optional compat_linux \ dependency "$S/i386/linux/linux_genassym.c $S/i386/linux/linux.h" \ compile-with "${CC} ${CFLAGS} ${PARAM} -UKERNEL -o $@ $<" \ no-obj no-implicit-rule \ clean "linux_genassym" # linux_assym.h optional compat_linux \ dependency "linux_genassym" \ compile-with "./linux_genassym > $@" \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # font.h optional sc_dflt_font \ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "atkbdmap.h" # ukbdmap.h optional ukbd_dflt_keymap \ compile-with "kbdcontrol -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" # contrib/dev/oltr/if_oltr.c optional oltr device-driver trlld.o optional oltr device-driver \ dependency "$S/contrib/dev/oltr/i386-${KERNFORMAT}.trlld.o.uu" \ compile-with "uudecode < $S/contrib/dev/oltr/i386-${KERNFORMAT}.trlld.o.uu" \ no-implicit-rule contrib/dev/oltr/trlldbm.c optional oltr device-driver contrib/dev/oltr/trlldhm.c optional oltr device-driver contrib/dev/oltr/trlldmac.c optional oltr device-driver dev/ata/ata-all.c optional ata device-driver dev/ata/ata-disk.c optional atadisk device-driver dev/ata/ata-dma.c optional ata device-driver dev/ata/atapi-all.c optional ata device-driver dev/ata/atapi-cd.c optional atapicd device-driver dev/ata/atapi-fd.c optional atapifd device-driver dev/ata/atapi-tape.c optional atapist device-driver dev/fb/fb.c optional fb device-driver dev/fb/fb.c optional vga device-driver dev/fb/splash.c optional splash dev/fb/vga.c optional vga device-driver dev/kbd/atkbd.c optional atkbd device-driver dev/kbd/atkbdc.c optional atkbdc device-driver dev/kbd/kbd.c optional atkbd device-driver dev/kbd/kbd.c optional kbd device-driver dev/kbd/kbd.c optional ukbd device-driver dev/pccard/if_xe.c optional xe device-driver dev/syscons/schistory.c optional sc device-driver dev/syscons/scmouse.c optional sc device-driver dev/syscons/scvesactl.c optional sc device-driver dev/syscons/scvgarndr.c optional sc device-driver dev/syscons/scvidctl.c optional sc device-driver dev/syscons/scvtb.c optional sc device-driver dev/syscons/syscons.c optional sc device-driver gnu/i386/fpemul/div_small.s optional gpl_math_emulate gnu/i386/fpemul/errors.c optional gpl_math_emulate gnu/i386/fpemul/fpu_arith.c optional gpl_math_emulate gnu/i386/fpemul/fpu_aux.c optional gpl_math_emulate gnu/i386/fpemul/fpu_entry.c optional gpl_math_emulate gnu/i386/fpemul/fpu_etc.c optional gpl_math_emulate gnu/i386/fpemul/fpu_trig.c optional gpl_math_emulate gnu/i386/fpemul/get_address.c optional gpl_math_emulate gnu/i386/fpemul/load_store.c optional gpl_math_emulate gnu/i386/fpemul/poly_2xm1.c optional gpl_math_emulate gnu/i386/fpemul/poly_atan.c optional gpl_math_emulate gnu/i386/fpemul/poly_div.s optional gpl_math_emulate gnu/i386/fpemul/poly_l2.c optional gpl_math_emulate gnu/i386/fpemul/poly_mul64.s optional gpl_math_emulate gnu/i386/fpemul/poly_sin.c optional gpl_math_emulate gnu/i386/fpemul/poly_tan.c optional gpl_math_emulate gnu/i386/fpemul/polynomial.s optional gpl_math_emulate gnu/i386/fpemul/reg_add_sub.c optional gpl_math_emulate gnu/i386/fpemul/reg_compare.c optional gpl_math_emulate gnu/i386/fpemul/reg_constant.c optional gpl_math_emulate gnu/i386/fpemul/reg_div.s optional gpl_math_emulate gnu/i386/fpemul/reg_ld_str.c optional gpl_math_emulate gnu/i386/fpemul/reg_mul.c optional gpl_math_emulate gnu/i386/fpemul/reg_norm.s optional gpl_math_emulate gnu/i386/fpemul/reg_round.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_add.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_div.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_mul.s optional gpl_math_emulate gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate gnu/i386/isa/dgb.c optional dgb device-driver gnu/i386/isa/dgm.c optional dgm device-driver gnu/i386/isa/sound/awe_wave.c optional awe device-driver i386/apm/apm.c optional apm device-driver i386/apm/apm_setup.s optional apm i386/eisa/3c5x9.c optional ep device-driver i386/eisa/adv_eisa.c optional adv device-driver i386/eisa/ahb.c optional ahb device-driver i386/eisa/ahc_eisa.c optional eisa ahc device-driver \ dependency "aic7xxx_reg.h $S/i386/eisa/ahc_eisa.c" i386/eisa/bt_eisa.c optional bt device-driver i386/eisa/dpt_eisa.c optional eisa dpt device-driver i386/eisa/eisaconf.c optional eisa i386/eisa/if_fea.c optional fea device-driver i386/eisa/if_vx_eisa.c optional vx device-driver i386/i386/autoconf.c standard device-driver i386/i386/bios.c standard i386/i386/bioscall.s standard i386/i386/busdma_machdep.c standard i386/i386/cons.c standard i386/i386/db_disasm.c optional ddb i386/i386/db_interface.c optional ddb i386/i386/db_trace.c optional ddb i386/i386/elf_machdep.c standard i386/i386/exception.s standard i386/i386/globals.s standard i386/i386/i386-gdbstub.c optional ddb i386/i386/i686_mem.c standard i386/i386/identcpu.c standard i386/i386/in_cksum.c optional inet i386/i386/initcpu.c standard i386/i386/k6_mem.c standard # locore.s needs to be handled in Makefile to put it first. Otherwise it's # now normal. # i386/i386/locore.s standard i386/i386/machdep.c standard i386/i386/math_emulate.c optional math_emulate i386/i386/mem.c standard i386/i386/mp_machdep.c optional smp i386/i386/mpapic.c optional smp i386/i386/mpboot.s optional smp i386/i386/mplock.s optional smp i386/i386/nexus.c standard i386/i386/perfmon.c optional perfmon i386/i386/perfmon.c optional perfmon profiling-routine i386/i386/pmap.c standard i386/i386/procfs_machdep.c standard i386/i386/simplelock.s optional smp i386/i386/support.s standard i386/i386/swtch.s standard i386/i386/sys_machdep.c standard i386/i386/trap.c standard i386/i386/userconfig.c optional userconfig i386/i386/vm86.c standard i386/i386/vm_machdep.c standard i386/ibcs2/ibcs2_errno.c optional ibcs2 i386/ibcs2/ibcs2_fcntl.c optional ibcs2 i386/ibcs2/ibcs2_ioctl.c optional ibcs2 i386/ibcs2/ibcs2_ipc.c optional ibcs2 i386/ibcs2/ibcs2_isc.c optional ibcs2 i386/ibcs2/ibcs2_isc_sysent.c optional ibcs2 i386/ibcs2/ibcs2_misc.c optional ibcs2 i386/ibcs2/ibcs2_msg.c optional ibcs2 i386/ibcs2/ibcs2_other.c optional ibcs2 i386/ibcs2/ibcs2_signal.c optional ibcs2 i386/ibcs2/ibcs2_socksys.c optional ibcs2 i386/ibcs2/ibcs2_stat.c optional ibcs2 i386/ibcs2/ibcs2_sysent.c optional ibcs2 i386/ibcs2/ibcs2_sysi86.c optional ibcs2 i386/ibcs2/ibcs2_sysvec.c optional ibcs2 i386/ibcs2/ibcs2_util.c optional ibcs2 i386/ibcs2/ibcs2_xenix.c optional ibcs2 i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2 i386/ibcs2/imgact_coff.c optional ibcs2 i386/isa/adv_isa.c optional adv device-driver i386/isa/aha_isa.c optional aha device-driver i386/isa/asc.c optional asc device-driver i386/isa/atapi-cd.c optional wcd device-driver i386/isa/atapi.c optional wdc device-driver i386/isa/clock.c standard i386/isa/cronyx.c optional cx device-driver i386/isa/ctx.c optional ctx device-driver i386/isa/cx.c optional cx device-driver i386/isa/cy.c optional cy device-driver i386/isa/diskslice_machdep.c standard i386/isa/elink.c optional ep device-driver i386/isa/elink.c optional ie device-driver isa/fd.c optional fd device-driver i386/isa/fla.c optional fla device-driver i386/isa/gpib.c optional gp device-driver i386/isa/gsc.c optional gsc device-driver i386/isa/if_ar.c optional ar device-driver i386/isa/if_cs.c optional cs device-driver i386/isa/if_cx.c optional cx device-driver i386/isa/if_ed.c optional ed device-driver i386/isa/if_el.c optional el device-driver i386/isa/if_ep.c optional ep device-driver i386/isa/if_ex.c optional ex device-driver i386/isa/if_fe.c optional fe device-driver i386/isa/if_ie.c optional ie device-driver i386/isa/if_le.c optional le device-driver i386/isa/if_lnc.c optional lnc device-driver i386/isa/if_rdp.c optional rdp device-driver i386/isa/if_sr.c optional sr device-driver i386/isa/if_wi.c optional wi device-driver i386/isa/if_wl.c optional wl device-driver i386/isa/if_ze.c optional ze device-driver i386/isa/if_zp.c optional zp device-driver i386/isa/intr_machdep.c standard i386/isa/ipl_funcs.c standard \ compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} $<" i386/isa/isa.c optional isa device-driver i386/isa/isa_compat.c optional isa device-driver i386/isa/isa_dma.c optional isa device-driver i386/isa/istallion.c optional stli device-driver i386/isa/joy.c optional joy device-driver i386/isa/labpc.c optional labpc device-driver i386/isa/loran.c optional loran device-driver i386/isa/matcd/matcd.c optional matcd device-driver i386/isa/mcd.c optional mcd device-driver i386/isa/mse.c optional mse device-driver i386/isa/npx.c mandatory npx device-driver i386/isa/pcaudio.c optional pca device-driver i386/isa/pcf.c optional pcf device-driver i386/isa/pcibus.c optional pci device-driver i386/isa/pcicx.c optional ze device-driver i386/isa/pcicx.c optional zp device-driver i386/isa/pcvt/pcvt_drv.c optional vt device-driver i386/isa/pcvt/pcvt_ext.c optional vt device-driver i386/isa/pcvt/pcvt_kbd.c optional vt device-driver i386/isa/pcvt/pcvt_out.c optional vt device-driver i386/isa/pcvt/pcvt_sup.c optional vt device-driver i386/isa/pcvt/pcvt_vtf.c optional vt device-driver i386/isa/pnp.c optional pnp device-driver i386/isa/ppc.c optional ppc device-driver i386/isa/prof_machdep.c optional profiling-routine i386/isa/random_machdep.c standard i386/isa/rc.c optional rc device-driver i386/isa/rp.c optional rp device-driver i386/isa/scd.c optional scd device-driver i386/isa/si.c optional si device-driver i386/isa/si2_z280.c optional si device-driver i386/isa/si3_t225.c optional si device-driver i386/isa/snd/ad1848.c optional pcm device-driver i386/isa/snd/clones.c optional pcm device-driver i386/isa/snd/dmabuf.c optional pcm device-driver i386/isa/snd/sb_dsp.c optional pcm device-driver i386/isa/snd/sound.c optional pcm device-driver i386/isa/sound/ad1848.c optional css device-driver i386/isa/sound/ad1848.c optional gus device-driver i386/isa/sound/ad1848.c optional gusxvi device-driver i386/isa/sound/ad1848.c optional mss device-driver i386/isa/sound/ad1848.c optional sscape device-driver i386/isa/sound/ad1848.c optional trix device-driver i386/isa/sound/ad1848.c optional sscape_mss device-driver i386/isa/sound/adlib_card.c optional opl device-driver i386/isa/sound/adlib_card.c optional trix device-driver i386/isa/sound/audio.c optional snd device-driver i386/isa/sound/cs4232.c optional css device-driver i386/isa/sound/dev_table.c optional snd device-driver i386/isa/sound/dmabuf.c optional snd device-driver i386/isa/sound/gus_card.c optional gus device-driver i386/isa/sound/gus_midi.c optional gus device-driver i386/isa/sound/gus_vol.c optional gus device-driver i386/isa/sound/gus_wave.c optional gus device-driver i386/isa/sound/ics2101.c optional gus device-driver i386/isa/sound/midi_synth.c optional css device-driver i386/isa/sound/midi_synth.c optional gus device-driver i386/isa/sound/midi_synth.c optional mpu device-driver i386/isa/sound/midi_synth.c optional mss device-driver i386/isa/sound/midi_synth.c optional pas device-driver i386/isa/sound/midi_synth.c optional sb device-driver i386/isa/sound/midi_synth.c optional sscape device-driver i386/isa/sound/midi_synth.c optional uart device-driver i386/isa/sound/midibuf.c optional css device-driver i386/isa/sound/midibuf.c optional gus device-driver i386/isa/sound/midibuf.c optional mpu device-driver i386/isa/sound/midibuf.c optional mss device-driver i386/isa/sound/midibuf.c optional pas device-driver i386/isa/sound/midibuf.c optional sb device-driver i386/isa/sound/midibuf.c optional sscape device-driver i386/isa/sound/midibuf.c optional uart device-driver i386/isa/sound/mpu401.c optional mpu device-driver i386/isa/sound/mpu401.c optional sscape device-driver i386/isa/sound/opl3.c optional opl device-driver i386/isa/sound/opl3.c optional trix device-driver i386/isa/sound/pas2_card.c optional pas device-driver i386/isa/sound/pas2_midi.c optional pas device-driver i386/isa/sound/pas2_mixer.c optional pas device-driver i386/isa/sound/pas2_pcm.c optional pas device-driver i386/isa/sound/patmgr.c optional snd device-driver i386/isa/sound/sb16_dsp.c optional sbxvi device-driver i386/isa/sound/sb16_midi.c optional sbmidi device-driver i386/isa/sound/sb_card.c optional sb device-driver i386/isa/sound/sb_dsp.c optional sb device-driver i386/isa/sound/sb_midi.c optional sb device-driver i386/isa/sound/sb_mixer.c optional sb device-driver i386/isa/sound/sequencer.c optional snd device-driver i386/isa/sound/sound_switch.c optional snd device-driver i386/isa/sound/sound_timer.c optional css device-driver i386/isa/sound/sound_timer.c optional gus device-driver i386/isa/sound/sound_timer.c optional mss device-driver i386/isa/sound/sound_timer.c optional mss device-driver i386/isa/sound/sound_timer.c optional sscape device-driver i386/isa/sound/sound_timer.c optional trix device-driver i386/isa/sound/soundcard.c optional snd device-driver i386/isa/sound/sscape.c optional sscape device-driver i386/isa/sound/sys_timer.c optional snd device-driver i386/isa/sound/trix.c optional trix device-driver i386/isa/sound/uart6850.c optional uart device-driver i386/isa/spigot.c optional spigot device-driver i386/isa/spkr.c optional speaker device-driver i386/isa/stallion.c optional stl device-driver i386/isa/tw.c optional tw device-driver i386/isa/vesa.c optional vga device-driver i386/isa/wd.c optional wd device-driver i386/isa/wd.c optional wdc device-driver i386/isa/wfd.c optional wfd device-driver i386/isa/wst.c optional wst device-driver i386/isa/wt.c optional wt device-driver i386/linux/imgact_linux.c optional compat_linux i386/linux/linux_dummy.c optional compat_linux i386/linux/linux_file.c optional compat_linux i386/linux/linux_ioctl.c optional compat_linux i386/linux/linux_ipc.c optional compat_linux i386/linux/linux_locore.s optional compat_linux \ dependency "linux_assym.h" i386/linux/linux_misc.c optional compat_linux i386/linux/linux_signal.c optional compat_linux i386/linux/linux_socket.c optional compat_linux i386/linux/linux_stats.c optional compat_linux i386/linux/linux_sysent.c optional compat_linux i386/linux/linux_sysvec.c optional compat_linux i386/linux/linux_util.c optional compat_linux i4b/layer1/i4b_avm_a1.c optional isic device-driver i4b/layer1/i4b_avm_fritz_pci.c optional isic device-driver i4b/layer1/i4b_avm_fritz_pcmcia.c optional isic device-driver i4b/layer1/i4b_bchan.c optional isic device-driver i4b/layer1/i4b_ctx_s0P.c optional isic device-driver i4b/layer1/i4b_drn_ngo.c optional isic device-driver i4b/layer1/i4b_dynalink.c optional isic device-driver i4b/layer1/i4b_elsa_qs1i.c optional isic device-driver i4b/layer1/i4b_elsa_qs1p.c optional isic device-driver i4b/layer1/i4b_hscx.c optional isic device-driver i4b/layer1/i4b_isac.c optional isic device-driver i4b/layer1/i4b_isic.c optional isic device-driver i4b/layer1/i4b_isic_isa.c optional isic device-driver i4b/layer1/i4b_isic_pci.c optional isic device-driver i4b/layer1/i4b_isic_pcmcia.c optional isic device-driver i4b/layer1/i4b_isic_pnp.c optional isic device-driver i4b/layer1/i4b_itk_ix1.c optional isic device-driver i4b/layer1/i4b_l1.c optional isic device-driver i4b/layer1/i4b_l1fsm.c optional isic device-driver i4b/layer1/i4b_sws.c optional isic device-driver i4b/layer1/i4b_tel_s016.c optional isic device-driver i4b/layer1/i4b_tel_s0163.c optional isic device-driver i4b/layer1/i4b_tel_s08.c optional isic device-driver i4b/layer1/i4b_tel_s0P.c optional isic device-driver i4b/layer1/i4b_usr_sti.c optional isic device-driver isa/atkbd_isa.c optional atkbd device-driver isa/atkbdc_isa.c optional atkbdc device-driver isa/psm.c optional psm device-driver isa/sio.c optional sio device-driver isa/syscons_isa.c optional sc device-driver isa/vga_isa.c optional vga device-driver libkern/bcd.c standard libkern/divdi3.c standard libkern/index.c standard libkern/inet_ntoa.c standard libkern/mcount.c optional profiling-routine libkern/moddi3.c standard libkern/qdivrem.c standard libkern/qsort.c standard libkern/random.c standard libkern/rindex.c standard libkern/scanc.c standard libkern/skpc.c standard libkern/strcat.c standard libkern/strcmp.c standard libkern/strcpy.c standard libkern/strlen.c standard libkern/strncmp.c standard libkern/strncpy.c standard libkern/udivdi3.c standard libkern/umoddi3.c standard -pci/es1370.c optional pcm device-driver -pci/ide_pci.c optional wd device-driver +pci/es1370.c optional pcm pci device-driver +pci/ide_pci.c optional wd pci device-driver Index: head/sys/pci/es1370.c =================================================================== --- head/sys/pci/es1370.c (revision 48522) +++ head/sys/pci/es1370.c (revision 48523) @@ -1,1128 +1,1123 @@ /* * Support the ENSONIQ AudioPCI board based on the ES1370 and Codec * AK4531. * * Copyright (c) 1998 by Joachim Kuebart. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * This product includes software developed by Joachim Kuebart. * * 4. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: es1370.c,v 1.4 1999/05/09 17:06:45 peter Exp $ + * $Id: es1370.c,v 1.5 1999/06/15 00:00:10 newton Exp $ */ -#include "pci.h" #include "pcm.h" #include #include #include #include #include #include #include #include #include #include #define DSP_ULAW_NOT_WANTED #include -#if NPCI != 0 - /* -------------------------------------------------------------------- */ /* * #defines */ #ifdef __alpha__ #define IO_SPACE_MAPPING ALPHA_BUS_SPACE_IO #define MEM_SPACE_MAPPING ALPHA_BUS_SPACE_MEM #else /* not __alpha__ */ #define IO_SPACE_MAPPING I386_BUS_SPACE_IO #define MEM_SPACE_MAPPING I386_BUS_SPACE_MEM #endif /* not __alpha__ */ #define DMA_ALIGN_THRESHOLD 4 #define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1)) #define DMA_READ_THRESHOLD 0x200 #define MEM_MAP_REG 0x14 #define UNIT(minor) ((minor) >> 4) #define DEV(minor) ((minor) & 0xf) /* -------------------------------------------------------------------- */ /* * PCI IDs of supported chips */ #define ES1370_PCI_ID 0x50001274 /* -------------------------------------------------------------------- */ /* * device private data */ struct es_info { bus_space_tag_t st; bus_space_handle_t sh; bus_dma_tag_t parent_dmat; bus_dmamap_t dmam_in, dmam_out; /* Contents of board's registers */ u_long ctrl; u_long sctrl; }; /* -------------------------------------------------------------------- */ /* * prototypes */ static void dma_wrintr(snddev_info *); static void dma_rdintr(snddev_info *); static int es_init(snddev_info *); static snd_callback_t es_callback; static d_open_t es_dsp_open; static d_close_t es_dsp_close; static d_ioctl_t es_dsp_ioctl; static d_read_t es_dsp_read; static d_write_t es_dsp_write; static void es_intr(void *); static int es_rdabort(snddev_info *); static void es_rd_map(void *, bus_dma_segment_t *, int, int); static int es_wrabort(snddev_info *); static void es_wr_map(void *, bus_dma_segment_t *, int, int); static const char *es_pci_probe __P((pcici_t, pcidi_t)); static void es_pci_attach __P((pcici_t, int)); static int es_rd_dmaupdate(snddev_info *); static d_select_t es_select; static int es_wr_dmaupdate(snddev_info *); static int alloc_dmabuf(snddev_info *, int); static int write_codec(snddev_info *, u_char, u_char); /* -------------------------------------------------------------------- */ /* * PCI driver and PCM driver method tables */ static struct pci_device es_pci_driver = { "pcm", es_pci_probe, es_pci_attach, &nsnd, NULL }; COMPAT_PCI_DRIVER(es_pci, es_pci_driver); static snddev_info es_op_desc = { "ENSONIQ AudioPCI", 0, /* type, apparently unused */ NULL, /* ISA probe */ NULL, /* ISA attach */ es_dsp_open, es_dsp_close, es_dsp_read, es_dsp_write, es_dsp_ioctl, es_select, NULL, /* Interrupt Service Routine */ es_callback, ES_BUFFSIZE, AFMT_FULLDUPLEX | AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, /* brag :-) */ }; /* -------------------------------------------------------------------- */ /* * The mixer interface */ static const struct { unsigned volidx:4; unsigned left:4; unsigned right:4; unsigned stereo:1; unsigned recmask:13; unsigned avail:1; } mixtable[SOUND_MIXER_NRDEVICES] = { [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x0000, 1 }, [SOUND_MIXER_PCM] = { 1, 0x2, 0x3, 1, 0x0400, 1 }, [SOUND_MIXER_SYNTH] = { 2, 0x4, 0x5, 1, 0x0060, 1 }, [SOUND_MIXER_CD] = { 3, 0x6, 0x7, 1, 0x0006, 1 }, [SOUND_MIXER_LINE] = { 4, 0x8, 0x9, 1, 0x0018, 1 }, [SOUND_MIXER_LINE1] = { 5, 0xa, 0xb, 1, 0x1800, 1 }, [SOUND_MIXER_LINE2] = { 6, 0xc, 0x0, 0, 0x0100, 1 }, [SOUND_MIXER_LINE3] = { 7, 0xd, 0x0, 0, 0x0200, 1 }, [SOUND_MIXER_MIC] = { 8, 0xe, 0x0, 0, 0x0001, 1 }, [SOUND_MIXER_OGAIN] = { 9, 0xf, 0x0, 0, 0x0000, 1 } }; static int mixer_ioctl(snddev_info *d, u_long cmd, caddr_t data, int fflag, struct proc *p) { int i, j, *val, ret = 0; val = (int *)data; i = cmd & 0xff; switch (cmd & IOC_DIRMASK) { case IOC_IN | IOC_OUT: /* _IOWR */ switch (i) { case SOUND_MIXER_RECSRC: for (i = j = 0; i != SOUND_MIXER_NRDEVICES; i++) if ((*val & (1 << i)) != 0) { if (!mixtable[i].recmask) *val &= ~(1 << i); else j |= mixtable[i].recmask; } d->mix_recsrc = *val; write_codec(d, CODEC_LIMIX1, j & 0x55); write_codec(d, CODEC_RIMIX1, j & 0xaa); write_codec(d, CODEC_LIMIX2, (j >> 8) & 0x17); write_codec(d, CODEC_RIMIX2, (j >> 8) & 0x0f); write_codec(d, CODEC_OMIX1, 0x7f); write_codec(d, CODEC_OMIX2, 0x3f); break; default: if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail) ret = EINVAL; else { int l, r, rl, rr; l = *val & 0xff; if (l > 100) l = 100; if (mixtable[i].left == 0xf) { if (l < 2) rl = 0x80; else rl = 7 - (l - 2) / 14; } else { if (l < 10) rl = 0x80; else rl = 15 - (l - 10) / 6; } if (mixtable[i].stereo) { r = (*val >> 8) & 0xff; if (r > 100) r = 100; if (r < 10) rr = 0x80; else rr = 15 - (r - 10) / 6; write_codec(d, mixtable[i].right, rr); } else r = l; write_codec(d, mixtable[i].left, rl); *val = d->mix_levels[i] = ((u_int) r << 8) | l; } break; } break; default: ret = ENOSYS; break; } return (ret); } /* -------------------------------------------------------------------- */ /* * File operations */ static int es_dsp_open(dev_t dev, int oflags, int devtype, struct proc *p) { int unit = UNIT(minor(dev)); snddev_info *d = &pcm_info[unit]; if (d->flags & SND_F_BUSY) return (EBUSY); d->flags = 0; d->dbuf_out.total = d->dbuf_out.prev_total = d->dbuf_in.total = d->dbuf_in.prev_total = 0; switch (DEV(minor(dev))) { case SND_DEV_DSP16: d->play_fmt = d->rec_fmt = AFMT_S16_LE; break; case SND_DEV_DSP: d->play_fmt = d->rec_fmt = AFMT_U8; break; case SND_DEV_AUDIO: d->play_fmt = d->rec_fmt = AFMT_MU_LAW; break; default: return (ENXIO); } if ((oflags & FREAD) == 0) d->rec_fmt = 0; else if ((oflags & FWRITE) == 0) d->play_fmt = 0; d->play_speed = d->rec_speed = DSP_DEFAULT_SPEED; d->flags |= SND_F_BUSY; if (oflags & O_NONBLOCK) d->flags |= SND_F_NBIO; ask_init(d); return (0); } static int es_dsp_close(dev_t dev, int cflags, int devtype, struct proc *p) { int unit = UNIT(minor(dev)); snddev_info *d = &pcm_info[unit]; d->flags &= ~SND_F_BUSY; es_rdabort(d); return (0); } static int es_dsp_read(dev_t dev, struct uio *buf, int flag) { int l, l1, limit, ret = 0, unit = UNIT(minor(dev)); long s; snddev_info *d = &pcm_info[unit]; snd_dbuf *b = &d->dbuf_in; if (d->flags & SND_F_READING) { /* This shouldn't happen and is actually silly */ tsleep(&s, PZERO, "sndar", hz); return (EBUSY); } d->flags |= SND_F_READING; /* * XXX Check for SND_F_INIT. If set, wait for DMA to run empty and * re-initialize the board */ if (buf->uio_resid - d->rec_blocksize > 0) limit = buf->uio_resid - d->rec_blocksize; else limit = 0; while ((l = buf->uio_resid) > limit) { s = spltty(); es_rd_dmaupdate(d); if ((l = min(l, b->rl)) == 0) { int timeout; if (b->dl == 0) dma_rdintr(d); if (d->flags & SND_F_NBIO) { splx(s); break; } if (buf->uio_resid - limit > b->dl) timeout = hz; else timeout = 1; splx(s); switch (ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "dsprd", timeout)) { case EINTR: es_rdabort(d); /* FALLTHROUGH */ case ERESTART: break; default: continue; } break; } splx(s); if ((l1 = b->bufsize - b->rp) < l) { if (d->flags & SND_F_XLAT8) { translate_bytes(ulaw_dsp, b->buf + b->rp, l1); translate_bytes(ulaw_dsp, b->buf, l - l1); } uiomove(b->buf + b->rp, l1, buf); uiomove(b->buf, l - l1, buf); } else { if (d->flags & SND_F_XLAT8) translate_bytes(ulaw_dsp, b->buf + b->rp, l); uiomove(b->buf + b->rp, l, buf); } s = spltty(); b->fl += l; b->rl -= l; b->rp = (b->rp + l) % b->bufsize; splx(s); } d->flags &= ~SND_F_READING; return (ret); } static int es_dsp_write(dev_t dev, struct uio *buf, int flag) { int l, l1, ret = 0, unit = UNIT(minor(dev)); long s; snddev_info *d = &pcm_info[unit]; snd_dbuf *b = &d->dbuf_out; if (d->flags & SND_F_WRITING) { /* This shouldn't happen and is actually silly */ tsleep(&s, PZERO, "sndaw", hz); return (EBUSY); } d->flags |= SND_F_WRITING; /* * XXX Check for SND_F_INIT. If set, wait for DMA to run empty and * re-initialize the board */ while ((l = buf->uio_resid) != 0) { s = spltty(); es_wr_dmaupdate(d); if ((l = min(l, b->fl)) == 0) { int timeout; if (d->flags & SND_F_NBIO) { splx(s); break; } if (buf->uio_resid >= b->dl) timeout = hz; else timeout = 1; splx(s); switch (ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "dspwr", timeout)) { case EINTR: es_wrabort(d); /* FALLTHROUGH */ case ERESTART: break; default: continue; } break; } splx(s); if ((l1 = b->bufsize - b->fp) < l) { uiomove(b->buf + b->fp, l1, buf); uiomove(b->buf, l - l1, buf); if (d->flags & SND_F_XLAT8) { translate_bytes(ulaw_dsp, b->buf + b->fp, l1); translate_bytes(ulaw_dsp, b->buf, l - l1); } } else { uiomove(b->buf + b->fp, l, buf); if (d->flags & SND_F_XLAT8) translate_bytes(ulaw_dsp, b->buf + b->fp, l); } s = spltty(); b->rl += l; b->fl -= l; b->fp = (b->fp + l) % b->bufsize; if (b->dl == 0) dma_wrintr(d); splx(s); } d->flags &= ~SND_F_WRITING; return (ret); } static int es_dsp_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) { int ret = 0, unit = UNIT(minor(dev)); snddev_info *d = &pcm_info[unit]; long s; if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) return mixer_ioctl(d, cmd, data, fflag, p); switch(cmd) { case AIONWRITE: if (d->dbuf_out.dl != 0) { s = spltty(); es_wr_dmaupdate(d); splx(s); } *(int *)data = d->dbuf_out.fl; break; case FIONREAD: if (d->dbuf_in.dl != 0) { s = spltty(); es_rd_dmaupdate(d); splx(s); } *(int *)data = d->dbuf_in.rl; break; case SNDCTL_DSP_GETISPACE: { audio_buf_info *a = (audio_buf_info *)data; snd_dbuf *b = &d->dbuf_in; if (b->dl != 0) { s = spltty(); es_rd_dmaupdate(d); splx(s); } a->bytes = b->fl; a->fragments = b->fl / d->rec_blocksize; a->fragstotal = b->bufsize / d->rec_blocksize; a->fragsize = d->rec_blocksize; } break; case SNDCTL_DSP_GETOSPACE: { audio_buf_info *a = (audio_buf_info *)data; snd_dbuf *b = &d->dbuf_out; if (b->dl != 0) { s = spltty(); es_wr_dmaupdate(d); splx(s); } a->bytes = b->fl; a->fragments = b->fl / d->rec_blocksize; a->fragstotal = b->bufsize / d->play_blocksize; a->fragsize = d->play_blocksize; } break; case SNDCTL_DSP_GETIPTR: { count_info *c = (count_info *)data; snd_dbuf *b = &d->dbuf_in; if (b->dl != 0) { s = spltty(); es_rd_dmaupdate(d); splx(s); } c->bytes = b->total; c->blocks = (b->total - b->prev_total + d->rec_blocksize - 1) / d->rec_blocksize; c->ptr = b->fp; b->prev_total = b->total; } break; case SNDCTL_DSP_GETOPTR: { count_info *c = (count_info *)data; snd_dbuf *b = &d->dbuf_out; if (b->dl != 0) { s = spltty(); es_wr_dmaupdate(d); splx(s); } c->bytes = b->total; c->blocks = (b->total - b->prev_total + d->play_blocksize - 1) / d->play_blocksize; c->ptr = b->rp; b->prev_total = b->total; } break; case AIOSTOP: case SNDCTL_DSP_RESET: case SNDCTL_DSP_SYNC: ret = EINVAL; break; default: ret = ENOSYS; break; } return (ret); } static int es_select(dev_t i_dev, int rw, struct proc * p) { return (ENOSYS); } /* -------------------------------------------------------------------- */ /* * The interrupt handler */ static void es_intr (void *p) { snddev_info *d = (snddev_info *)p; struct es_info *es = (struct es_info *)d->device_data; unsigned intsrc, sctrl; intsrc = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS); if ((intsrc & STAT_INTR) == 0) return; sctrl = es->sctrl; if (intsrc & STAT_ADC) sctrl &= ~SCTRL_R1INTEN; if (intsrc & STAT_DAC1) sctrl &= ~SCTRL_P1INTEN; if (intsrc & STAT_DAC2) { sctrl &= ~SCTRL_P2INTEN; } bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, sctrl); bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl); if (intsrc & STAT_DAC2) dma_wrintr(d); if (intsrc & STAT_ADC) dma_rdintr(d); } /* -------------------------------------------------------------------- */ /* * DMA hassle */ static int alloc_dmabuf(snddev_info *d, int rd) { struct es_info *es = (struct es_info *)d->device_data; snd_dbuf *b = rd ? &d->dbuf_in : &d->dbuf_out; bus_dmamap_t *dmam = rd ? &es->dmam_in : &es->dmam_out; if (bus_dmamem_alloc(es->parent_dmat, (void **)&b->buf, BUS_DMA_NOWAIT, dmam) != 0 || bus_dmamap_load(es->parent_dmat, *dmam, b->buf, d->bufsize, rd ? es_rd_map : es_wr_map, es, 0) != 0) return -1; b->rp = b->fp = b->dl = b->rl = 0; b->fl = b->bufsize = d->bufsize; return (0); } static int es_wr_dmaupdate(snddev_info *d) { struct es_info *es = (struct es_info *)d->device_data; unsigned hwptr, delta; bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_DAC2_FRAMECNT >> 8); hwptr = (bus_space_read_4(es->st, es->sh, ES1370_REG_DAC2_FRAMECNT & 0xff) >> 14) & 0x3fffc; delta = (d->dbuf_out.bufsize + hwptr - d->dbuf_out.rp) % d->dbuf_out.bufsize; d->dbuf_out.rp = hwptr; d->dbuf_out.rl -= delta; d->dbuf_out.fl += delta; d->dbuf_out.total += delta; return delta; } static int es_rd_dmaupdate(snddev_info *d) { struct es_info *es = (struct es_info *)d->device_data; unsigned hwptr, delta; bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMECNT >> 8); hwptr = (bus_space_read_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff) >> 14) & 0x3fffc; delta = (d->dbuf_in.bufsize + hwptr - d->dbuf_in.fp) % d->dbuf_in.bufsize; d->dbuf_in.fp = hwptr; d->dbuf_in.rl += delta; d->dbuf_in.fl -= delta; d->dbuf_in.total += delta; return delta; } /* -------------------------------------------------------------------- */ /* * Hardware */ static int es_callback(snddev_info *d, int reason) { struct es_info *es = (struct es_info *)d->device_data; int rd = reason & SND_CB_RD; switch(reason & SND_CB_REASON_MASK) { case SND_CB_INIT: es->ctrl = (es->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(d->play_speed) << CTRL_SH_PCLKDIV); snd_set_blocksize(d); es->sctrl &= ~(SCTRL_R1FMT | SCTRL_P2FMT); d->flags &= ~SND_F_XLAT8; switch(d->play_fmt) { case 0: case AFMT_U8: break; case AFMT_S16_LE: es->sctrl |= SCTRL_P2SEB; break; case AFMT_MU_LAW: d->flags |= SND_F_XLAT8; break; default: return (-1); } switch(d->rec_fmt) { case 0: case AFMT_U8: break; case AFMT_S16_LE: es->sctrl |= SCTRL_R1SEB; break; case AFMT_MU_LAW: d->flags |= SND_F_XLAT8; break; default: return (-1); } if (d->flags & SND_F_STEREO) es->sctrl |= SCTRL_P2SMB | SCTRL_R1SMB; bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl); bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl); break; case SND_CB_START: if (rd) { es->ctrl |= CTRL_ADC_EN; es->sctrl = (es->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN; bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_SCOUNT, d->dbuf_in.dl / d->dbuf_in.sample_size - 1); } else { es->ctrl |= CTRL_DAC2_EN; es->sctrl = (es->sctrl & ~(SCTRL_P2ENDINC | SCTRL_P2STINC | SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN)) | SCTRL_P2INTEN | (((d->play_fmt == AFMT_S16_LE) ? 2 : 1) << SCTRL_SH_P2ENDINC); bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_SCOUNT, d->dbuf_out.dl / d->dbuf_out.sample_size - 1); } bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl); bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl); break; case SND_CB_ABORT: case SND_CB_STOP: if (rd) es->ctrl &= ~CTRL_ADC_EN; else es->ctrl &= ~CTRL_DAC2_EN; bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl); break; default: return (-1); } return (0); } static int write_codec(snddev_info *d, u_char i, u_char data) { struct es_info *es = (struct es_info *)d->device_data; int wait = 100; /* 100 msec timeout */ do { if ((bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS) & STAT_CSTAT) == 0) { bus_space_write_2(es->st, es->sh, ES1370_REG_CODEC, ((u_short)i << CODEC_INDEX_SHIFT) | data); return (0); } DELAY(1000); /* tsleep(&wait, PZERO, "sndaw", hz / 1000); */ } while (--wait); printf("pcm: write_codec timed out\n"); return (-1); } static void es_wr_map(void *arg, bus_dma_segment_t *segs, int nseg, int error) { struct es_info *es = (struct es_info *)arg; bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_DAC2_FRAMEADR >> 8); bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMEADR & 0xff, segs->ds_addr); bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMECNT & 0xff, (segs->ds_len >> 2) - 1); } static void es_rd_map(void *arg, bus_dma_segment_t *segs, int nseg, int error) { struct es_info *es = (struct es_info *)arg; bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMEADR >> 8); bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMEADR & 0xff, segs->ds_addr); bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff, (segs->ds_len >> 2) - 1); } static void dma_wrintr(snddev_info *d) { snd_dbuf *b = &d->dbuf_out; /* * According to Linux driver: * dmaupdate() * Bei underrun error++ * wake_up(dac2.wait) */ if (b->dl != 0) { es_wr_dmaupdate(d); wakeup(b); } if (b->rl >= DMA_ALIGN_THRESHOLD && !(d->flags & SND_F_ABORTING)) { int l = min(b->rl, d->play_blocksize); l &= DMA_ALIGN_MASK; if (l != b->dl) { if (b->dl != 0) { d->callback(d, SND_CB_WR | SND_CB_STOP); es_wr_dmaupdate(d); l = min(b->rl, d->play_blocksize); l &= DMA_ALIGN_MASK; } b->dl = l; d->callback(d, SND_CB_WR | SND_CB_START); } } else if (b->dl != 0) { b->dl = 0; d->callback(d, SND_CB_WR | SND_CB_STOP); es_wr_dmaupdate(d); } } static void dma_rdintr(snddev_info *d) { snd_dbuf *b = &d->dbuf_in; if (b->dl != 0) { es_rd_dmaupdate(d); wakeup(b); } if (b->fl >= DMA_READ_THRESHOLD && !(d->flags & SND_F_ABORTING)) { int l = min(b->fl, d->rec_blocksize); l &= DMA_ALIGN_MASK; if (l != b->dl) { if (b->dl != 0) { d->callback(d, SND_CB_RD | SND_CB_STOP); es_rd_dmaupdate(d); l = min(b->fl, d->rec_blocksize); l &= DMA_ALIGN_MASK; } b->dl = l; d->callback(d, SND_CB_RD | SND_CB_START); } } else { if (b->dl != 0) { b->dl = 0; d->callback(d, SND_CB_RD | SND_CB_STOP); es_rd_dmaupdate(d); } } } static int es_wrabort(snddev_info *d) { snd_dbuf *b = &d->dbuf_out; long s; int missing; s = spltty(); if (b->dl != 0) { wakeup(b); b->dl = 0; d->callback(d, SND_CB_WR | SND_CB_ABORT); } es_wr_dmaupdate(d); missing = b->rl; b->rl = 0; b->fp = b->rp; b->fl = b->bufsize; splx(s); return missing; } static int es_rdabort(snddev_info *d) { snd_dbuf *b = &d->dbuf_in; long s; int missing; s = spltty(); if (b->dl != 0) { wakeup(b); b->dl = 0; d->callback(d, SND_CB_RD | SND_CB_ABORT); es_rd_dmaupdate(d); } missing = b->rl; b->rl = 0; b->fp = b->rp; b->fl = b->bufsize; splx(s); return missing; } /* -------------------------------------------------------------------- */ /* * Probe and attach the card */ static int es_init(snddev_info *d) { struct es_info *es = (struct es_info *)d->device_data; u_int i; es->ctrl = CTRL_CDC_EN | CTRL_SERR_DIS | (DAC2_SRTODIV(DSP_DEFAULT_SPEED) << CTRL_SH_PCLKDIV); bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl); es->sctrl = 0; bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl); write_codec(d, CODEC_RES_PD, 3);/* No RST, PD */ write_codec(d, CODEC_CSEL, 0); /* CODEC ADC and CODEC DAC use * {LR,B}CLK2 and run off the LRCLK2 * PLL; program DAC_SYNC=0! */ write_codec(d, CODEC_ADSEL, 0); /* Recording source is mixer */ write_codec(d, CODEC_MGAIN, 0); /* MIC amp is 0db */ i = SOUND_MASK_MIC; mixer_ioctl(d, SOUND_MIXER_WRITE_RECSRC, (caddr_t) &i, 0, NULL); i = 0; mixer_ioctl(d, SOUND_MIXER_WRITE_VOLUME, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_PCM, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_SYNTH, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_CD, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_LINE, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_LINE1, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_LINE2, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_LINE3, (caddr_t) &i, 0, NULL); mixer_ioctl(d, SOUND_MIXER_WRITE_MIC, (caddr_t) &i, 0, NULL); return (0); } static const char * es_pci_probe(pcici_t tag, pcidi_t type) { if (type == ES1370_PCI_ID) return ("AudioPCI ES1370"); return (NULL); } static void es_pci_attach(pcici_t config_id, int unit) { snddev_info *d; u_int32_t data; struct es_info *es; pci_port_t io_port; int i, mapped; vm_offset_t vaddr, paddr; if (unit > NPCM_MAX) return; d = &pcm_info[unit]; *d = es_op_desc; if ((es = malloc(sizeof(*es), M_DEVBUF, M_NOWAIT)) == NULL) { printf("pcm%d: cannot allocate softc\n", unit); return; } bzero(es, sizeof(*es)); d->device_data = es; vaddr = paddr = NULL; mapped = 0; data = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) { if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) { es->st = MEM_SPACE_MAPPING; es->sh = vaddr; mapped++; } } if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) { if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) { es->st = IO_SPACE_MAPPING; es->sh = io_port; mapped++; } } if (mapped == 0) { printf("pcm%d: unable to map any ports\n", unit); free(es, M_DEVBUF); return; } printf("pcm%d: using %s space register mapping at %#x\n", unit, es->st == IO_SPACE_MAPPING ? "I/O" : "Memory", es->sh); d->io_base = es->sh; d->mix_devs = 0; for (i = 0; i != SOUND_MIXER_NRDEVICES; i++) if (mixtable[i].avail) d->mix_devs |= (1 << i); d->mix_rec_devs = 0; for (i = 0; i != SOUND_MIXER_NRDEVICES; i++) if (mixtable[i].recmask) d->mix_rec_devs |= (1 << i); if (es_init(d) == -1) { printf("pcm%d: unable to initialize the card\n", unit); free(es, M_DEVBUF); d->io_base = 0; return; } if (pci_map_int(config_id, es_intr, d, &tty_imask) == 0) { printf("pcm%d: unable to map interrupt\n", unit); free(es, M_DEVBUF); d->io_base = 0; return; } if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/d->bufsize, /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, &es->parent_dmat) != 0) { printf("pcm%d: unable to create dma tag\n", unit); free(es, M_DEVBUF); d->io_base = 0; return; } if (alloc_dmabuf(d, 0) == -1 || alloc_dmabuf(d, 1) == -1) { printf("pcm%d: unable to allocate dma buffers\n", unit); free(es, M_DEVBUF); d->io_base = 0; return; } pcminit(d, unit); return; } - -#endif /* NPCI != 0 */ Index: head/sys/pci/ide_pci.c =================================================================== --- head/sys/pci/ide_pci.c (revision 48522) +++ head/sys/pci/ide_pci.c (revision 48523) @@ -1,1938 +1,1935 @@ /* * Copyright 1996 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ide_pci.c,v 1.33 1999/04/24 20:13:58 peter Exp $ + * $Id: ide_pci.c,v 1.34 1999/05/09 17:06:47 peter Exp $ */ -#include "pci.h" -#if NPCI > 0 #include "wd.h" #if NWDC > 0 #include #include #include #include #include #include #include #include #ifdef PC98 #include #else #include #endif #include #include #include #include #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif #define PROMISE_ULTRA33 0x4d33105a #define CMD640B_PCI_ID 0x06401095 struct ide_pci_cookie; /* structs vendor_fns, ide_pci_cookie are recursive */ struct vendor_fns { int (*vendor_dmainit) /* initialize DMA controller and drive */ (struct ide_pci_cookie *cookie, struct wdparams *wp, int (*wdcmd)(int, void *), void *); void (*vendor_status) /* prints off DMA timing info */ (struct ide_pci_cookie *cookie); }; /* * XXX the fact that this list keeps all kinds of info on PCI controllers * is pretty grotty-- much of this should be replaced by a proper integration * of PCI probes into the wd driver. * XXX if we're going to support native-PCI controllers, we also need to * keep the address of the IDE control block register, which is something wd.c * needs to know, which is why this info is in the wrong place. */ struct ide_pci_cookie { LIST_ENTRY(ide_pci_cookie) le; int iobase_wd; int ctlr; /* controller 0/1 on PCI IDE interface */ int unit; int iobase_bm; /* SFF-8038 control registers */ int altiobase_wd; pcici_t tag; pcidi_t type; struct ide_pci_prd *prd; struct vendor_fns vs; }; struct ide_pci_softc { LIST_HEAD(, ide_pci_cookie) cookies; }; static int generic_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int (*wdcmd)(int, void *), void *wdinfo); static void generic_status(struct ide_pci_cookie *cookie); static int sis_5591_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int (*wdcmd)(int, void *), void *wdinfo); static void sis_5591_status(struct ide_pci_cookie *cookie); static void via_571_status(struct ide_pci_cookie *cookie); static int via_571_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int (*wdcmd)(int, void *), void *wdinfo); static void acer_status(struct ide_pci_cookie *cookie); static int acer_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int (*wdcmd)(int, void *), void *wdinfo); static void intel_piix_dump_drive(char *ctlr, int sitre, int is_piix4, int word40, int word44, int word48, int word4a, int drive); static void intel_piix_status(struct ide_pci_cookie *cookie); static int intel_piix_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int (*wdcmd)(int, void *), void *wdinfo); static struct ide_pci_cookie * mkcookie(int iobase_wd, int ctlr, int unit, int iobase_bm, pcici_t tag, pcidi_t type, struct vendor_fns *vp, int altiobase_wd); static void ide_pci_attach(pcici_t tag, int unit); static void *ide_pci_candma(int, int, int); static int ide_pci_dmainit(void *, struct wdparams *, int (*)(int, void *), void *); static int ide_pci_dmaverify(void *, char *, u_long, int); static int ide_pci_dmasetup(void *, char *, u_long, int); static void ide_pci_dmastart(void *); static int ide_pci_dmadone(void *); static int ide_pci_status(void *); static int ide_pci_iobase(void *xcp); static int ide_pci_altiobase(void *xcp); static struct ide_pci_softc softc; static int ide_pci_softc_cookies_initted = 0; extern struct isa_driver wdcdriver; /* * PRD_ALLOC_SIZE should be something that will not be allocated across a 64k * boundary. * PRD_MAX_SEGS is defined to be the maximum number of segments required for * a transfer on an IDE drive, for an xfer that is linear in virtual memory. * PRD_BUF_SIZE is the size of the buffer needed for a PRD table. */ #define PRD_ALLOC_SIZE PAGE_SIZE #define PRD_MAX_SEGS ((256 * 512 / PAGE_SIZE) + 1) #define PRD_BUF_SIZE PRD_MAX_SEGS * 8 static void *prdbuf = 0; static void *prdbuf_next = 0; /* * Hardware specific IDE controller code. All vendor-specific code * for handling IDE timing and other chipset peculiarities should be * encapsulated here. */ /* helper funcs */ /* * nnn_mode() return the highest valid mode, or -1 if the mode class is * not supported */ static __inline int pio_mode(struct wdparams *wp) { if ((wp->wdp_atavalid & 2) == 2) { if ((wp->wdp_eidepiomodes & 2) == 2) return 4; if ((wp->wdp_eidepiomodes & 1) == 1) return 3; } return -1; } #if 0 static __inline int dma_mode(struct wdparams *wp) { /* XXX not quite sure how to verify validity on this field */ } #endif static __inline int mwdma_mode(struct wdparams *wp) { /* * XXX technically, using wdp_atavalid to test for validity of * this field is not quite correct */ if ((wp->wdp_atavalid & 2) == 2) { if ((wp->wdp_dmamword & 4) == 4) return 2; if ((wp->wdp_dmamword & 2) == 2) return 1; if ((wp->wdp_dmamword & 1) == 1) return 0; } return -1; } static __inline int udma_mode(struct wdparams *wp) { if ((wp->wdp_atavalid & 4) == 4) { if ((wp->wdp_udmamode & 4) == 4) return 2; if ((wp->wdp_udmamode & 2) == 2) return 1; if ((wp->wdp_udmamode & 1) == 1) return 0; } return -1; } /* Generic busmastering PCI-IDE */ static int generic_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int(*wdcmd)(int, void *), void *wdinfo) { /* * punt on the whole timing issue by looking for either a * drive programmed for both PIO4 and mDMA2 (which use similar * timing) or a drive in an UltraDMA mode (hopefully all * controllers have separate timing for UDMA). one hopes that if * the drive's DMA mode has been configured by the BIOS, the * controller's has also. * * XXX there are examples where this approach is now known to be * broken, at least on systems based on Intel chipsets. */ if ((pio_mode(wp) >= 4 && mwdma_mode(wp) >= 2) || (udma_mode(wp) >= 2)) { printf("ide_pci: generic_dmainit %04x:%d: warning, IDE controller timing not set\n", cookie->iobase_wd, cookie->unit); /* If we're here, then this controller is most likely not set for UDMA, even if the drive may be. Make the drive wise up. */ if(!wdcmd(WDDMA_MDMA2, wdinfo)) printf("generic_dmainit: could not set multiword DMA mode!\n"); return 1; } #ifdef IDE_PCI_DEBUG printf("pio_mode: %d, mwdma_mode(wp): %d, udma_mode(wp): %d\n", pio_mode(wp), mwdma_mode(wp), udma_mode(wp)); #endif return 0; } static void generic_status(struct ide_pci_cookie *cookie) { printf("generic_status: no PCI IDE timing info available\n"); } static struct vendor_fns vs_generic = { generic_dmainit, generic_status }; /* VIA Technologies "82C571" PCI-IDE controller core */ static void via_571_status(struct ide_pci_cookie *cookie) { int iobase_wd; int ctlr, unit; int iobase_bm; pcici_t tag; pcidi_t type; u_long word40[5]; int i, unitno; iobase_wd = cookie->iobase_wd; unit = cookie->unit; ctlr = cookie->ctlr; iobase_bm = cookie->iobase_bm; tag = cookie->tag; type = cookie->type; unitno = ctlr * 2 + unit; for (i=0; i<5; i++) { word40[i] = pci_conf_read(tag, i * 4 + 0x40); } if (ctlr == 0) printf("via_571_status: Primary IDE prefetch/postwrite %s/%s\n", word40[0] & 0x8000 ? "enabled" : "disabled", word40[0] & 0x4000 ? "enabled" : "disabled"); else printf("via_571_status: Secondary IDE prefetch/postwrite %s/%s\n", word40[0] & 0x2000 ? "enabled" : "disabled", word40[0] & 0x1000 ? "enabled" : "disabled"); printf("via_571_status: busmaster status read retry %s\n", (word40[1] & 0x08) ? "enabled" : "disabled"); printf("via_571_status: %s drive %d data setup=%d active=%d recovery=%d\n", unitno < 2 ? "primary" : "secondary", unitno & 1, ((u_int)(word40[3] >> ((3 - unitno) * 2)) & 3) + 1, ((u_int)(word40[2] >> (((3 - unitno) * 8) + 4)) & 0x0f) + 1, ((u_int)(word40[2] >> ((3 - unitno) * 8)) & 0x0f) + 1); if (ctlr == 0) printf("via_571_status: primary ctrl active=%d recovery=%d\n", ((u_int)(word40[3] >> 28) & 0x0f) + 1, ((u_int)(word40[2] >> 24) & 0x0f) + 1); else printf("via_571_status: secondary ctrl active=%d recovery=%d\n", ((u_int)(word40[3] >> 20) & 0x0f) + 1, ((u_int)(word40[2] >> 16) & 0x0f) + 1); /* UltraDMA dump */ { int foo; foo = word40[4] >> ((3 - unitno) * 8); printf("via_571_status: %s drive %d udma method=%d enable=%d PIOmode=%d cycle=%d\n", i < 2 ? "primary" : "secondary", i & 1, (foo >> 7) & 1, (foo >> 6) & 1, (foo >> 5) & 1, (foo & 3) + 2); } } /* * XXX timing values set here are only good for 30/33MHz buses; should deal * with slower ones too (BTW: you overclock-- you lose) */ static int via_571_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int(*wdcmd)(int, void *), void *wdinfo) { int r; u_long pci_revision; int unitno; pci_revision = pci_conf_read(cookie->tag, PCI_CLASS_REG) & PCI_REVISION_MASK; unitno = cookie->ctlr * 2 + cookie->unit; /* If it's a UDMA drive on a '590, set it up */ /* * XXX the revision number we check for is of dubious validity. * it's extracted from the AMD 645 datasheet. */ if (pci_revision >= 1 && udma_mode(wp) >= 2) { unsigned int word50, mask, new; word50 = pci_conf_read(cookie->tag, 0x50); /* UDMA enable by SET FEATURES, DMA cycles, cycle time 2T */ mask = 0xe3000000 >> (unitno * 8); new = 0x40000000 >> (unitno * 8); word50 &= ~mask; word50 |= new; pci_conf_write(cookie->tag, 0x50, word50); /* * With the '590, drive configuration should come *after* the * controller configuration, to make sure the controller sees * the SET FEATURES command and does the right thing. */ /* Set UDMA mode 2 on drive */ if (bootverbose) printf("via_571_dmainit: setting ultra DMA mode 2\n"); r = wdcmd(WDDMA_UDMA2, wdinfo); if (!r) { printf("via_571_dmainit: setting DMA mode failed\n"); return 0; } if (bootverbose) via_571_status(cookie); return 1; } /* otherwise, try and program it for MW DMA mode 2 */ else if (mwdma_mode(wp) >= 2 && pio_mode(wp) >= 4) { u_long workword; /* Set multiword DMA mode 2 on drive */ if (bootverbose) printf("via_571_dmainit: setting multiword DMA mode 2\n"); r = wdcmd(WDDMA_MDMA2, wdinfo); if (!r) { printf("via_571_dmainit: setting DMA mode failed\n"); return 0; } /* Configure the controller appropriately for MWDMA mode 2 */ workword = pci_conf_read(cookie->tag, 0x40); /* * enable prefetch/postwrite-- XXX may cause problems * with CD-ROMs? */ workword |= 0xc000 >> (cookie->ctlr * 2); /* FIFO configurations-- equal split, threshold 1/2 */ workword &= 0x90ffffff; workword |= 0x2a000000; pci_conf_write(cookie->tag, 0x40, workword); workword = pci_conf_read(cookie->tag, 0x44); /* enable status read retry */ workword |= 8; /* enable FIFO flush on interrupt and end of sector */ workword &= 0xff0cffff; workword |= 0x00f00000; pci_conf_write(cookie->tag, 0x44, workword); workword = pci_conf_read(cookie->tag, 0x48); /* set Mode2 timing */ workword &= ~(0xff000000 >> (unitno * 8)); workword |= 0x31000000 >> (unitno * 8); pci_conf_write(cookie->tag, 0x48, workword); /* set sector size */ pci_conf_write(cookie->tag, cookie->ctlr ? 0x68 : 0x60, 0x200); if (bootverbose) via_571_status(cookie); return 1; } return 0; } static struct vendor_fns vs_via_571 = { via_571_dmainit, via_571_status }; /* Cyrix Cx5530 Courtesy of Whistle Communications */ /* * Verify that controller can handle a dma request for cp. Should * not affect any hardware or driver state. * Special version for 5530 that allows only transfers on 16 byte boundaries.(!) * (Yes the Cyrix 5530 can only UDMA to cache-line boundaries.(bleh!)) * Luckily nearly all disk IO is to kernel bufers which are page alligned. * They may fix this in some other version of the chip, but it's in the latest * at this time (Jan 1999). */ static int cyrix_5530_dmaverify(void *xcp, char *vaddr, u_long count, int dir) { int badfu; /* * check for nonaligned or odd-length Stuff */ badfu = ((unsigned int)vaddr & 0xf) || (count & 0xf); #ifdef DIAGNOSTIC if (badfu) { printf("ide_pci: dmaverify odd vaddr or length, "); printf("vaddr = %p length = %08lx\n", (void *)vaddr, count); } #endif return (!badfu); } /* * XXX Unit number handling may be broken in the Cx5530 modules. * It has only been checked with a single drive. * 12MByte/Sec transfer rates were seen with Quantum Fireball drives * with negligable CPU usage. */ static void cyrix_5530_status(struct ide_pci_cookie *cookie) { int iobase_wd; int ctlr, unit; int iobase_bm; pcici_t tag; pcidi_t type; u_long PIO_config; u_long DMA_config; int unitno; iobase_wd = cookie->iobase_wd; unit = cookie->unit; ctlr = cookie->ctlr; iobase_bm = cookie->iobase_bm; tag = cookie->tag; type = cookie->type; unitno = ctlr * 2 + unit; /* set some values the BIOS should have set */ printf("Using 0x%x\n", cookie->iobase_bm); outl(iobase_bm + (unit * 0x10) + 0x20, 0x00040010); outl(iobase_bm + (unit * 0x10) + 0x24, 0x00911030); /* if ((ctlr == 0) && (unit == 0)) */ /* XXX */ /* outb(iobase_bm + (unit * 0x10) + BMISTA_PORT, 0xe6);*/ PIO_config = inl(iobase_bm + (unit * 0x10) + 0x20); DMA_config = inl(iobase_bm + (unit * 0x10) + 0x24); printf("cyrix_5530_status: %s:%u IDE PIO cfg: 0x%08lx\n", (ctlr ? "Secondary" : "Primary"), unit, PIO_config); printf("cyrix_5530_status: %s:%u IDE DMA cfg: 0x%08lx\n", (ctlr ? "Secondary" : "Primary"), unit, DMA_config); } /* * XXX timing values set here are only good for 30/33MHz buses; should deal * with slower ones too (BTW: you overclock-- you lose) */ static int cyrix_5530_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int(*wdcmd)(int, void *), void *wdinfo) { int r; u_long pci_revision; int unitno; int iobase_bm; int unit; /*cookie->unit = 0; */ /* XXX */ unit = cookie->unit; pci_revision = pci_conf_read(cookie->tag, PCI_CLASS_REG) & PCI_REVISION_MASK; unitno = cookie->ctlr * 2 + unit; iobase_bm = cookie->iobase_bm; printf("Setting using 0x%x\n", iobase_bm); if ((cookie->ctlr == 0) && (unit == 0)) /* XXX */ outb(iobase_bm + (unit * 0x10) + BMISTA_PORT, 0xe6); outl(iobase_bm + (unit * 0x10) + 0x20, 0x00040010); outl(iobase_bm + (unit * 0x10) + 0x24, 0x00911030); /* If it's a UDMA drive on a '5530, set it up */ /* * depending on what the drive can do, * set the correct modes, */ printf("wd%d: mw=0x%x, pio=0x%x, pcirev=0x%lx, udma=0x%x\n", unitno, mwdma_mode(wp), pio_mode(wp), pci_revision, udma_mode(wp)); if (/* pci_revision >= 1 && */ udma_mode(wp) >= 2) { /*outl(iobase_bm + 0x20 + (cookie->unit * 16), 0x00100010);*/ outl(iobase_bm + 0x24 + (cookie->unit * 16), 0x00911030); /* * With the Cx5530, drive configuration should come *after* the * controller configuration, to make sure the controller sees * the command and does the right thing. */ /* Set UDMA mode 2 on drive */ if (bootverbose) printf("cyrix_5530_dmainit: setting ultra DMA mode 2\n"); r = wdcmd(WDDMA_UDMA2, wdinfo); if (!r) { printf("cyrix_5530_dmainit: setting DMA mode failed\n"); return 0; } if (bootverbose) cyrix_5530_status(cookie); return 1; } /* otherwise, try and program it for MW DMA mode 2 */ else if (mwdma_mode(wp) >= 2 && pio_mode(wp) >= 4) { /* Set multiword DMA mode 2 on drive */ if (bootverbose) printf("cyrix_5530_dmainit: setting multiword DMA mode 2\n"); r = wdcmd(WDDMA_MDMA2, wdinfo); if (!r) { printf("cyrix_5530_dmainit: setting DMA mode failed\n"); return 0; } /* Configure the controller appropriately for MWDMA mode 2 */ /*outl(iobase_bm + 0x20 + (cookie->unit * 16), 0x00100010);*/ outl(iobase_bm + 0x24 + (cookie->unit * 16), 0x00002020); if (bootverbose) cyrix_5530_status(cookie); return 1; } return 0; } static struct vendor_fns vs_cyrix_5530 = { cyrix_5530_dmainit, cyrix_5530_status }; static void promise_status(struct ide_pci_cookie *cookie) { pcici_t tag; int i; u_int32_t port0_command, port0_altstatus; u_int32_t port1_command, port1_altstatus; u_int32_t dma_block; u_int32_t lat_and_interrupt; u_int32_t drivetiming; int pa, pb, mb, mc; tag = cookie->tag; port0_command = pci_conf_read(tag, 0x10); port0_altstatus = pci_conf_read(tag, 0x14); port1_command = pci_conf_read(tag, 0x18); port1_altstatus = pci_conf_read(tag, 0x1c); dma_block = pci_conf_read(tag, 0x20); lat_and_interrupt = pci_conf_read(tag, 0x3c); printf("promise_status: port0: 0x%lx, port0_alt: 0x%lx, port1: 0x%lx, port1_alt: 0x%lx\n", (u_long)port0_command, (u_long)port0_altstatus, (u_long)port1_command, (u_long)port1_altstatus); printf( "promise_status: dma control blk address: 0x%lx, int: %d, irq: %d\n", (u_long)dma_block, (u_int)(lat_and_interrupt >> 8) & 0xff, (u_int)lat_and_interrupt & 0xff); for(i=0;i<4;i+=2) { drivetiming = pci_conf_read(tag, 0x60 + i * 4); printf("drivebits%d-%d: %b\n", i, i+1, drivetiming, "\020\05Prefetch\06Iordy\07Errdy\010Sync\025DmaW\026DmaR"); pa = drivetiming & 0xf; pb = (drivetiming >> 8) & 0x1f; mb = (drivetiming >> 13) & 0x7; mc = (drivetiming >> 16) & 0xf; printf("drivetiming%d: pa: 0x%x, pb: 0x%x, mb: 0x%x, mc: 0x%x\n", i, pa, pb, mb, mc); drivetiming = pci_conf_read(tag, 0x60 + (i + 1) * 4); pa = drivetiming & 0xf; pb = (drivetiming >> 8) & 0x1f; mb = (drivetiming >> 13) & 0x7; mc = (drivetiming >> 16) & 0xf; printf("drivetiming%d: pa: 0x%x, pb: 0x%x, mb: 0x%x, mc: 0x%x\n", i + 1, pa, pb, mb, mc); } } static struct vendor_fns vs_promise = { generic_dmainit, promise_status }; /* Intel PIIX, PIIX3, and PIIX4 IDE controller subfunctions */ static void intel_piix_dump_drive(char *ctlr, int sitre, int is_piix4, int word40, int word44, int word48, int word4a, int drive) { char *ms; if (!sitre) ms = "master/slave"; else if (drive == 0) ms = "master"; else ms = "slave"; printf("intel_piix_status: %s %s sample = %d, %s recovery = %d\n", ctlr, ms, 5 - ((sitre && drive) ? ((word44 >> 2) & 3) : ((word40 >> 12) & 3)), ms, 4 - ((sitre && drive) ? ((word44 >> 0) & 3) : ((word40 >> 8) & 3))); word40 >>= (drive * 4); printf("intel_piix_status: %s %s fastDMAonly %s, pre/post %s,\n\ intel_piix_status: IORDY sampling %s,\n\ intel_piix_status: fast PIO %s%s\n", ctlr, (drive == 0) ? "master" : "slave", (word40 & 8) ? "enabled" : "disabled", (word40 & 4) ? "enabled" : "disabled", (word40 & 2) ? "enabled" : "disabled", (word40 & 1) ? "enabled" : "disabled", ((word40 & 9) == 9) ? " (overridden by fastDMAonly)" : "" ); if (is_piix4) printf("intel_piix_status: UltraDMA %s, CT/RP = %d/%d\n", word48 ? "enabled": "disabled", 4 - (word4a & 3), 6 - (word4a & 3)); } static void intel_piix_status(struct ide_pci_cookie *cookie) { int iobase_wd; int unit; int iobase_bm; pcici_t tag; pcidi_t type; int ctlr; u_long word40, word44, word48; int sitre, is_piix4; iobase_wd = cookie->iobase_wd; unit = cookie->unit; iobase_bm = cookie->iobase_bm; tag = cookie->tag; type = cookie->type; ctlr = cookie->ctlr; word40 = pci_conf_read(tag, 0x40); word44 = pci_conf_read(tag, 0x44); word48 = pci_conf_read(tag, 0x48); /* * XXX will not be right for the *next* generation of upward-compatible * intel IDE controllers... */ is_piix4 = pci_conf_read(tag, PCI_CLASS_REG) == 0x71118086; sitre = word40 & 0x4000; switch (ctlr * 2 + unit) { case 0: intel_piix_dump_drive("primary", sitre, is_piix4, word40 & 0xffff, word44 & 0x0f, word48, word48 >> 16, 0); break; case 1: intel_piix_dump_drive("primary", sitre, is_piix4, word40 & 0xffff, word44 & 0x0f, word48 >> 1, word48 >> 20, 1); break; case 2: intel_piix_dump_drive("secondary", sitre, is_piix4, (word40 >> 16) & 0xffff, (word44 >> 4) & 0x0f, word48 >> 2, word48 >> 24, 0); break; case 3: intel_piix_dump_drive("secondary", sitre, is_piix4, (word40 >> 16) & 0xffff, (word44 >> 4) & 0x0f, word48 >> 3, word48 >> 28, 1); break; default: printf("intel_piix_status: bad drive or controller number\n"); } } /* * XXX timing values set hereare only good for 30/33MHz buses; should deal * with slower ones too (BTW: you overclock-- you lose) */ static int intel_piix_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int(*wdcmd)(int, void *), void *wdinfo) { int r; /* If it's a UDMA drive and a PIIX4, set it up */ if (cookie->type == 0x71118086 && udma_mode(wp) >= 2) { /* Set UDMA mode 2 on controller */ int unitno, mask, new; if (bootverbose) printf("intel_piix_dmainit: setting ultra DMA mode 2\n"); r = wdcmd(WDDMA_UDMA2, wdinfo); if (!r) { printf("intel_piix_dmainit: setting DMA mode failed\n"); return 0; } unitno = cookie->ctlr * 2 + cookie->unit; mask = (1 << unitno) + (3 << (16 + unitno * 4)); new = (1 << unitno) + (2 << (16 + unitno * 4)); pci_conf_write(cookie->tag, 0x48, (pci_conf_read(cookie->tag, 0x48) & ~mask) | new); if (bootverbose) intel_piix_status(cookie); return 1; } /* * if it's an 82371FB, which can't do independent programming of * drive timing, we punt; we're not going to fuss with trying to * coordinate timing modes between drives. if this is you, get a * new motherboard. or contribute patches :) * * we do now at least see if the modes set are OK to use. this should * satisfy the majority of people, with mwdma mode2 drives. */ else if (cookie->type == 0x12308086) { u_long word40; /* can drive do PIO 4 and MW DMA 2? */ if (!(mwdma_mode(wp) >= 2 && pio_mode(wp) >= 4)) return 0; word40 = pci_conf_read(cookie->tag, 0x40); word40 >>= cookie->ctlr * 16; /* Check for timing config usable for DMA on controller */ if (!((word40 & 0x3300) == 0x2300 && ((word40 >> (cookie->unit * 4)) & 1) == 1)) return 0; /* Set multiword DMA mode 2 on drive */ if (bootverbose) printf("intel_piix_dmainit: setting multiword DMA mode 2\n"); r = wdcmd(WDDMA_MDMA2, wdinfo); if (!r) { printf("intel_piix_dmainit: setting DMA mode failed\n"); return 0; } return 1; } /* otherwise, treat it as a PIIX3 and program it for MW DMA mode 2 */ else if (mwdma_mode(wp) >= 2 && pio_mode(wp) >= 4) { u_long mask40, mask44, new40, new44; /* * If SITRE is not set, set it and copy the * appropriate bits into the secondary registers. Do * both controllers at once. */ if (((pci_conf_read(cookie->tag, 0x40) >> (16 * cookie->ctlr)) & 0x4000) == 0) { unsigned int word40, word44; word40 = pci_conf_read(cookie->tag, 0x40); /* copy bits to secondary register */ word44 = pci_conf_read(cookie->tag, 0x44); /* * I've got a Biostar motherboard with Award * BIOS that sets SITRE and secondary timing * on one controller but not the other. * Bizarre. */ if ((word40 & 0x4000) == 0) { word44 &= ~0xf; word44 |= ((word40 & 0x3000) >> 10) | ((word40 & 0x0300) >> 8); } if ((word40 & 0x40000000) == 0) { word44 &= ~0xf0; word44 |= ((word40 & 0x30000000) >> 22) | ((word40 & 0x03000000) >> 20); } /* set SITRE */ word40 |= 0x40004000; pci_conf_write(cookie->tag, 0x40, word40); pci_conf_write(cookie->tag, 0x44, word44); } /* Set multiword DMA mode 2 on drive */ if (bootverbose) printf("intel_piix_dmainit: setting multiword DMA mode 2\n"); r = wdcmd(WDDMA_MDMA2, wdinfo); if (!r) { printf("intel_piix_dmainit: setting DMA mode failed\n"); return 0; } /* * backward compatible hardware leaves us with such * twisted masses of software (aka twiddle the * extremely weird register layout on a PIIX3, setting * PIO mode 4 and MWDMA mode 2) */ if (cookie->unit == 0) { mask40 = 0x330f; new40 = 0x2307; mask44 = 0; new44 = 0; } else { mask40 = 0x00f0; new40 = 0x0070; mask44 = 0x000f; new44 = 0x000b; } if (cookie->ctlr) { mask40 <<= 16; new40 <<= 16; mask44 <<= 4; new44 <<= 4; } pci_conf_write(cookie->tag, 0x40, (pci_conf_read(cookie->tag, 0x40) & ~mask40) | new40); pci_conf_write(cookie->tag, 0x44, (pci_conf_read(cookie->tag, 0x44) & ~mask44) | new44); if (bootverbose) intel_piix_status(cookie); return 1; } return 0; } static struct vendor_fns vs_intel_piix = { intel_piix_dmainit, intel_piix_status }; static void acer_status(struct ide_pci_cookie *cookie) { /* XXX does not do anything right now */ } static int acer_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int(*wdcmd)(int, void *), void *wdinfo) { /* Acer Aladdin DMA setup code. UDMA looks to be sinfully easy to set on this thing - just one register. */ u_long word54 = pci_conf_read(cookie->tag, 0x54); /* Set the default Acer FIFO settings (0x55 = 13-word depth and slave operation mode 1) */ word54 |= 0x5555; /* Is this drive UDMA? Set it up if so... */ if(udma_mode(wp) >= 2) { /* This is really easy to do. Just write 0xa (enable UDMA mode with 2T timing) into the word at the right places. */ word54 |= (0xA << (16 + (cookie->ctlr * 8) + (cookie->unit * 4))); /* Now set the drive for UDMA2. */ if(!wdcmd(WDDMA_UDMA2, wdinfo)) { printf("acer_dmainit: could not set UDMA2 mode on wdc%d:%d!\n", cookie->ctlr, cookie->unit); return 0; } /* Write the new config into the registers. I'm not sure if I'm doing this in the right order. */ pci_conf_write(cookie->tag, 0x54, word54); } else if(mwdma_mode(wp) >= 2 && pio_mode(wp) >=4) { /* Otherwise, we're already set for regular DMA. */ if(!wdcmd(WDDMA_MDMA2, wdinfo)) { printf("acer_dmainit: could not set MWDMA2 mode on wdc%d:%d!\n", cookie->ctlr, cookie->unit); return 0; } return 1; } return 0; } static struct vendor_fns vs_acer = { acer_dmainit, acer_status }; /* SiS 5591 */ static void sis_5591_status(struct ide_pci_cookie *cookie) { int iobase_wd; int ctlr, unit; int iobase_bm; pcici_t tag; pcidi_t type; u_int word40[5]; int i, unitno; int DRTC, DATC; int val; iobase_wd = cookie->iobase_wd; unit = cookie->unit; ctlr = cookie->ctlr; iobase_bm = cookie->iobase_bm; tag = cookie->tag; type = cookie->type; unitno = ctlr * 2 + unit; for (i=0; i<5; i++) { word40[i] = pci_conf_read(tag, i * 4 + 0x40); } DRTC = word40[ctlr] >> (16 * unit); DATC = word40[ctlr] >> (8 + 16*unit); if (unitno == 0) { if ((word40[4] & 0x80000) == 0) { val = word40[2] & 0xf; if (val == 0) val = 12; else if (val > 11) val++; printf ("SiS 5591 status: CRTC %d PCICLK, ", val); val = (word40[2] >> 8) & 0x7; if (val == 0) val = 8 ; else if (val > 6) val = 12; printf ("CATC %d PCICLK, applies to all IDE devices\n", val); } else { printf ("SiS 5591 status: CRTC and CATC timings are per device, taken from DRTC and DATC\n"); } printf ("SiS 5591 status: burst cycles %s, fast post write control %s\n", ((word40[2] >> 16) & 0x80) ? "enabled" : "disabled", ((word40[2] >> 16) & 0x20) ? "enabled" : "disabled"); } val = DRTC & 0xf; if (val == 0) val = 12; else if (val > 11) val++; printf ("SiS 5591 status: %s drive %d DRTC %d PCICLK,", unitno < 2 ? "primary" : "secondary", unitno & 1, val); val = DATC & 0x7; if (val == 0) val = 8 ; else if (val > 6) val = 12; printf (" DATC %d PCICLK\n", val); printf ("SiS 5591 status: %s drive %d Ultra DMA %s", unitno < 2 ? "primary" : "secondary", unitno & 1, (DATC & 0x80) ? "disabled\n" : "enabled"); if ((DATC & 0x80) == 0) printf (", %d PCICLK data out\n", ((DATC >> 5) & 0x3) + 1); printf ("SiS 5591 status: %s drive %d postwrite %s, prefetch %s prefetch count is %d\n", unitno < 2 ? "primary" : "secondary", unitno & 1, ((word40[2] >> (28 + unitno)) & 1) ? "enabled" : "disabled", ((word40[2] >> (24 + unitno)) & 1) ? "enabled" : "disabled", (word40[3] >> (16 * ctlr)) & 0xffff); printf ("SiS 5591 status: %s drive %d has%s been configured for DMA\n", unitno < 2 ? "primary" : "secondary", unitno & 1, (inb(iobase_bm + BMISTA_PORT) & ((unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP)) ? " " : " not"); } static int sis_5591_dmainit(struct ide_pci_cookie *cookie, struct wdparams *wp, int(*wdcmd)(int, void *), void *wdinfo) { int r; unsigned int workword, new, mask; int ctlr, unit; int iobase_bm; pcici_t tag; int unitno; unit = cookie->unit; ctlr = cookie->ctlr; iobase_bm = cookie->iobase_bm; tag = cookie->tag; unitno = ctlr * 2 + unit; if (udma_mode(wp) >= 2) { workword = pci_conf_read(tag, ctlr * 4 + 0x40); /* These settings are a little arbitrary. They're taken from my * system, where the BIOS has already set the values, but where * we don't detect that we're initialized because the * BMISTA_DMA?CAP values aren't set by the BIOS. * 0x8000 turns on UDMA * 0x2000 sets UDMA cycle time to 2 PCI clocks for data out * 0x0300 sets DATC to 3 PCI clocks * 0x0001 sets DRTC to 1 PCI clock */ if (unit) { mask = 0x0000ffff; new = 0xa3010000; } else { mask = 0xffff0000; new = 0x0000a301; } workword &= mask; workword |= new; pci_conf_write(tag, ctlr * 4 + 0x40, workword); outb(iobase_bm + BMISTA_PORT, (inb(iobase_bm + BMISTA_PORT) | ((unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP))); if (bootverbose) printf("SiS 5591 dmainit: %s drive %d setting ultra DMA mode 2\n", unitno < 2 ? "primary" : "secondary", unitno & 1); r = wdcmd(WDDMA_UDMA2, wdinfo); if (!r) { printf("SiS 5591 dmainit: %s drive %d setting DMA mode failed\n", unitno < 2 ? "primary" : "secondary", unitno & 1); return 0; } if (bootverbose) sis_5591_status(cookie); return 1; } /* otherwise, try and program it for MW DMA mode 2 */ else if (mwdma_mode(wp) >= 2 && pio_mode(wp) >= 4) { workword = pci_conf_read(tag, ctlr * 4 + 0x40); /* These settings are a little arbitrary. They're taken from my * system, where the BIOS has already set the values, but where * we don't detect that we're initialized because the * BMISTA_DMA?CAP values aren't set by the BIOS. * 0x0300 sets DATC to 3 PCI clocks * 0x0001 sets DRTC to 1 PCI clock */ if (unit) { mask = 0x0000ffff; new = 0x03010000; } else { mask = 0xffff0000; new = 0x00000301; } workword &= mask; workword |= new; pci_conf_write(tag, ctlr * 4 + 0x40, workword); outb(iobase_bm + BMISTA_PORT, (inb(iobase_bm + BMISTA_PORT) | ((unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP))); /* Set multiword DMA mode 2 on drive */ if (bootverbose) printf("SiS 5591 dmainit: %s drive %d setting multiword DMA mode 2\n", unitno < 2 ? "primary" : "secondary", unitno & 1); r = wdcmd(WDDMA_MDMA2, wdinfo); if (!r) { printf("SiS 5591 dmainit: %s drive %d setting DMA mode failed\n", unitno < 2 ? "primary" : "secondary", unitno & 1); return 0; } if (bootverbose) sis_5591_status(cookie); return 1; } return 0; } static struct vendor_fns vs_sis_5591 = { sis_5591_dmainit, sis_5591_status }; /* Generic SFF-8038i code-- all code below here, except for PCI probes, * more or less conforms to the SFF-8038i spec as extended for PCI. * There should be no code that goes beyond that feature set below. */ /* XXX mkcookie is overloaded with too many parameters */ static struct ide_pci_cookie * mkcookie(int iobase_wd, int ctlr, int unit, int iobase_bm, pcici_t tag, pcidi_t type, struct vendor_fns *vp, int altiobase_wd) { struct ide_pci_cookie *cp; cp = malloc(sizeof *cp, M_DEVBUF, M_NOWAIT); if (!cp) return 0; cp->iobase_wd = iobase_wd; cp->ctlr = ctlr; cp->unit = unit; cp->tag = tag; cp->type = type; cp->iobase_bm = iobase_bm; cp->altiobase_wd = altiobase_wd; bcopy(vp, &cp->vs, sizeof(struct vendor_fns)); if (!prdbuf) { prdbuf = malloc(PRD_ALLOC_SIZE, M_DEVBUF, M_NOWAIT); if (!prdbuf) { FREE(cp, M_DEVBUF); return 0; } if (((int)prdbuf >> PAGE_SHIFT) ^ (((int)prdbuf + PRD_ALLOC_SIZE - 1) >> PAGE_SHIFT)) { printf("ide_pci: prdbuf straddles page boundary, no DMA\n"); FREE(cp, M_DEVBUF); FREE(prdbuf, M_DEVBUF); return 0; } prdbuf_next = prdbuf; } if (((char *)prdbuf_next + PRD_BUF_SIZE) > ((char *)prdbuf + PRD_ALLOC_SIZE)) { printf("ide_pci: mkcookie %04x:%d: no more space for PRDs, no DMA\n", iobase_wd, unit); FREE(cp, M_DEVBUF); return 0; } cp->prd = prdbuf_next; (char *)prdbuf_next += PRD_BUF_SIZE; LIST_INSERT_HEAD(&softc.cookies, cp, le); return cp; } static const char * ide_pci_probe(pcici_t tag, pcidi_t type) { u_long data; data = pci_conf_read(tag, PCI_CLASS_REG); if ((data & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE && ((data & PCI_SUBCLASS_MASK) == 0x00010000 || ((data & PCI_SUBCLASS_MASK) == 0x00040000))) { if (type == 0x71118086) return ("Intel PIIX4 Bus-master IDE controller"); if (type == 0x70108086) return ("Intel PIIX3 Bus-master IDE controller"); if (type == 0x12308086) return ("Intel PIIX Bus-master IDE controller"); if (type == PROMISE_ULTRA33) return ("Promise Ultra/33 IDE controller"); if (type == 0x05711106) return ("VIA 82C586x (Apollo) Bus-master IDE controller"); if (type == 0x01021078) return ("Cyrix 5530 Bus-master IDE controller"); if (type == 0x522910b9) return ("Acer Aladdin IV/V (M5229) Bus-master IDE controller"); if (type == 0x55131039) return ("SiS 5591 Bus-master IDE Controller"); if (type == CMD640B_PCI_ID) return "CMD 640B IDE controller"; if (data & 0x8000) return ("PCI IDE controller (busmaster capable)"); else return ("PCI IDE controller (not busmaster capable)"); }; return ((char*)0); } static void ide_pci_attach(pcici_t tag, int unit) { u_long class = 0, cmd; int bmista_1, bmista_2; int iobase_wd_1, iobase_wd_2, iobase_bm_1, iobase_bm_2; int altiobase_wd_1, altiobase_wd_2; struct vendor_fns *vp; pcidi_t type; struct ide_pci_cookie *cookie; int ctlridx; ctlridx = unit * 2; /* set up vendor-specific stuff */ type = pci_conf_read(tag, PCI_ID_REG); if (type != PROMISE_ULTRA33) { /* is it busmaster capable? bail if not */ class = pci_conf_read(tag, PCI_CLASS_REG); if (!(class & 0x8000)) { return; } /* is it enabled and is busmastering turned on? */ cmd = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); if ((cmd & 5) != 5) { return; } } switch (type) { case 0x71118086: case 0x70108086: case 0x12308086: /* Intel PIIX, PIIX3, PIIX4 */ vp = &vs_intel_piix; break; case 0x5711106: /* VIA Apollo chipset family */ vp = &vs_via_571; break; case PROMISE_ULTRA33: /* Promise controllers */ vp = &vs_promise; break; case 0x01021078: /* cyrix 5530 */ printf("cyrix 5530\n"); vp = &vs_cyrix_5530; break; case 0x522910B9: /* Acer Aladdin IV/V (M5229) */ vp = &vs_acer; break; case 0x55131039: /* SiS 5591 */ vp = &vs_sis_5591; break; case CMD640B_PCI_ID: /* CMD 640B IDE */ wdc_pci(Q_CMD640B); /* I'm curious to know if we can disable this and remove the return */ #if 1 return; #endif vp = &vs_generic; break; default: /* everybody else */ vp = &vs_generic; break; } if (type != PROMISE_ULTRA33) { if ((class & 0x100) == 0) { iobase_wd_1 = IO_WD1; altiobase_wd_1 = iobase_wd_1 + wd_altsts; } else { iobase_wd_1 = pci_conf_read(tag, 0x10) & 0xfffc; altiobase_wd_1 = pci_conf_read(tag, 0x14) & 0xfffc; } if ((class & 0x400) == 0) { iobase_wd_2 = IO_WD2; altiobase_wd_2 = iobase_wd_2 + wd_altsts; } else { iobase_wd_2 = pci_conf_read(tag, 0x18) & 0xfffc; altiobase_wd_2 = pci_conf_read(tag, 0x1c) & 0xfffc; } } else { iobase_wd_1 = pci_conf_read(tag, 0x10) & 0xfffc; altiobase_wd_1 = pci_conf_read(tag, 0x14) & 0xfffc; iobase_wd_2 = pci_conf_read(tag, 0x18) & 0xfffc; altiobase_wd_2 = pci_conf_read(tag, 0x1c) & 0xfffc; } iobase_bm_1 = pci_conf_read(tag, 0x20) & 0xfffc; if (iobase_bm_1 == 0) { printf("ide_pci: BIOS has not configured busmaster" "I/O address,\n ide_pci: giving up\n"); return; } iobase_bm_2 = iobase_bm_1 + SFF8038_CTLR_1; wddma[unit].wdd_candma = ide_pci_candma; wddma[unit].wdd_dmainit = ide_pci_dmainit; if (type == 0x01021078 /*CYRIX_5530*/) wddma[unit].wdd_dmaverify = cyrix_5530_dmaverify; else wddma[unit].wdd_dmaverify = ide_pci_dmaverify; wddma[unit].wdd_dmaprep = ide_pci_dmasetup; wddma[unit].wdd_dmastart = ide_pci_dmastart; wddma[unit].wdd_dmadone = ide_pci_dmadone; wddma[unit].wdd_dmastatus = ide_pci_status; wddma[unit].wdd_iobase = ide_pci_iobase; wddma[unit].wdd_altiobase = ide_pci_altiobase; #if 0 /* * This code below is mighty bogus. The config entries for the * isa_devtab_bio are plugged in before the standard ISA bios scan. * This is our "hack" way to simulate a dynamic assignment of I/O * addresses, from a PCI device to an ISA probe. Sorry :-). */ if (iobase_wd_1 != IO_WD1) { struct isa_device *dvp, *dvp1, *dvup; for( dvp = isa_devtab_bio; dvp->id_id != 0; dvp++) { if ((dvp->id_driver == &wdcdriver) && (dvp->id_iobase == 0)) { int biotabunit; biotabunit = dvp->id_unit * 2; dvp->id_iobase = iobase_wd_1; dvp1 = dvp + 1; dvp1->id_iobase = iobase_wd_2; printf("ide_pci%d: adding drives to controller %d:", unit, biotabunit); for(dvup = isa_biotab_wdc; dvup->id_id != 0; dvup++) { if (dvup->id_driver != &wdcdriver) continue; if (dvup->id_unit != biotabunit) continue; dvup->id_iobase = dvp->id_iobase; printf(" %d", dvup->id_unit); dvup++; pci_map_int(tag, wdintr, (void *) dvp->id_unit, &bio_imask); if (dvup->id_id == 0) break; if (dvup->id_unit == biotabunit + 1) { dvup->id_iobase = dvp->id_iobase; printf(" %d", dvup->id_unit); dvup++; if (dvup->id_id == 0) { iobase_wd_2 = 0; break; } } if (dvup->id_unit == biotabunit + 2) { pci_map_int(tag, wdintr, (void *) ((int) dvp->id_unit + 1), &bio_imask); dvup->id_iobase = dvp1->id_iobase; printf(" %d", dvup->id_unit); dvup++; if (dvup->id_id == 0) { break; } } if (dvup->id_unit == biotabunit + 3) { pci_map_int(tag, wdintr, (void *) ((int) dvp->id_unit + 1), &bio_imask); dvup->id_iobase = dvp1->id_iobase; printf(" %d", dvup->id_unit); } break; } printf("\n"); break; } } } #endif bmista_1 = inb(iobase_bm_1 + BMISTA_PORT); bmista_2 = inb(iobase_bm_2 + BMISTA_PORT); if (!ide_pci_softc_cookies_initted) { LIST_INIT(&softc.cookies); ide_pci_softc_cookies_initted = 1; } if (iobase_wd_1 != 0) { cookie = mkcookie(iobase_wd_1, ctlridx, 0, iobase_bm_1, tag, type, vp, altiobase_wd_1); if (bootverbose) vp->vendor_status(cookie); cookie = mkcookie(iobase_wd_1, ctlridx, 1, iobase_bm_1, tag, type, vp, altiobase_wd_1); if (bootverbose) { vp->vendor_status(cookie); bmista_1 = inb(iobase_bm_1 + BMISTA_PORT); bmista_2 = inb(iobase_bm_2 + BMISTA_PORT); printf("ide_pci: busmaster 0 status: %02x from port: %08x\n", bmista_1, iobase_bm_1+BMISTA_PORT); if (bmista_1 & BMISTA_DMA0CAP) printf("ide_pci: ide0:0 has been configured for DMA by BIOS\n"); if (bmista_1 & BMISTA_DMA1CAP) printf("ide_pci: ide0:1 has been configured for DMA by BIOS\n"); } } if (iobase_wd_2 != 0) { cookie = mkcookie(iobase_wd_2, ctlridx + 1, 0, iobase_bm_2, tag, type, vp, altiobase_wd_2); if (bootverbose) vp->vendor_status(cookie); cookie = mkcookie(iobase_wd_2, ctlridx + 1, 1, iobase_bm_2, tag, type, vp, altiobase_wd_2); if (bootverbose) { vp->vendor_status(cookie); bmista_1 = inb(iobase_bm_1 + BMISTA_PORT); bmista_2 = inb(iobase_bm_2 + BMISTA_PORT); printf("ide_pci: busmaster 1 status: %02x from port: %08x\n", bmista_2, iobase_bm_2+BMISTA_PORT); if (bmista_2 & BMISTA_DMA0CAP) printf("ide_pci: ide1:0 has been configured for DMA by BIOS\n"); if (bmista_2 & BMISTA_DMA1CAP) printf("ide_pci: ide1:1 has been configured for DMA by BIOS\n"); } } } static u_long ide_pci_count; static struct pci_device ide_pci_device = { "ide_pci", ide_pci_probe, ide_pci_attach, &ide_pci_count, 0 }; COMPAT_PCI_DRIVER(ide_pci, ide_pci_device); /* * Return a cookie if we may be able to do DMA on the specified * (iobase_wd, ctlr, unit). */ static void * ide_pci_candma(int iobase_wd, int ctlr, int unit) { struct ide_pci_cookie *cp; cp = softc.cookies.lh_first; while(cp) { if (cp->ctlr == ctlr && cp->unit == unit && ((iobase_wd == 0) || (cp->iobase_wd == iobase_wd))) break; cp = cp->le.le_next; } return cp; } /* * Initialize controller and drive for DMA operation, including timing modes. * Uses data passed from the wd driver and a callback function to initialize * timing modes on the drive. */ static int ide_pci_dmainit(void *cookie, struct wdparams *wp, int(*wdcmd)(int, void *), void *wdinfo) { struct ide_pci_cookie *cp = cookie; /* * If the controller status indicates that DMA is configured already, * we flounce happily away */ if (inb(cp->iobase_bm + BMISTA_PORT) & ((cp->unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP)) return 1; /* We take a stab at it with device-dependent code */ return(cp->vs.vendor_dmainit(cp, wp, wdcmd, wdinfo)); } /* * Verify that controller can handle a dma request for cp. Should * not affect any hardware or driver state. */ static int ide_pci_dmaverify(void *xcp, char *vaddr, u_long count, int dir) { int badfu; /* * check for nonaligned or odd-length Stuff */ badfu = ((unsigned int)vaddr & 1) || (count & 1); #ifdef DIAGNOSTIC if (badfu) { printf("ide_pci: dmaverify odd vaddr or length, "); printf("vaddr = %p length = %08lx\n", (void *)vaddr, count); } #endif return (!badfu); } /* * Set up DMA for cp. It is the responsibility of the caller * to ensure that the controller is idle before this routine * is called. */ static int ide_pci_dmasetup(void *xcp, char *vaddr, u_long vcount, int dir) { struct ide_pci_cookie *cp = xcp; struct ide_pci_prd *prd; int i; u_long firstpage; u_long prd_base, prd_count; u_long nbase, ncount, nend; int iobase_bm; u_long count; #ifdef DIAGNOSTIC u_long checkcount; #endif prd = cp->prd; count = vcount; i = 0; iobase_bm = cp->iobase_bm; if (count == 0) { printf("ide_pci: dmasetup 0-length transfer, "); printf("vaddr = %p length = %08lx\n", (void *)vaddr, count); return 1; } /* Generate first PRD entry, which may be non-aligned. */ firstpage = PAGE_SIZE - ((uintptr_t)vaddr & PAGE_MASK); prd_base = vtophys(vaddr); prd_count = MIN(count, firstpage); vaddr += prd_count; count -= prd_count; /* Step through virtual pages, coalescing as needed. */ while (count) { nbase = vtophys(vaddr); ncount = MIN(count, PAGE_SIZE); nend = nbase + ncount; /* * Coalesce if physically contiguous and not crossing * 64k boundary. */ #if 0 /* * Aggregation is NOT an optimisation worth doing, * and the Cyrix UDMA controller screws itself * in some aggregated situations. * We might as well just assign each 4K page a DMA entry * as this doesn't really gain us anything to aggregate them. * This was basically copied from my agregation code in the aha * driver, but I doubt it helped much there either. [JRE] */ if ((prd_base + prd_count == nbase) && ((((nend - 1) ^ prd_base) & ~0xffff) == 0)) { prd_count += ncount; } else #endif { prd[i].prd_base = prd_base; prd[i].prd_count = (prd_count & 0xffff); i++; if (i >= PRD_MAX_SEGS) { printf("wd82371: too many segments in PRD table\n"); return 1; } prd_base = nbase; prd_count = ncount; } vaddr += ncount; count -= ncount; } /* Write last PRD entry. */ prd[i].prd_base = prd_base; prd[i].prd_count = (prd_count & 0xffff) | PRD_EOT_BIT; #ifdef DIAGNOSTIC /* sanity check the transfer for length and page-alignment, at least */ checkcount = 0; for (i = 0;; i++) { unsigned int modcount; modcount = prd[i].prd_count & 0xffffe; if (modcount == 0) modcount = 0x10000; checkcount += modcount; if (i != 0 && ((prd[i].prd_base & PAGE_MASK) != 0)) { printf("ide_pci: dmasetup() diagnostic fails-- unaligned page\n"); return 1; } if (prd[i].prd_count & PRD_EOT_BIT) break; } if (checkcount != vcount) { printf("ide_pci: dmasetup() diagnostic fails-- bad length\n"); return 1; } #endif /* Set up PRD base register */ outl(iobase_bm + BMIDTP_PORT, vtophys(prd)); /* Set direction of transfer */ outb(iobase_bm + BMICOM_PORT, (dir == B_READ) ? BMICOM_READ_WRITE : 0); /* Clear interrupt and error bits */ outb(iobase_bm + BMISTA_PORT, (inb(iobase_bm + BMISTA_PORT) | (BMISTA_INTERRUPT | BMISTA_DMA_ERROR))); return 0; } static void ide_pci_dmastart(void *xcp) { struct ide_pci_cookie *cp = xcp; int iobase_bm; iobase_bm = cp->iobase_bm; outb(iobase_bm + BMICOM_PORT, inb(iobase_bm + BMICOM_PORT) | BMICOM_STOP_START); } static int ide_pci_dmadone(void *xcp) { struct ide_pci_cookie *cp = xcp; int iobase_bm, status; status = ide_pci_status(xcp); iobase_bm = cp->iobase_bm; outb(iobase_bm + BMICOM_PORT, inb(iobase_bm + BMICOM_PORT) & ~BMICOM_STOP_START); return status; } static int ide_pci_status(void *xcp) { int iobase_bm, status, bmista; status = 0; iobase_bm = ((struct ide_pci_cookie *)xcp)->iobase_bm; bmista = inb(iobase_bm + BMISTA_PORT); if (bmista & BMISTA_INTERRUPT) status |= WDDS_INTERRUPT; if (bmista & BMISTA_DMA_ERROR) status |= WDDS_ERROR; if (bmista & BMISTA_DMA_ACTIVE) status |= WDDS_ACTIVE; return status; } static int ide_pci_altiobase(void *xcp) { struct ide_pci_cookie *cp = xcp; if (cp == 0) { return 0; } else { return cp->altiobase_wd; } } static int ide_pci_iobase(void *xcp) { struct ide_pci_cookie *cp = xcp; if (cp == 0) { return 0; } else { return cp->iobase_wd; } } #endif -#endif /* NPCI > 0 */