Index: head/share/man/man4/Makefile =================================================================== --- head/share/man/man4/Makefile (revision 333018) +++ head/share/man/man4/Makefile (revision 333019) @@ -1,1020 +1,1021 @@ # @(#)Makefile 8.1 (Berkeley) 6/18/93 # $FreeBSD$ .include PACKAGE=runtime-manuals MAN= aac.4 \ aacraid.4 \ acpi.4 \ ${_acpi_asus.4} \ ${_acpi_asus_wmi.4} \ ${_acpi_dock.4} \ ${_acpi_fujitsu.4} \ ${_acpi_hp.4} \ ${_acpi_ibm.4} \ ${_acpi_panasonic.4} \ ${_acpi_rapidstart.4} \ ${_acpi_sony.4} \ acpi_thermal.4 \ ${_acpi_toshiba.4} \ acpi_video.4 \ ${_acpi_wmi.4} \ ada.4 \ adm6996fc.4 \ adv.4 \ adw.4 \ ae.4 \ ${_aesni.4} \ age.4 \ agp.4 \ aha.4 \ ahc.4 \ ahci.4 \ ahd.4 \ ${_aibs.4} \ aio.4 \ alc.4 \ ale.4 \ alpm.4 \ altera_atse.4 \ altera_avgen.4 \ altera_jtag_uart.4 \ altera_sdcard.4 \ altq.4 \ amdpm.4 \ ${_amdsbwd.4} \ ${_amdsmb.4} \ ${_amdsmn.4} \ ${_amdtemp.4} \ ${_bxe.4} \ amr.4 \ an.4 \ ${_aout.4} \ ${_apic.4} \ arcmsr.4 \ ${_armv8crypto.4} \ ${_asmc.4} \ ata.4 \ ath.4 \ ath_ahb.4 \ ath_hal.4 \ ath_pci.4 \ atkbd.4 \ atkbdc.4 \ atp.4 \ ${_atf_test_case.4} \ ${_atrtc.4} \ ${_attimer.4} \ audit.4 \ auditpipe.4 \ aue.4 \ ${_aw_gpio.4} \ ${_aw_mmc.4} \ ${_aw_rtc.4} \ ${_aw_sid.4} \ ${_aw_syscon.4} \ axe.4 \ axge.4 \ bce.4 \ ${_bcm283x_pwm.4} \ bcma.4 \ bfe.4 \ bge.4 \ ${_bhyve.4} \ bhnd.4 \ bhnd_chipc.4 \ bhnd_pmu.4 \ bhndb.4 \ bhndb_pci.4 \ bktr.4 \ blackhole.4 \ bnxt.4 \ bpf.4 \ bridge.4 \ bt.4 \ bwi.4 \ bwn.4 \ ${_bytgpio.4} \ ${_chvgpio.4} \ capsicum.4 \ cardbus.4 \ carp.4 \ cas.4 \ cc_cdg.4 \ cc_chd.4 \ cc_cubic.4 \ cc_dctcp.4 \ cc_hd.4 \ cc_htcp.4 \ cc_newreno.4 \ cc_vegas.4 \ ${_ccd.4} \ ccr.4 \ cd.4 \ cdce.4 \ cfi.4 \ cfumass.4 \ ch.4 \ chromebook_platform.4 \ ciss.4 \ cloudabi.4 \ cmx.4 \ ${_coretemp.4} \ ${_cpuctl.4} \ cpufreq.4 \ crypto.4 \ ctl.4 \ cue.4 \ cxgb.4 \ cxgbe.4 \ cxgbev.4 \ cy.4 \ cyapa.4 \ da.4 \ dc.4 \ dcons.4 \ dcons_crom.4 \ ddb.4 \ de.4 \ devctl.4 \ disc.4 \ divert.4 \ ${_dpms.4} \ dpt.4 \ ds1307.4 \ ds3231.4 \ ${_dtrace_provs} \ dummynet.4 \ ed.4 \ edsc.4 \ ehci.4 \ em.4 \ ena.4 \ enc.4 \ epair.4 \ esp.4 \ est.4 \ et.4 \ etherswitch.4 \ eventtimers.4 \ exca.4 \ e6060sw.4 \ fd.4 \ fdc.4 \ fdt.4 \ fdt_pinctrl.4 \ fdtbus.4 \ ffclock.4 \ filemon.4 \ firewire.4 \ full.4 \ fwe.4 \ fwip.4 \ fwohci.4 \ fxp.4 \ gbde.4 \ gdb.4 \ gem.4 \ geom.4 \ geom_fox.4 \ geom_linux_lvm.4 \ geom_map.4 \ geom_uzip.4 \ gif.4 \ gpio.4 \ gpioiic.4 \ gpioled.4 \ gre.4 \ h_ertt.4 \ hifn.4 \ hme.4 \ hpet.4 \ ${_hpt27xx.4} \ ${_hptiop.4} \ ${_hptmv.4} \ ${_hptnr.4} \ ${_hptrr.4} \ ${_hv_kvp.4} \ ${_hv_netvsc.4} \ ${_hv_storvsc.4} \ ${_hv_utils.4} \ ${_hv_vmbus.4} \ ${_hv_vss.4} \ hwpmc.4 \ ichsmb.4 \ ${_ichwd.4} \ icmp.4 \ icmp6.4 \ ida.4 \ if_ipsec.4 \ ifmib.4 \ ig4.4 \ igmp.4 \ iic.4 \ iicbb.4 \ iicbus.4 \ iicsmb.4 \ iir.4 \ ${_imcsmb.4} \ inet.4 \ inet6.4 \ intpm.4 \ intro.4 \ ${_io.4} \ ${_ioat.4} \ ip.4 \ ip6.4 \ ipfirewall.4 \ ipheth.4 \ ${_ipmi.4} \ ips.4 \ ipsec.4 \ ipw.4 \ ipwfw.4 \ isci.4 \ isl.4 \ ismt.4 \ isp.4 \ ispfw.4 \ iwi.4 \ iwifw.4 \ iwm.4 \ iwmfw.4 \ iwn.4 \ iwnfw.4 \ ixgb.4 \ ixgbe.4 \ ixl.4 \ ixlv.4 \ jedec_dimm.4 \ jedec_ts.4 \ jme.4 \ joy.4 \ kbdmux.4 \ keyboard.4 \ kld.4 \ ksyms.4 \ ksz8995ma.4 \ ktr.4 \ kue.4 \ lagg.4 \ le.4 \ led.4 \ lge.4 \ ${_linux.4} \ liquidio.4 \ lm75.4 \ lmc.4 \ lo.4 \ lp.4 \ lpbb.4 \ lpt.4 \ mac.4 \ mac_biba.4 \ mac_bsdextended.4 \ mac_ifoff.4 \ mac_lomac.4 \ mac_mls.4 \ mac_none.4 \ mac_partition.4 \ mac_portacl.4 \ mac_seeotheruids.4 \ mac_stub.4 \ mac_test.4 \ malo.4 \ md.4 \ mdio.4 \ me.4 \ mem.4 \ meteor.4 \ mfi.4 \ miibus.4 \ mk48txx.4 \ mld.4 \ mlx.4 \ mlx4en.4 \ mlx5en.4 \ mly.4 \ mmc.4 \ mmcsd.4 \ mn.4 \ mod_cc.4 \ mos.4 \ mouse.4 \ mpr.4 \ mps.4 \ mpt.4 \ mrsas.4 \ msk.4 \ mtio.4 \ multicast.4 \ mvs.4 \ mwl.4 \ mwlfw.4 \ mxge.4 \ my.4 \ nand.4 \ nandsim.4 \ ncr.4 \ ncv.4 \ ${_ndis.4} \ net80211.4 \ netfpga10g_nf10bmac.4 \ netgraph.4 \ netintro.4 \ netmap.4 \ ${_nfe.4} \ ${_nfsmb.4} \ ng_async.4 \ ngatmbase.4 \ ng_atmllc.4 \ ng_bpf.4 \ ng_bridge.4 \ ng_bt3c.4 \ ng_btsocket.4 \ ng_car.4 \ ng_ccatm.4 \ ng_cisco.4 \ ng_deflate.4 \ ng_device.4 \ nge.4 \ ng_echo.4 \ ng_eiface.4 \ ng_etf.4 \ ng_ether.4 \ ng_ether_echo.4 \ ng_frame_relay.4 \ ng_gif.4 \ ng_gif_demux.4 \ ng_h4.4 \ ng_hci.4 \ ng_hole.4 \ ng_hub.4 \ ng_iface.4 \ ng_ipfw.4 \ ng_ip_input.4 \ ng_ksocket.4 \ ng_l2cap.4 \ ng_l2tp.4 \ ng_lmi.4 \ ng_mppc.4 \ ng_nat.4 \ ng_netflow.4 \ ng_one2many.4 \ ng_patch.4 \ ng_ppp.4 \ ng_pppoe.4 \ ng_pptpgre.4 \ ng_pred1.4 \ ng_rfc1490.4 \ ng_socket.4 \ ng_source.4 \ ng_split.4 \ ng_sppp.4 \ ng_sscfu.4 \ ng_sscop.4 \ ng_tag.4 \ ng_tcpmss.4 \ ng_tee.4 \ ng_tty.4 \ ng_ubt.4 \ ng_UI.4 \ ng_uni.4 \ ng_vjc.4 \ ng_vlan.4 \ nmdm.4 \ nsp.4 \ ${_ntb.4} \ ${_ntb_hw_intel.4} \ ${_ntb_hw_plx.4} \ ${_ntb_transport.4} \ ${_nda.4} \ ${_if_ntb.4} \ null.4 \ numa.4 \ ${_nvd.4} \ ${_nvme.4} \ ${_nvram.4} \ ${_nvram2env.4} \ ${_nxge.4} \ oce.4 \ ocs_fc.4\ ohci.4 \ orm.4 \ ow.4 \ ow_temp.4 \ owc.4 \ ${_padlock.4} \ pass.4 \ pccard.4 \ pccbb.4 \ pcf.4 \ pci.4 \ pcib.4 \ pcic.4 \ pcm.4 \ pcn.4 \ ${_pf.4} \ ${_pflog.4} \ ${_pfsync.4} \ pim.4 \ pms.4 \ polling.4 \ ppbus.4 \ ppc.4 \ ppi.4 \ procdesc.4 \ proto.4 \ psm.4 \ pst.4 \ pt.4 \ pts.4 \ pty.4 \ puc.4 \ ${_qlxge.4} \ ${_qlxgb.4} \ ${_qlxgbe.4} \ ${_qlnxe.4} \ ral.4 \ random.4 \ rc.4 \ rctl.4 \ re.4 \ rgephy.4 \ rights.4 \ rl.4 \ rndtest.4 \ route.4 \ rp.4 \ rtwn.4 \ rtwnfw.4 \ rtwn_pci.4 \ rue.4 \ sa.4 \ safe.4 \ sbp.4 \ sbp_targ.4 \ scc.4 \ sched_4bsd.4 \ sched_ule.4 \ screen.4 \ scsi.4 \ sctp.4 \ sdhci.4 \ sem.4 \ send.4 \ ses.4 \ sf.4 \ ${_sfxge.4} \ sge.4 \ siba.4 \ siftr.4 \ siis.4 \ simplebus.4 \ sio.4 \ sis.4 \ sk.4 \ + smartpqi.4 \ smb.4 \ smbus.4 \ smp.4 \ smsc.4 \ sn.4 \ snd_ad1816.4 \ snd_als4000.4 \ snd_atiixp.4 \ snd_cmi.4 \ snd_cs4281.4 \ snd_csa.4 \ snd_ds1.4 \ snd_emu10k1.4 \ snd_emu10kx.4 \ snd_envy24.4 \ snd_envy24ht.4 \ snd_es137x.4 \ snd_ess.4 \ snd_fm801.4 \ snd_gusc.4 \ snd_hda.4 \ snd_hdspe.4 \ snd_ich.4 \ snd_maestro3.4 \ snd_maestro.4 \ snd_mss.4 \ snd_neomagic.4 \ snd_sbc.4 \ snd_solo.4 \ snd_spicds.4 \ snd_t4dwave.4 \ snd_uaudio.4 \ snd_via8233.4 \ snd_via82c686.4 \ snd_vibes.4 \ snp.4 \ ${_spkr.4} \ splash.4 \ sppp.4 \ ste.4 \ stf.4 \ stg.4 \ stge.4 \ sym.4 \ syncache.4 \ syncer.4 \ syscons.4 \ sysmouse.4 \ tap.4 \ targ.4 \ tcp.4 \ tdfx.4 \ terasic_mtl.4 \ termios.4 \ textdump.4 \ ti.4 \ timecounters.4 \ tl.4 \ ${_tpm.4} \ trm.4 \ tty.4 \ tun.4 \ twa.4 \ twe.4 \ tws.4 \ tx.4 \ txp.4 \ udp.4 \ udplite.4 \ ure.4 \ vale.4 \ vga.4 \ vge.4 \ viapm.4 \ ${_viawd.4} \ ${_virtio.4} \ ${_virtio_balloon.4} \ ${_virtio_blk.4} \ ${_virtio_console.4} \ ${_virtio_random.4} \ ${_virtio_scsi.4} \ vkbd.4 \ vlan.4 \ vxlan.4 \ ${_vmm.4} \ ${_vmx.4} \ vpo.4 \ vr.4 \ vt.4 \ vte.4 \ ${_vtnet.4} \ ${_vxge.4} \ watchdog.4 \ wb.4 \ ${_wbwd.4} \ wi.4 \ witness.4 \ wlan.4 \ wlan_acl.4 \ wlan_amrr.4 \ wlan_ccmp.4 \ wlan_tkip.4 \ wlan_wep.4 \ wlan_xauth.4 \ wmt.4 \ ${_wpi.4} \ wsp.4 \ xe.4 \ ${_xen.4} \ xhci.4 \ xl.4 \ ${_xnb.4} \ xpt.4 \ zero.4 MLINKS= ae.4 if_ae.4 MLINKS+=age.4 if_age.4 MLINKS+=agp.4 agpgart.4 MLINKS+=alc.4 if_alc.4 MLINKS+=ale.4 if_ale.4 MLINKS+=altera_atse.4 atse.4 MLINKS+=altera_sdcard.4 altera_sdcardc.4 MLINKS+=altq.4 ALTQ.4 MLINKS+=ath.4 if_ath.4 MLINKS+=ath_pci.4 if_ath_pci.4 MLINKS+=an.4 if_an.4 MLINKS+=aue.4 if_aue.4 MLINKS+=axe.4 if_axe.4 MLINKS+=bce.4 if_bce.4 MLINKS+=bfe.4 if_bfe.4 MLINKS+=bge.4 if_bge.4 MLINKS+=bktr.4 brooktree.4 MLINKS+=bnxt.4 if_bnxt.4 MLINKS+=bridge.4 if_bridge.4 MLINKS+=bwi.4 if_bwi.4 MLINKS+=bwn.4 if_bwn.4 MLINKS+=${_bxe.4} ${_if_bxe.4} MLINKS+=cas.4 if_cas.4 MLINKS+=cdce.4 if_cdce.4 MLINKS+=cfi.4 cfid.4 MLINKS+=cloudabi.4 cloudabi32.4 \ cloudabi.4 cloudabi64.4 MLINKS+=crypto.4 cryptodev.4 MLINKS+=cue.4 if_cue.4 MLINKS+=cxgb.4 if_cxgb.4 MLINKS+=cxgbe.4 if_cxgbe.4 \ cxgbe.4 vcxgbe.4 \ cxgbe.4 if_vcxgbe.4 \ cxgbe.4 cxl.4 \ cxgbe.4 if_cxl.4 \ cxgbe.4 vcxl.4 \ cxgbe.4 if_vcxl.4 \ cxgbe.4 cc.4 \ cxgbe.4 if_cc.4 \ cxgbe.4 vcc.4 \ cxgbe.4 if_vcc.4 MLINKS+=cxgbev.4 if_cxgbev.4 \ cxgbev.4 cxlv.4 \ cxgbev.4 if_cxlv.4 \ cxgbev.4 ccv.4 \ cxgbev.4 if_ccv.4 MLINKS+=dc.4 if_dc.4 MLINKS+=de.4 if_de.4 MLINKS+=disc.4 if_disc.4 MLINKS+=ed.4 if_ed.4 MLINKS+=edsc.4 if_edsc.4 MLINKS+=em.4 if_em.4 MLINKS+=enc.4 if_enc.4 MLINKS+=epair.4 if_epair.4 MLINKS+=et.4 if_et.4 MLINKS+=fd.4 stderr.4 \ fd.4 stdin.4 \ fd.4 stdout.4 MLINKS+=fdt.4 FDT.4 MLINKS+=firewire.4 ieee1394.4 MLINKS+=fwe.4 if_fwe.4 MLINKS+=fwip.4 if_fwip.4 MLINKS+=fxp.4 if_fxp.4 MLINKS+=gem.4 if_gem.4 MLINKS+=geom.4 GEOM.4 MLINKS+=gif.4 if_gif.4 MLINKS+=gpio.4 gpiobus.4 MLINKS+=gre.4 if_gre.4 MLINKS+=hme.4 if_hme.4 MLINKS+=hpet.4 acpi_hpet.4 MLINKS+=${_hptrr.4} ${_rr232x.4} MLINKS+=${_attimer.4} ${_i8254.4} MLINKS+=ip.4 rawip.4 MLINKS+=ipfirewall.4 ipaccounting.4 \ ipfirewall.4 ipacct.4 \ ipfirewall.4 ipfw.4 MLINKS+=ipheth.4 if_ipheth.4 MLINKS+=ipw.4 if_ipw.4 MLINKS+=iwi.4 if_iwi.4 MLINKS+=iwm.4 if_iwm.4 MLINKS+=iwn.4 if_iwn.4 MLINKS+=ixgb.4 if_ixgb.4 MLINKS+=ixgbe.4 ix.4 MLINKS+=ixgbe.4 if_ix.4 MLINKS+=ixgbe.4 if_ixgbe.4 MLINKS+=ixl.4 if_ixl.4 MLINKS+=ixlv.4 if_ixlv.4 MLINKS+=jme.4 if_jme.4 MLINKS+=kue.4 if_kue.4 MLINKS+=lagg.4 trunk.4 MLINKS+=lagg.4 if_lagg.4 MLINKS+=le.4 if_le.4 MLINKS+=lge.4 if_lge.4 MLINKS+=lmc.4 if_lmc.4 MLINKS+=lo.4 loop.4 MLINKS+=lp.4 plip.4 MLINKS+=malo.4 if_malo.4 MLINKS+=md.4 vn.4 MLINKS+=mem.4 kmem.4 MLINKS+=mfi.4 mfi_linux.4 \ mfi.4 mfip.4 MLINKS+=mlx5en.4 mce.4 MLINKS+=mn.4 if_mn.4 MLINKS+=mos.4 if_mos.4 MLINKS+=msk.4 if_msk.4 MLINKS+=mwl.4 if_mwl.4 MLINKS+=mxge.4 if_mxge.4 MLINKS+=my.4 if_my.4 MLINKS+=${_ndis.4} ${_if_ndis.4} MLINKS+=netfpga10g_nf10bmac.4 if_nf10bmac.4 MLINKS+=netintro.4 net.4 \ netintro.4 networking.4 MLINKS+=${_nfe.4} ${_if_nfe.4} MLINKS+=nge.4 if_nge.4 MLINKS+=${_nxge.4} ${_if_nxge.4} MLINKS+=ow.4 onewire.4 MLINKS+=pccbb.4 cbb.4 MLINKS+=pcm.4 snd.4 \ pcm.4 sound.4 MLINKS+=pcn.4 if_pcn.4 MLINKS+=pms.4 pmspcv.4 MLINKS+=ral.4 if_ral.4 MLINKS+=re.4 if_re.4 MLINKS+=rl.4 if_rl.4 MLINKS+=rtwn_pci.4 if_rtwn_pci.4 MLINKS+=rue.4 if_rue.4 MLINKS+=scsi.4 CAM.4 \ scsi.4 cam.4 \ scsi.4 scbus.4 \ scsi.4 SCSI.4 MLINKS+=sf.4 if_sf.4 MLINKS+=sge.4 if_sge.4 MLINKS+=sis.4 if_sis.4 MLINKS+=sk.4 if_sk.4 MLINKS+=smp.4 SMP.4 MLINKS+=smsc.4 if_smsc.4 MLINKS+=sn.4 if_sn.4 MLINKS+=snd_envy24.4 snd_ak452x.4 MLINKS+=snd_sbc.4 snd_sb16.4 \ snd_sbc.4 snd_sb8.4 MLINKS+=${_spkr.4} ${_speaker.4} MLINKS+=splash.4 screensaver.4 MLINKS+=ste.4 if_ste.4 MLINKS+=stf.4 if_stf.4 MLINKS+=stge.4 if_stge.4 MLINKS+=syncache.4 syncookies.4 MLINKS+=syscons.4 sc.4 MLINKS+=tap.4 if_tap.4 MLINKS+=tdfx.4 tdfx_linux.4 MLINKS+=ti.4 if_ti.4 MLINKS+=tl.4 if_tl.4 MLINKS+=tun.4 if_tun.4 MLINKS+=tx.4 if_tx.4 MLINKS+=txp.4 if_txp.4 MLINKS+=ure.4 if_ure.4 MLINKS+=vge.4 if_vge.4 MLINKS+=vlan.4 if_vlan.4 MLINKS+=vxlan.4 if_vxlan.4 MLINKS+=${_vmx.4} ${_if_vmx.4} MLINKS+=vpo.4 imm.4 MLINKS+=vr.4 if_vr.4 MLINKS+=vte.4 if_vte.4 MLINKS+=${_vtnet.4} ${_if_vtnet.4} MLINKS+=${_vxge.4} ${_if_vxge.4} MLINKS+=watchdog.4 SW_WATCHDOG.4 MLINKS+=wb.4 if_wb.4 MLINKS+=wi.4 if_wi.4 MLINKS+=${_wpi.4} ${_if_wpi.4} MLINKS+=xe.4 if_xe.4 MLINKS+=xl.4 if_xl.4 .if ${MACHINE_CPUARCH} == "aarch64" _armv8crypto.4= armv8crypto.4 .endif .if ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "aarch64" _aw_gpio.4= aw_gpio.4 _aw_mmc.4= aw_mmc.4 _aw_rtc.4= aw_rtc.4 _aw_sid.4= aw_sid.4 _aw_syscon.4= aw_syscon.4 .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" _acpi_asus.4= acpi_asus.4 _acpi_asus_wmi.4= acpi_asus_wmi.4 _acpi_dock.4= acpi_dock.4 _acpi_fujitsu.4=acpi_fujitsu.4 _acpi_hp.4= acpi_hp.4 _acpi_ibm.4= acpi_ibm.4 _acpi_panasonic.4=acpi_panasonic.4 _acpi_rapidstart.4=acpi_rapidstart.4 _acpi_sony.4= acpi_sony.4 _acpi_toshiba.4=acpi_toshiba.4 _acpi_wmi.4= acpi_wmi.4 _aesni.4= aesni.4 _aout.4= aout.4 _apic.4= apic.4 _atrtc.4= atrtc.4 _attimer.4= attimer.4 _aibs.4= aibs.4 _amdsbwd.4= amdsbwd.4 _amdsmb.4= amdsmb.4 _amdsmn.4= amdsmn.4 _amdtemp.4= amdtemp.4 _asmc.4= asmc.4 _bxe.4= bxe.4 _bytgpio.4= bytgpio.4 _chvgpio.4= chvgpio.4 _coretemp.4= coretemp.4 _cpuctl.4= cpuctl.4 _dpms.4= dpms.4 _hpt27xx.4= hpt27xx.4 _hptiop.4= hptiop.4 _hptmv.4= hptmv.4 _hptnr.4= hptnr.4 _hptrr.4= hptrr.4 _hv_kvp.4= hv_kvp.4 _hv_netvsc.4= hv_netvsc.4 _hv_storvsc.4= hv_storvsc.4 _hv_utils.4= hv_utils.4 _hv_vmbus.4= hv_vmbus.4 _hv_vss.4= hv_vss.4 _i8254.4= i8254.4 _ichwd.4= ichwd.4 _if_bxe.4= if_bxe.4 _if_ndis.4= if_ndis.4 _if_nfe.4= if_nfe.4 _if_nxge.4= if_nxge.4 _if_urtw.4= if_urtw.4 _if_vmx.4= if_vmx.4 _if_vtnet.4= if_vtnet.4 _if_vxge.4= if_vxge.4 _if_wpi.4= if_wpi.4 _imcsmb.4= imcsmb.4 _ipmi.4= ipmi.4 _io.4= io.4 _linux.4= linux.4 _nda.4= nda.4 _ndis.4= ndis.4 _nfe.4= nfe.4 _nfsmb.4= nfsmb.4 _nvd.4= nvd.4 _nvme.4= nvme.4 _nvram.4= nvram.4 _nxge.4= nxge.4 _virtio.4= virtio.4 _virtio_balloon.4=virtio_balloon.4 _virtio_blk.4= virtio_blk.4 _virtio_console.4=virtio_console.4 _virtio_random.4= virtio_random.4 _virtio_scsi.4= virtio_scsi.4 _vmx.4= vmx.4 _vtnet.4= vtnet.4 _vxge.4= vxge.4 _padlock.4= padlock.4 _rr232x.4= rr232x.4 _speaker.4= speaker.4 _spkr.4= spkr.4 _tpm.4= tpm.4 _urtw.4= urtw.4 _viawd.4= viawd.4 _wbwd.4= wbwd.4 _wpi.4= wpi.4 _xen.4= xen.4 _xnb.4= xnb.4 .endif .if ${MACHINE_CPUARCH} == "amd64" _if_ntb.4= if_ntb.4 _ioat.4= ioat.4 _ntb.4= ntb.4 _ntb_hw_intel.4= ntb_hw_intel.4 _ntb_hw_plx.4= ntb_hw_plx.4 _ntb_transport.4=ntb_transport.4 _qlxge.4= qlxge.4 _qlxgb.4= qlxgb.4 _qlxgbe.4= qlxgbe.4 _qlnxe.4= qlnxe.4 _sfxge.4= sfxge.4 MLINKS+=qlxge.4 if_qlxge.4 MLINKS+=qlxgb.4 if_qlxgb.4 MLINKS+=qlxgbe.4 if_qlxgbe.4 MLINKS+=qlnxe.4 if_qlnxe.4 MLINKS+=sfxge.4 if_sfxge.4 .if ${MK_BHYVE} != "no" _bhyve.4= bhyve.4 _vmm.4= vmm.4 .endif .endif .if ${MACHINE_CPUARCH} == "mips" _nvram2env.4= nvram2env.4 .endif .if ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "aarch64" _bcm283x_pwm.4= bcm283x_pwm.4 .endif .if exists(${.CURDIR}/man4.${MACHINE_CPUARCH}) SUBDIR= man4.${MACHINE_CPUARCH} .endif .if ${MK_BLUETOOTH} != "no" MAN+= ng_bluetooth.4 .endif .if ${MK_CCD} != "no" _ccd.4= ccd.4 .endif .if ${MK_CDDL} != "no" _dtrace_provs= dtrace_io.4 \ dtrace_ip.4 \ dtrace_lockstat.4 \ dtrace_proc.4 \ dtrace_sched.4 \ dtrace_tcp.4 \ dtrace_udp.4 .endif .if ${MK_ISCSI} != "no" MAN+= cfiscsi.4 MAN+= iscsi.4 MAN+= iscsi_initiator.4 MAN+= iser.4 .endif .if ${MK_OFED} != "no" MAN+= mlx4ib.4 MAN+= mlx5ib.4 .endif .if ${MK_MLX5TOOL} != "no" MAN+= mlx5io.4 .endif .if ${MK_TESTS} != "no" ATF= ${SRCTOP}/contrib/atf .PATH: ${ATF}/doc _atf_test_case.4= atf-test-case.4 .endif .if ${MK_PF} != "no" _pf.4= pf.4 _pflog.4= pflog.4 _pfsync.4= pfsync.4 .endif .if ${MK_USB} != "no" MAN+= \ otus.4 \ otusfw.4 \ rsu.4 \ rsufw.4 \ rtwn_usb.4 \ rum.4 \ run.4 \ runfw.4 \ u3g.4 \ uark.4 \ uart.4 \ uath.4 \ ubsa.4 \ ubsec.4 \ ubser.4 \ ubtbcmfw.4 \ uchcom.4 \ ucom.4 \ ucycom.4 \ udav.4 \ udbp.4 \ udl.4 \ uep.4 \ ufm.4 \ ufoma.4 \ uftdi.4 \ ugen.4 \ ugold.4 \ uhci.4 \ uhid.4 \ uhso.4 \ uipaq.4 \ ukbd.4 \ uled.4 \ ulpt.4 \ umass.4 \ umcs.4 \ umct.4 \ umodem.4 \ umoscom.4 \ ums.4 \ unix.4 \ upgt.4 \ uplcom.4 \ ural.4 \ urio.4 \ urndis.4 \ ${_urtw.4} \ usb.4 \ usb_quirk.4 \ usb_template.4 \ usfs.4 \ uslcom.4 \ uvisor.4 \ uvscom.4 \ zyd.4 MLINKS+=otus.4 if_otus.4 MLINKS+=rsu.4 if_rsu.4 MLINKS+=rtwn_usb.4 if_rtwn_usb.4 MLINKS+=rum.4 if_rum.4 MLINKS+=run.4 if_run.4 MLINKS+=u3g.4 u3gstub.4 MLINKS+=uath.4 if_uath.4 MLINKS+=udav.4 if_udav.4 MLINKS+=upgt.4 if_upgt.4 MLINKS+=ural.4 if_ural.4 MLINKS+=urndis.4 if_urndis.4 MLINKS+=${_urtw.4} ${_if_urtw.4} MLINKS+=zyd.4 if_zyd.4 .endif .include Index: head/share/man/man4/smartpqi.4 =================================================================== --- head/share/man/man4/smartpqi.4 (nonexistent) +++ head/share/man/man4/smartpqi.4 (revision 333019) @@ -0,0 +1,102 @@ +.\" Copyright (c) 2018 Murthy Bhat +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. +.\" +.\" $FreeBSD$ stable/10/share/man/man4/smartpqi.4 195614 2017-01-11 08:10:18Z jkim $ +.Dd April 06, 2018 +.Dt SMARTPQI 4 +.Os +.Sh NAME +.Nm smartpqi +.Nd Microsemi smartpqi SCSI driver for PQI controllers +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd device pci +.Cd device scbus +.Cd device smartpqi +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +smartpqi_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +SCSI driver provides support for the new generation of PQI controllers from +Microsemi. +The +.Nm +driver is the first SCSI driver to implement the PQI queuing model. +.Pp +The +.Nm +driver will replace the aacraid driver for Adaptec Series 9 controllers. +.Pp +The +.Pa /dev/smartpqi? +device nodes provide access to the management interface of the controller. +One node exists per installed card. +.Sh HARDWARE +Controllers supported by the +.Nm +driver include: +.Pp +.Bl -bullet -compact +.It +HPE Gen10 Smart Array Controller Family +.It +OEM Controllers based on the Microsemi Chipset +.El +.Sh FILES +.Bl -tag -width /boot/kernel/aac.ko -compact +.It Pa /dev/smartpqi? +smartpqi management interface +.El +.Sh SEE ALSO +.Xr kld 4 , +.Xr linux 4 , +.Xr scsi 4 , +.Xr kldload 8 +.Xr pass 4 +.Xr xpt 4 +.Xr loader.conf 5 +.Xr camcontrol 8 +.Rs +.%T "Microsemi Website" +.%U http://www.microsemi.com/ +.Re +.Sh HISTORY +The +.Nm +driver first appeared in +.Fx 11.1 . +.Sh AUTHOR +.An Murthy Bhat +.Aq murthy.bhat@microsemi.com +.Sh BUGS +The controller is not actually paused on suspend/resume. Property changes on: head/share/man/man4/smartpqi.4 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/amd64/conf/GENERIC =================================================================== --- head/sys/amd64/conf/GENERIC (revision 333018) +++ head/sys/amd64/conf/GENERIC (revision 333019) @@ -1,373 +1,374 @@ # # GENERIC -- Generic kernel configuration file for FreeBSD/amd64 # # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # # https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (https://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ../../conf/NOTES and NOTES files. # If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ cpu HAMMER ident GENERIC makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options VIMAGE # Subsystem virtualization, e.g. VNET options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_OFFLOAD # TCP offload options TCP_BLACKBOX # Enhanced TCP event logging options TCP_HHOOK # hhook(9) framework for TCP options TCP_RFC7413 # TCP Fast Open options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options UFS_GJOURNAL # Enable gjournal-based UFS journaling options QUOTA # Enable disk quotas for UFS options MD_ROOT # MD is a potential root device options NFSCL # Network Filesystem Client options NFSD # Network Filesystem Server options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework options GEOM_PART_GPT # GUID Partition Tables. options GEOM_RAID # Soft RAID functionality. options GEOM_LABEL # Provides labelization options COMPAT_FREEBSD32 # Compatible with i386 binaries options COMPAT_FREEBSD4 # Compatible with FreeBSD4 options COMPAT_FREEBSD5 # Compatible with FreeBSD5 options COMPAT_FREEBSD6 # Compatible with FreeBSD6 options COMPAT_FREEBSD7 # Compatible with FreeBSD7 options COMPAT_FREEBSD9 # Compatible with FreeBSD9 options COMPAT_FREEBSD10 # Compatible with FreeBSD10 options COMPAT_FREEBSD11 # Compatible with FreeBSD11 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options STACK # stack(9) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options KBD_INSTALL_CDEV # install a CDEV entry in /dev options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing options CAPABILITY_MODE # Capsicum capability mode options CAPABILITIES # Capsicum capabilities options MAC # TrustedBSD MAC Framework options KDTRACE_FRAME # Ensure frames are compiled in options KDTRACE_HOOKS # Kernel DTrace hooks options DDB_CTF # Kernel ELF linker loads CTF data options INCLUDE_CONFIG_FILE # Include this file in kernel options RACCT # Resource accounting framework options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default options RCTL # Resource limits # Debugging support. Always need this: options KDB # Enable kernel debugger support. options KDB_TRACE # Print a stack trace for a panic. # For full debugger support use (turn off in stable branch): options BUF_TRACKING # Track buffer history options DDB # Support DDB. options FULL_BUF_TRACKING # Track more buffer history options GDB # Support remote GDB. options DEADLKRES # Enable the deadlock resolver options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones # Make an SMP-capable kernel by default options SMP # Symmetric MultiProcessor Kernel options EARLY_AP_STARTUP # CPU frequency control device cpufreq # Bus support. device acpi options ACPI_DMAR device pci options PCI_HP # PCI-Express native HotPlug options PCI_IOV # PCI SR-IOV support # Floppy drives device fdc # ATA controllers device ahci # AHCI-compatible SATA controllers device ata # Legacy ATA/SATA controllers device mvs # Marvell 88SX50XX/88SX60XX/88SX70XX/SoC SATA device siis # SiliconImage SiI3124/SiI3132/SiI3531 SATA # SCSI Controllers device ahc # AHA2940 and onboard AIC7xxx devices device ahd # AHA39320/29320 and onboard AIC79xx devices device esp # AMD Am53C974 (Tekram DC-390(T)) device hptiop # Highpoint RocketRaid 3xxx series device isp # Qlogic family #device ispfw # Firmware for QLogic HBAs- normally a module device mpt # LSI-Logic MPT-Fusion device mps # LSI-Logic MPT-Fusion 2 device mpr # LSI-Logic MPT-Fusion 3 #device ncr # NCR/Symbios Logic device sym # NCR/Symbios Logic (newer chipsets + those of `ncr') device trm # Tekram DC395U/UW/F DC315U adapters device adv # Advansys SCSI adapters device adw # Advansys wide SCSI adapters device aic # Adaptec 15[012]x SCSI adapters, AIC-6[23]60. device bt # Buslogic/Mylex MultiMaster SCSI adapters device isci # Intel C600 SAS controller device ocs_fc # Emulex FC adapters # ATA/SCSI peripherals device scbus # SCSI bus (required for ATA/SCSI) device ch # SCSI media changers device da # Direct Access (disks) device sa # Sequential Access (tape etc) device cd # CD device pass # Passthrough device (direct ATA/SCSI access) device ses # Enclosure Services (SES and SAF-TE) #device ctl # CAM Target Layer # RAID controllers interfaced to the SCSI subsystem device amr # AMI MegaRAID device arcmsr # Areca SATA II RAID device ciss # Compaq Smart RAID 5* device dpt # DPT Smartcache III, IV - See NOTES for options device hptmv # Highpoint RocketRAID 182x device hptnr # Highpoint DC7280, R750 device hptrr # Highpoint RocketRAID 17xx, 22xx, 23xx, 25xx device hpt27xx # Highpoint RocketRAID 27xx device iir # Intel Integrated RAID device ips # IBM (Adaptec) ServeRAID device mly # Mylex AcceleRAID/eXtremeRAID device twa # 3ware 9000 series PATA/SATA RAID +device smartpqi # Microsemi smartpqi driver device tws # LSI 3ware 9750 SATA+SAS 6Gb/s RAID controller # RAID controllers device aac # Adaptec FSA RAID device aacp # SCSI passthrough for aac (requires CAM) device aacraid # Adaptec by PMC RAID device ida # Compaq Smart RAID device mfi # LSI MegaRAID SAS device mlx # Mylex DAC960 family device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s device pmspcv # PMC-Sierra SAS/SATA Controller driver #XXX pointer/int warnings #device pst # Promise Supertrak SX6000 device twe # 3ware ATA RAID # NVM Express (NVMe) support device nvme # base NVMe driver device nvd # expose NVMe namespaces as disks, depends on nvme # atkbdc0 controls both the keyboard and the PS/2 mouse device atkbdc # AT keyboard controller device atkbd # AT keyboard device psm # PS/2 mouse device kbdmux # keyboard multiplexer device vga # VGA video card driver options VESA # Add support for VESA BIOS Extensions (VBE) device splash # Splash screen and screen saver support # syscons is the default console driver, resembling an SCO console device sc options SC_PIXEL_MODE # add support for the raster text mode # vt is the new video console driver device vt device vt_vga device vt_efifb device agp # support several AGP chipsets # PCCARD (PCMCIA) support # PCMCIA and cardbus bridge support device cbb # cardbus (yenta) bridge device pccard # PC Card (16-bit) bus device cardbus # CardBus (32-bit) bus # Serial (COM) ports device uart # Generic UART driver # Parallel port device ppc device ppbus # Parallel port bus (required) device lpt # Printer device ppi # Parallel port interface device #device vpo # Requires scbus and da device puc # Multi I/O cards and multi-channel UARTs # PCI Ethernet NICs. device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE device de # DEC/Intel DC21x4x (``Tulip'') device em # Intel PRO/1000 Gigabit Ethernet Family device ix # Intel PRO/10GbE PCIE PF Ethernet device ixv # Intel PRO/10GbE PCIE VF Ethernet device ixl # Intel XL710 40Gbe PCIE Ethernet options IXL_IW # Enable iWARP Client Interface in ixl(4) device ixlv # Intel XL710 40Gbe VF PCIE Ethernet device le # AMD Am7900 LANCE and Am79C9xx PCnet device ti # Alteon Networks Tigon I/II gigabit Ethernet device txp # 3Com 3cR990 (``Typhoon'') device vx # 3Com 3c590, 3c595 (``Vortex'') # PCI Ethernet NICs that use the common MII bus controller code. # NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! device miibus # MII bus support device ae # Attansic/Atheros L2 FastEthernet device age # Attansic/Atheros L1 Gigabit Ethernet device alc # Atheros AR8131/AR8132 Ethernet device ale # Atheros AR8121/AR8113/AR8114 Ethernet device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet device bfe # Broadcom BCM440x 10/100 Ethernet device bge # Broadcom BCM570xx Gigabit Ethernet device cas # Sun Cassini/Cassini+ and NS DP83065 Saturn device dc # DEC/Intel 21143 and various workalikes device et # Agere ET1310 10/100/Gigabit Ethernet device fxp # Intel EtherExpress PRO/100B (82557, 82558) device gem # Sun GEM/Sun ERI/Apple GMAC device hme # Sun HME (Happy Meal Ethernet) device jme # JMicron JMC250 Gigabit/JMC260 Fast Ethernet device lge # Level 1 LXT1001 gigabit Ethernet device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet device nfe # nVidia nForce MCP on-board Ethernet device nge # NatSemi DP83820 gigabit Ethernet device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) device stge # Sundance/Tamarack TC9021 gigabit Ethernet device tl # Texas Instruments ThunderLAN device tx # SMC EtherPower II (83c170 ``EPIC'') device vge # VIA VT612x gigabit Ethernet device vr # VIA Rhine, Rhine II device wb # Winbond W89C840F device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') # Wireless NIC cards device wlan # 802.11 support options IEEE80211_DEBUG # enable debug msgs options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's options IEEE80211_SUPPORT_MESH # enable 802.11s draft support device wlan_wep # 802.11 WEP support device wlan_ccmp # 802.11 CCMP support device wlan_tkip # 802.11 TKIP support device wlan_amrr # AMRR transmit rate control algorithm device an # Aironet 4500/4800 802.11 wireless NICs. device ath # Atheros NICs device ath_pci # Atheros pci/cardbus glue device ath_hal # pci/cardbus chip support options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors options AH_AR5416_INTERRUPT_MITIGATION # AR5416 interrupt mitigation options ATH_ENABLE_11N # Enable 802.11n support for AR5416 and later device ath_rate_sample # SampleRate tx rate control for ath #device bwi # Broadcom BCM430x/BCM431x wireless NICs. #device bwn # Broadcom BCM43xx wireless NICs. device ipw # Intel 2100 wireless NICs. device iwi # Intel 2200BG/2225BG/2915ABG wireless NICs. device iwn # Intel 4965/1000/5000/6000 wireless NICs. device malo # Marvell Libertas wireless NICs. device mwl # Marvell 88W8363 802.11n wireless NICs. device ral # Ralink Technology RT2500 wireless NICs. device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs. device wpi # Intel 3945ABG wireless NICs. # Pseudo devices. device loop # Network loopback device random # Entropy device device padlock_rng # VIA Padlock RNG device rdrand_rng # Intel Bull Mountain RNG device ether # Ethernet support device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter # USB support options USB_DEBUG # enable debug msgs device uhci # UHCI PCI->USB interface device ohci # OHCI PCI->USB interface device ehci # EHCI PCI->USB interface (USB 2.0) device xhci # XHCI PCI->USB interface (USB 3.0) device usb # USB Bus (required) device ukbd # Keyboard device umass # Disks/Mass storage - Requires scbus and da # Sound support device sound # Generic sound driver (required) device snd_cmi # CMedia CMI8338/CMI8738 device snd_csa # Crystal Semiconductor CS461x/428x device snd_emu10kx # Creative SoundBlaster Live! and Audigy device snd_es137x # Ensoniq AudioPCI ES137x device snd_hda # Intel High Definition Audio device snd_ich # Intel, NVidia and other ICH AC'97 Audio device snd_via8233 # VIA VT8233x Audio # MMC/SD device mmc # MMC/SD bus device mmcsd # MMC/SD memory card device sdhci # Generic PCI SD Host Controller # VirtIO support device virtio # Generic VirtIO bus (required) device virtio_pci # VirtIO PCI device device vtnet # VirtIO Ethernet device device virtio_blk # VirtIO Block device device virtio_scsi # VirtIO SCSI device device virtio_balloon # VirtIO Memory Balloon device # HyperV drivers and enhancement support device hyperv # HyperV drivers # Xen HVM Guest Optimizations # NOTE: XENHVM depends on xenpci. They must be added or removed together. options XENHVM # Xen HVM kernel infrastructure device xenpci # Xen HVM Hypervisor services driver # VMware support device vmx # VMware VMXNET3 Ethernet # Netmap provides direct access to TX/RX rings on supported NICs device netmap # netmap(4) support # The crypto framework is required by IPSEC device crypto # Required by IPSEC Index: head/sys/conf/NOTES =================================================================== --- head/sys/conf/NOTES (revision 333018) +++ head/sys/conf/NOTES (revision 333019) @@ -1,3021 +1,3028 @@ # $FreeBSD$ # # NOTES -- Lines that can be cut/pasted into kernel and hints configs. # # Lines that begin with 'device', 'options', 'machine', 'ident', 'maxusers', # 'makeoptions', 'hints', etc. go into the kernel configuration that you # run config(8) with. # # Lines that begin with 'hint.' are NOT for config(8), they go into your # hints file. See /boot/device.hints and/or the 'hints' config(8) directive. # # Please use ``make LINT'' to create an old-style LINT file if you want to # do kernel test-builds. # # This file contains machine independent kernel configuration notes. For # machine dependent notes, look in /sys//conf/NOTES. # # # NOTES conventions and style guide: # # Large block comments should begin and end with a line containing only a # comment character. # # To describe a particular object, a block comment (if it exists) should # come first. Next should come device, options, and hints lines in that # order. All device and option lines must be described by a comment that # doesn't just expand the device or option name. Use only a concise # comment on the same line if possible. Very detailed descriptions of # devices and subsystems belong in man pages. # # A space followed by a tab separates 'options' from an option name. Two # spaces followed by a tab separate 'device' from a device name. Comments # after an option or device should use one space after the comment character. # To comment out a negative option that disables code and thus should not be # enabled for LINT builds, precede 'options' with "#!". # # # This is the ``identification'' of the kernel. Usually this should # be the same as the name of your kernel. # ident LINT # # The `maxusers' parameter controls the static sizing of a number of # internal system tables by a formula defined in subr_param.c. # Omitting this parameter or setting it to 0 will cause the system to # auto-size based on physical memory. # maxusers 10 # To statically compile in device wiring instead of /boot/device.hints #hints "LINT.hints" # Default places to look for devices. # Use the following to compile in values accessible to the kernel # through getenv() (or kenv(1) in userland). The format of the file # is 'variable=value', see kenv(1) # #env "LINT.env" # # The `makeoptions' parameter allows variables to be passed to the # generated Makefile in the build area. # # CONF_CFLAGS gives some extra compiler flags that are added to ${CFLAGS} # after most other flags. Here we use it to inhibit use of non-optimal # gcc built-in functions (e.g., memcmp). # # DEBUG happens to be magic. # The following is equivalent to 'config -g KERNELNAME' and creates # 'kernel.debug' compiled with -g debugging as well as a normal # 'kernel'. Use 'make install.debug' to install the debug kernel # but that isn't normally necessary as the debug symbols are not loaded # by the kernel and are not useful there anyway. # # KERNEL can be overridden so that you can change the default name of your # kernel. # # MODULES_OVERRIDE can be used to limit modules built to a specific list. # makeoptions CONF_CFLAGS=-fno-builtin #Don't allow use of memcmp, etc. #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols #makeoptions KERNEL=foo #Build kernel "foo" and install "/foo" # Only build ext2fs module plus those parts of the sound system I need. #makeoptions MODULES_OVERRIDE="ext2fs sound/sound sound/driver/maestro3" makeoptions DESTDIR=/tmp # # FreeBSD processes are subject to certain limits to their consumption # of system resources. See getrlimit(2) for more details. Each # resource limit has two values, a "soft" limit and a "hard" limit. # The soft limits can be modified during normal system operation, but # the hard limits are set at boot time. Their default values are # in sys//include/vmparam.h. There are two ways to change them: # # 1. Set the values at kernel build time. The options below are one # way to allow that limit to grow to 1GB. They can be increased # further by changing the parameters: # # 2. In /boot/loader.conf, set the tunables kern.maxswzone, # kern.maxbcache, kern.maxtsiz, kern.dfldsiz, kern.maxdsiz, # kern.dflssiz, kern.maxssiz and kern.sgrowsiz. # # The options in /boot/loader.conf override anything in the kernel # configuration file. See the function init_param1 in # sys/kern/subr_param.c for more details. # options MAXDSIZ=(1024UL*1024*1024) options MAXSSIZ=(128UL*1024*1024) options DFLDSIZ=(1024UL*1024*1024) # # BLKDEV_IOSIZE sets the default block size used in user block # device I/O. Note that this value will be overridden by the label # when specifying a block device from a label with a non-0 # partition blocksize. The default is PAGE_SIZE. # options BLKDEV_IOSIZE=8192 # # MAXPHYS and DFLTPHYS # # These are the maximal and safe 'raw' I/O block device access sizes. # Reads and writes will be split into MAXPHYS chunks for known good # devices and DFLTPHYS for the rest. Some applications have better # performance with larger raw I/O access sizes. Note that certain VM # parameters are derived from these values and making them too large # can make an unbootable kernel. # # The defaults are 64K and 128K respectively. options DFLTPHYS=(64*1024) options MAXPHYS=(128*1024) # This allows you to actually store this configuration file into # the kernel binary itself. See config(8) for more details. # options INCLUDE_CONFIG_FILE # Include this file in kernel # # Compile-time defaults for various boot parameters # options BOOTVERBOSE=1 options BOOTHOWTO=RB_MULTIPLE options GEOM_BDE # Disk encryption. options GEOM_BSD # BSD disklabels (obsolete, gone in 12) options GEOM_CACHE # Disk cache. options GEOM_CONCAT # Disk concatenation. options GEOM_ELI # Disk encryption. options GEOM_FOX # Redundant path mitigation (obsolete, gone in 12) options GEOM_GATE # Userland services. options GEOM_JOURNAL # Journaling. options GEOM_LABEL # Providers labelization. options GEOM_LINUX_LVM # Linux LVM2 volumes options GEOM_MAP # Map based partitioning options GEOM_MBR # DOS/MBR partitioning (obsolete, gone in 12) options GEOM_MIRROR # Disk mirroring. options GEOM_MULTIPATH # Disk multipath options GEOM_NOP # Test class. options GEOM_PART_APM # Apple partitioning options GEOM_PART_BSD # BSD disklabel options GEOM_PART_BSD64 # BSD disklabel64 options GEOM_PART_EBR # Extended Boot Records options GEOM_PART_EBR_COMPAT # Backward compatible partition names options GEOM_PART_GPT # GPT partitioning options GEOM_PART_LDM # Logical Disk Manager options GEOM_PART_MBR # MBR partitioning options GEOM_PART_VTOC8 # SMI VTOC8 disk label options GEOM_RAID # Soft RAID functionality. options GEOM_RAID3 # RAID3 functionality. options GEOM_SHSEC # Shared secret. options GEOM_STRIPE # Disk striping. options GEOM_SUNLABEL # Sun/Solaris partitioning (obsolete, gone in 12) options GEOM_UZIP # Read-only compressed disks options GEOM_VINUM # Vinum logical volume manager options GEOM_VIRSTOR # Virtual storage. options GEOM_VOL # Volume names from UFS superblock (obsolete, gone in 12) options GEOM_ZERO # Performance testing helper. # # The root device and filesystem type can be compiled in; # this provides a fallback option if the root device cannot # be correctly guessed by the bootstrap code, or an override if # the RB_DFLTROOT flag (-r) is specified when booting the kernel. # options ROOTDEVNAME=\"ufs:da0s2e\" ##################################################################### # Scheduler options: # # Specifying one of SCHED_4BSD or SCHED_ULE is mandatory. These options # select which scheduler is compiled in. # # SCHED_4BSD is the historical, proven, BSD scheduler. It has a global run # queue and no CPU affinity which makes it suboptimal for SMP. It has very # good interactivity and priority selection. # # SCHED_ULE provides significant performance advantages over 4BSD on many # workloads on SMP machines. It supports cpu-affinity, per-cpu runqueues # and scheduler locks. It also has a stronger notion of interactivity # which leads to better responsiveness even on uniprocessor machines. This # is the default scheduler. # # SCHED_STATS is a debugging option which keeps some stats in the sysctl # tree at 'kern.sched.stats' and is useful for debugging scheduling decisions. # options SCHED_4BSD options SCHED_STATS #options SCHED_ULE ##################################################################### # SMP OPTIONS: # # SMP enables building of a Symmetric MultiProcessor Kernel. # Mandatory: options SMP # Symmetric MultiProcessor Kernel # EARLY_AP_STARTUP releases the Application Processors earlier in the # kernel startup process (before devices are probed) rather than at the # end. This is a temporary option for use during the transition from # late to early AP startup. options EARLY_AP_STARTUP # MAXCPU defines the maximum number of CPUs that can boot in the system. # A default value should be already present, for every architecture. options MAXCPU=32 # NUMA enables use of Non-Uniform Memory Access policies in various kernel # subsystems. options NUMA # MAXMEMDOM defines the maximum number of memory domains that can boot in the # system. A default value should already be defined by every architecture. options MAXMEMDOM=2 # ADAPTIVE_MUTEXES changes the behavior of blocking mutexes to spin # if the thread that currently owns the mutex is executing on another # CPU. This behavior is enabled by default, so this option can be used # to disable it. options NO_ADAPTIVE_MUTEXES # ADAPTIVE_RWLOCKS changes the behavior of reader/writer locks to spin # if the thread that currently owns the rwlock is executing on another # CPU. This behavior is enabled by default, so this option can be used # to disable it. options NO_ADAPTIVE_RWLOCKS # ADAPTIVE_SX changes the behavior of sx locks to spin if the thread that # currently owns the sx lock is executing on another CPU. # This behavior is enabled by default, so this option can be used to # disable it. options NO_ADAPTIVE_SX # MUTEX_NOINLINE forces mutex operations to call functions to perform each # operation rather than inlining the simple cases. This can be used to # shrink the size of the kernel text segment. Note that this behavior is # already implied by the INVARIANT_SUPPORT, INVARIANTS, KTR, LOCK_PROFILING, # and WITNESS options. options MUTEX_NOINLINE # RWLOCK_NOINLINE forces rwlock operations to call functions to perform each # operation rather than inlining the simple cases. This can be used to # shrink the size of the kernel text segment. Note that this behavior is # already implied by the INVARIANT_SUPPORT, INVARIANTS, KTR, LOCK_PROFILING, # and WITNESS options. options RWLOCK_NOINLINE # SX_NOINLINE forces sx lock operations to call functions to perform each # operation rather than inlining the simple cases. This can be used to # shrink the size of the kernel text segment. Note that this behavior is # already implied by the INVARIANT_SUPPORT, INVARIANTS, KTR, LOCK_PROFILING, # and WITNESS options. options SX_NOINLINE # SMP Debugging Options: # # CALLOUT_PROFILING enables rudimentary profiling of the callwheel data # structure used as backend in callout(9). # PREEMPTION allows the threads that are in the kernel to be preempted by # higher priority [interrupt] threads. It helps with interactivity # and allows interrupt threads to run sooner rather than waiting. # WARNING! Only tested on amd64 and i386. # FULL_PREEMPTION instructs the kernel to preempt non-realtime kernel # threads. Its sole use is to expose race conditions and other # bugs during development. Enabling this option will reduce # performance and increase the frequency of kernel panics by # design. If you aren't sure that you need it then you don't. # Relies on the PREEMPTION option. DON'T TURN THIS ON. # SLEEPQUEUE_PROFILING enables rudimentary profiling of the hash table # used to hold active sleep queues as well as sleep wait message # frequency. # TURNSTILE_PROFILING enables rudimentary profiling of the hash table # used to hold active lock queues. # UMTX_PROFILING enables rudimentary profiling of the hash table used # to hold active lock queues. # WITNESS enables the witness code which detects deadlocks and cycles # during locking operations. # WITNESS_KDB causes the witness code to drop into the kernel debugger if # a lock hierarchy violation occurs or if locks are held when going to # sleep. # WITNESS_SKIPSPIN disables the witness checks on spin mutexes. options PREEMPTION options FULL_PREEMPTION options WITNESS options WITNESS_KDB options WITNESS_SKIPSPIN # LOCK_PROFILING - Profiling locks. See LOCK_PROFILING(9) for details. options LOCK_PROFILING # Set the number of buffers and the hash size. The hash size MUST be larger # than the number of buffers. Hash size should be prime. options MPROF_BUFFERS="1536" options MPROF_HASH_SIZE="1543" # Profiling for the callout(9) backend. options CALLOUT_PROFILING # Profiling for internal hash tables. options SLEEPQUEUE_PROFILING options TURNSTILE_PROFILING options UMTX_PROFILING ##################################################################### # COMPATIBILITY OPTIONS # # Implement system calls compatible with 4.3BSD and older versions of # FreeBSD. You probably do NOT want to remove this as much current code # still relies on the 4.3 emulation. Note that some architectures that # are supported by FreeBSD do not include support for certain important # aspects of this compatibility option, namely those related to the # signal delivery mechanism. # options COMPAT_43 # Old tty interface. options COMPAT_43TTY # Note that as a general rule, COMPAT_FREEBSD depends on # COMPAT_FREEBSD, COMPAT_FREEBSD, etc. # Enable FreeBSD4 compatibility syscalls options COMPAT_FREEBSD4 # Enable FreeBSD5 compatibility syscalls options COMPAT_FREEBSD5 # Enable FreeBSD6 compatibility syscalls options COMPAT_FREEBSD6 # Enable FreeBSD7 compatibility syscalls options COMPAT_FREEBSD7 # Enable FreeBSD9 compatibility syscalls options COMPAT_FREEBSD9 # Enable FreeBSD10 compatibility syscalls options COMPAT_FREEBSD10 # Enable FreeBSD11 compatibility syscalls options COMPAT_FREEBSD11 # Enable Linux Kernel Programming Interface options COMPAT_LINUXKPI # # These three options provide support for System V Interface # Definition-style interprocess communication, in the form of shared # memory, semaphores, and message queues, respectively. # options SYSVSHM options SYSVSEM options SYSVMSG ##################################################################### # DEBUGGING OPTIONS # # Compile with kernel debugger related code. # options KDB # # Print a stack trace of the current thread on the console for a panic. # options KDB_TRACE # # Don't enter the debugger for a panic. Intended for unattended operation # where you may want to enter the debugger from the console, but still want # the machine to recover from a panic. # options KDB_UNATTENDED # # Enable the ddb debugger backend. # options DDB # # Print the numerical value of symbols in addition to the symbolic # representation. # options DDB_NUMSYM # # Enable the remote gdb debugger backend. # options GDB # # SYSCTL_DEBUG enables a 'sysctl' debug tree that can be used to dump the # contents of the registered sysctl nodes on the console. It is disabled by # default because it generates excessively verbose console output that can # interfere with serial console operation. # options SYSCTL_DEBUG # # Enable textdump by default, this disables kernel core dumps. # options TEXTDUMP_PREFERRED # # Enable extra debug messages while performing textdumps. # options TEXTDUMP_VERBOSE # # NO_SYSCTL_DESCR omits the sysctl node descriptions to save space in the # resulting kernel. options NO_SYSCTL_DESCR # # MALLOC_DEBUG_MAXZONES enables multiple uma zones for malloc(9) # allocations that are smaller than a page. The purpose is to isolate # different malloc types into hash classes, so that any buffer # overruns or use-after-free will usually only affect memory from # malloc types in that hash class. This is purely a debugging tool; # by varying the hash function and tracking which hash class was # corrupted, the intersection of the hash classes from each instance # will point to a single malloc type that is being misused. At this # point inspection or memguard(9) can be used to catch the offending # code. # options MALLOC_DEBUG_MAXZONES=8 # # DEBUG_MEMGUARD builds and enables memguard(9), a replacement allocator # for the kernel used to detect modify-after-free scenarios. See the # memguard(9) man page for more information on usage. # options DEBUG_MEMGUARD # # DEBUG_REDZONE enables buffer underflows and buffer overflows detection for # malloc(9). # options DEBUG_REDZONE # # EARLY_PRINTF enables support for calling a special printf (eprintf) # very early in the kernel (before cn_init() has been called). This # should only be used for debugging purposes early in boot. Normally, # it is not defined. It is commented out here because this feature # isn't generally available. And the required eputc() isn't defined. # #options EARLY_PRINTF # # KTRACE enables the system-call tracing facility ktrace(2). To be more # SMP-friendly, KTRACE uses a worker thread to process most trace events # asynchronously to the thread generating the event. This requires a # pre-allocated store of objects representing trace events. The # KTRACE_REQUEST_POOL option specifies the initial size of this store. # The size of the pool can be adjusted both at boottime and runtime via # the kern.ktrace_request_pool tunable and sysctl. # options KTRACE #kernel tracing options KTRACE_REQUEST_POOL=101 # # KTR is a kernel tracing facility imported from BSD/OS. It is # enabled with the KTR option. KTR_ENTRIES defines the number of # entries in the circular trace buffer; it may be an arbitrary number. # KTR_BOOT_ENTRIES defines the number of entries during the early boot, # before malloc(9) is functional. # KTR_COMPILE defines the mask of events to compile into the kernel as # defined by the KTR_* constants in . KTR_MASK defines the # initial value of the ktr_mask variable which determines at runtime # what events to trace. KTR_CPUMASK determines which CPU's log # events, with bit X corresponding to CPU X. The layout of the string # passed as KTR_CPUMASK must match a series of bitmasks each of them # separated by the "," character (ie: # KTR_CPUMASK=0xAF,0xFFFFFFFFFFFFFFFF). KTR_VERBOSE enables # dumping of KTR events to the console by default. This functionality # can be toggled via the debug.ktr_verbose sysctl and defaults to off # if KTR_VERBOSE is not defined. See ktr(4) and ktrdump(8) for details. # options KTR options KTR_BOOT_ENTRIES=1024 options KTR_ENTRIES=(128*1024) options KTR_COMPILE=(KTR_ALL) options KTR_MASK=KTR_INTR options KTR_CPUMASK=0x3 options KTR_VERBOSE # # ALQ(9) is a facility for the asynchronous queuing of records from the kernel # to a vnode, and is employed by services such as ktr(4) to produce trace # files based on a kernel event stream. Records are written asynchronously # in a worker thread. # options ALQ options KTR_ALQ # # The INVARIANTS option is used in a number of source files to enable # extra sanity checking of internal structures. This support is not # enabled by default because of the extra time it would take to check # for these conditions, which can only occur as a result of # programming errors. # options INVARIANTS # # The INVARIANT_SUPPORT option makes us compile in support for # verifying some of the internal structures. It is a prerequisite for # 'INVARIANTS', as enabling 'INVARIANTS' will make these functions be # called. The intent is that you can set 'INVARIANTS' for single # source files (by changing the source file or specifying it on the # command line) if you have 'INVARIANT_SUPPORT' enabled. Also, if you # wish to build a kernel module with 'INVARIANTS', then adding # 'INVARIANT_SUPPORT' to your kernel will provide all the necessary # infrastructure without the added overhead. # options INVARIANT_SUPPORT # # The DIAGNOSTIC option is used to enable extra debugging information # from some parts of the kernel. As this makes everything more noisy, # it is disabled by default. # options DIAGNOSTIC # # REGRESSION causes optional kernel interfaces necessary only for regression # testing to be enabled. These interfaces may constitute security risks # when enabled, as they permit processes to easily modify aspects of the # run-time environment to reproduce unlikely or unusual (possibly normally # impossible) scenarios. # options REGRESSION # # This option lets some drivers co-exist that can't co-exist in a running # system. This is used to be able to compile all kernel code in one go for # quality assurance purposes (like this file, which the option takes it name # from.) # options COMPILING_LINT # # STACK enables the stack(9) facility, allowing the capture of kernel stack # for the purpose of procinfo(1), etc. stack(9) will also be compiled in # automatically if DDB(4) is compiled into the kernel. # options STACK # # The NUM_CORE_FILES option specifies the limit for the number of core # files generated by a particular process, when the core file format # specifier includes the %I pattern. Since we only have 1 character for # the core count in the format string, meaning the range will be 0-9, the # maximum value allowed for this option is 10. # This core file limit can be adjusted at runtime via the debug.ncores # sysctl. # options NUM_CORE_FILES=5 # # The TSLOG option enables timestamped logging of events, especially # function entries/exits, in order to track the time spent by the kernel. # In particular, this is useful when investigating the early boot process, # before it is possible to use more sophisticated tools like DTrace. # The TSLOGSIZE option controls the size of the (preallocated, fixed # length) buffer used for storing these events (default: 262144 records). # # For security reasons the TSLOG option should not be enabled on systems # used in production. # options TSLOG options TSLOGSIZE=262144 ##################################################################### # PERFORMANCE MONITORING OPTIONS # # The hwpmc driver that allows the use of in-CPU performance monitoring # counters for performance monitoring. The base kernel needs to be configured # with the 'options' line, while the hwpmc device can be either compiled # in or loaded as a loadable kernel module. # # Additional configuration options may be required on specific architectures, # please see hwpmc(4). device hwpmc # Driver (also a loadable module) options HWPMC_DEBUG options HWPMC_HOOKS # Other necessary kernel hooks ##################################################################### # NETWORKING OPTIONS # # Protocol families # options INET #Internet communications protocols options INET6 #IPv6 communications protocols options RATELIMIT # TX rate limiting support options ROUTETABLES=2 # allocated fibs up to 65536. default is 1. # but that would be a bad idea as they are large. options TCP_OFFLOAD # TCP offload support. # In order to enable IPSEC you MUST also add device crypto to # your kernel configuration options IPSEC #IP security (requires device crypto) # Option IPSEC_SUPPORT does not enable IPsec, but makes it possible to # load it as a kernel module. You still MUST add device crypto to your kernel # configuration. options IPSEC_SUPPORT #options IPSEC_DEBUG #debug for IP security # # SMB/CIFS requester # NETSMB enables support for SMB protocol, it requires LIBMCHAIN and LIBICONV # options. options NETSMB #SMB/CIFS requester # mchain library. It can be either loaded as KLD or compiled into kernel options LIBMCHAIN # libalias library, performing NAT options LIBALIAS # # SCTP is a NEW transport protocol defined by # RFC2960 updated by RFC3309 and RFC3758.. and # soon to have a new base RFC and many many more # extensions. This release supports all the extensions # including many drafts (most about to become RFC's). # It is the reference implementation of SCTP # and is quite well tested. # # Note YOU MUST have both INET and INET6 defined. # You don't have to enable V6, but SCTP is # dual stacked and so far we have not torn apart # the V6 and V4.. since an association can span # both a V6 and V4 address at the SAME time :-) # options SCTP # There are bunches of options: # this one turns on all sorts of # nastily printing that you can # do. It's all controlled by a # bit mask (settable by socket opt and # by sysctl). Including will not cause # logging until you set the bits.. but it # can be quite verbose.. so without this # option we don't do any of the tests for # bits and prints.. which makes the code run # faster.. if you are not debugging don't use. options SCTP_DEBUG # # All that options after that turn on specific types of # logging. You can monitor CWND growth, flight size # and all sorts of things. Go look at the code and # see. I have used this to produce interesting # charts and graphs as well :-> # # I have not yet committed the tools to get and print # the logs, I will do that eventually .. before then # if you want them send me an email rrs@freebsd.org # You basically must have ktr(4) enabled for these # and you then set the sysctl to turn on/off various # logging bits. Use ktrdump(8) to pull the log and run # it through a display program.. and graphs and other # things too. # options SCTP_LOCK_LOGGING options SCTP_MBUF_LOGGING options SCTP_MBCNT_LOGGING options SCTP_PACKET_LOGGING options SCTP_LTRACE_CHUNKS options SCTP_LTRACE_ERRORS # altq(9). Enable the base part of the hooks with the ALTQ option. # Individual disciplines must be built into the base system and can not be # loaded as modules at this point. ALTQ requires a stable TSC so if yours is # broken or changes with CPU throttling then you must also have the ALTQ_NOPCC # option. options ALTQ options ALTQ_CBQ # Class Based Queueing options ALTQ_RED # Random Early Detection options ALTQ_RIO # RED In/Out options ALTQ_CODEL # CoDel Active Queueing options ALTQ_HFSC # Hierarchical Packet Scheduler options ALTQ_FAIRQ # Fair Packet Scheduler options ALTQ_CDNR # Traffic conditioner options ALTQ_PRIQ # Priority Queueing options ALTQ_NOPCC # Required if the TSC is unusable options ALTQ_DEBUG # netgraph(4). Enable the base netgraph code with the NETGRAPH option. # Individual node types can be enabled with the corresponding option # listed below; however, this is not strictly necessary as netgraph # will automatically load the corresponding KLD module if the node type # is not already compiled into the kernel. Each type below has a # corresponding man page, e.g., ng_async(8). options NETGRAPH # netgraph(4) system options NETGRAPH_DEBUG # enable extra debugging, this # affects netgraph(4) and nodes # Node types options NETGRAPH_ASYNC options NETGRAPH_ATMLLC options NETGRAPH_ATM_ATMPIF options NETGRAPH_BLUETOOTH # ng_bluetooth(4) options NETGRAPH_BLUETOOTH_BT3C # ng_bt3c(4) options NETGRAPH_BLUETOOTH_HCI # ng_hci(4) options NETGRAPH_BLUETOOTH_L2CAP # ng_l2cap(4) options NETGRAPH_BLUETOOTH_SOCKET # ng_btsocket(4) options NETGRAPH_BLUETOOTH_UBT # ng_ubt(4) options NETGRAPH_BLUETOOTH_UBTBCMFW # ubtbcmfw(4) options NETGRAPH_BPF options NETGRAPH_BRIDGE options NETGRAPH_CAR options NETGRAPH_CISCO options NETGRAPH_DEFLATE options NETGRAPH_DEVICE options NETGRAPH_ECHO options NETGRAPH_EIFACE options NETGRAPH_ETHER options NETGRAPH_FRAME_RELAY options NETGRAPH_GIF options NETGRAPH_GIF_DEMUX options NETGRAPH_HOLE options NETGRAPH_IFACE options NETGRAPH_IP_INPUT options NETGRAPH_IPFW options NETGRAPH_KSOCKET options NETGRAPH_L2TP options NETGRAPH_LMI options NETGRAPH_MPPC_COMPRESSION options NETGRAPH_MPPC_ENCRYPTION options NETGRAPH_NETFLOW options NETGRAPH_NAT options NETGRAPH_ONE2MANY options NETGRAPH_PATCH options NETGRAPH_PIPE options NETGRAPH_PPP options NETGRAPH_PPPOE options NETGRAPH_PPTPGRE options NETGRAPH_PRED1 options NETGRAPH_RFC1490 options NETGRAPH_SOCKET options NETGRAPH_SPLIT options NETGRAPH_SPPP options NETGRAPH_TAG options NETGRAPH_TCPMSS options NETGRAPH_TEE options NETGRAPH_UI options NETGRAPH_VJC options NETGRAPH_VLAN # NgATM - Netgraph ATM options NGATM_ATM options NGATM_ATMBASE options NGATM_SSCOP options NGATM_SSCFU options NGATM_UNI options NGATM_CCATM device mn # Munich32x/Falc54 Nx64kbit/sec cards. # Network stack virtualization. options VIMAGE options VNET_DEBUG # debug for VIMAGE # # Network interfaces: # The `loop' device is MANDATORY when networking is enabled. device loop # The `ether' device provides generic code to handle # Ethernets; it is MANDATORY when an Ethernet device driver is # configured. device ether # The `vlan' device implements the VLAN tagging of Ethernet frames # according to IEEE 802.1Q. device vlan # The `vxlan' device implements the VXLAN encapsulation of Ethernet # frames in UDP packets according to RFC7348. device vxlan # The `wlan' device provides generic code to support 802.11 # drivers, including host AP mode; it is MANDATORY for the wi, # and ath drivers and will eventually be required by all 802.11 drivers. device wlan options IEEE80211_DEBUG #enable debugging msgs options IEEE80211_AMPDU_AGE #age frames in AMPDU reorder q's options IEEE80211_SUPPORT_MESH #enable 802.11s D3.0 support options IEEE80211_SUPPORT_TDMA #enable TDMA support # The `wlan_wep', `wlan_tkip', and `wlan_ccmp' devices provide # support for WEP, TKIP, and AES-CCMP crypto protocols optionally # used with 802.11 devices that depend on the `wlan' module. device wlan_wep device wlan_ccmp device wlan_tkip # The `wlan_xauth' device provides support for external (i.e. user-mode) # authenticators for use with 802.11 drivers that use the `wlan' # module and support 802.1x and/or WPA security protocols. device wlan_xauth # The `wlan_acl' device provides a MAC-based access control mechanism # for use with 802.11 drivers operating in ap mode and using the # `wlan' module. # The 'wlan_amrr' device provides AMRR transmit rate control algorithm device wlan_acl device wlan_amrr # The `sppp' device serves a similar role for certain types # of synchronous PPP links (like `cx', `ar'). device sppp # The `bpf' device enables the Berkeley Packet Filter. Be # aware of the legal and administrative consequences of enabling this # option. DHCP requires bpf. device bpf # The `netmap' device implements memory-mapped access to network # devices from userspace, enabling wire-speed packet capture and # generation even at 10Gbit/s. Requires support in the device # driver. Supported drivers are ixgbe, e1000, re. device netmap # The `disc' device implements a minimal network interface, # which throws away all packets sent and never receives any. It is # included for testing and benchmarking purposes. device disc # The `epair' device implements a virtual back-to-back connected Ethernet # like interface pair. device epair # The `edsc' device implements a minimal Ethernet interface, # which discards all packets sent and receives none. device edsc # The `tap' device is a pty-like virtual Ethernet interface device tap # The `tun' device implements (user-)ppp and nos-tun(8) device tun # The `gif' device implements IPv6 over IP4 tunneling, # IPv4 over IPv6 tunneling, IPv4 over IPv4 tunneling and # IPv6 over IPv6 tunneling. # The `gre' device implements GRE (Generic Routing Encapsulation) tunneling, # as specified in the RFC 2784 and RFC 2890. # The `me' device implements Minimal Encapsulation within IPv4 as # specified in the RFC 2004. # The XBONEHACK option allows the same pair of addresses to be configured on # multiple gif interfaces. device gif device gre device me options XBONEHACK # The `stf' device implements 6to4 encapsulation. device stf # The pf packet filter consists of three devices: # The `pf' device provides /dev/pf and the firewall code itself. # The `pflog' device provides the pflog0 interface which logs packets. # The `pfsync' device provides the pfsync0 interface used for # synchronization of firewall state tables (over the net). device pf device pflog device pfsync # Bridge interface. device if_bridge # Common Address Redundancy Protocol. See carp(4) for more details. device carp # IPsec interface. device enc # Link aggregation interface. device lagg # # Internet family options: # # MROUTING enables the kernel multicast packet forwarder, which works # with mrouted and XORP. # # IPFIREWALL enables support for IP firewall construction, in # conjunction with the `ipfw' program. IPFIREWALL_VERBOSE sends # logged packets to the system logger. IPFIREWALL_VERBOSE_LIMIT # limits the number of times a matching entry can be logged. # # WARNING: IPFIREWALL defaults to a policy of "deny ip from any to any" # and if you do not add other rules during startup to allow access, # YOU WILL LOCK YOURSELF OUT. It is suggested that you set firewall_type=open # in /etc/rc.conf when first enabling this feature, then refining the # firewall rules in /etc/rc.firewall after you've tested that the new kernel # feature works properly. # # IPFIREWALL_DEFAULT_TO_ACCEPT causes the default rule (at boot) to # allow everything. Use with care, if a cracker can crash your # firewall machine, they can get to your protected machines. However, # if you are using it as an as-needed filter for specific problems as # they arise, then this may be for you. Changing the default to 'allow' # means that you won't get stuck if the kernel and /sbin/ipfw binary get # out of sync. # # IPDIVERT enables the divert IP sockets, used by ``ipfw divert''. It # depends on IPFIREWALL if compiled into the kernel. # # IPFIREWALL_NAT adds support for in kernel nat in ipfw, and it requires # LIBALIAS. # # IPFIREWALL_NAT64 adds support for in kernel NAT64 in ipfw. # # IPFIREWALL_NPTV6 adds support for in kernel NPTv6 in ipfw. # # IPFIREWALL_PMOD adds support for protocols modification module. Currently # it supports only TCP MSS modification. # # IPSTEALTH enables code to support stealth forwarding (i.e., forwarding # packets without touching the TTL). This can be useful to hide firewalls # from traceroute and similar tools. # # PF_DEFAULT_TO_DROP causes the default pf(4) rule to deny everything. # # TCPDEBUG enables code which keeps traces of the TCP state machine # for sockets with the SO_DEBUG option set, which can then be examined # using the trpt(8) utility. # # TCPPCAP enables code which keeps the last n packets sent and received # on a TCP socket. # # TCP_BLACKBOX enables enhanced TCP event logging. # # TCP_HHOOK enables the hhook(9) framework hooks for the TCP stack. # # RADIX_MPATH provides support for equal-cost multi-path routing. # options MROUTING # Multicast routing options IPFIREWALL #firewall options IPFIREWALL_VERBOSE #enable logging to syslogd(8) options IPFIREWALL_VERBOSE_LIMIT=100 #limit verbosity options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default options IPFIREWALL_NAT #ipfw kernel nat support options IPFIREWALL_NAT64 #ipfw kernel NAT64 support options IPFIREWALL_NPTV6 #ipfw kernel IPv6 NPT support options IPDIVERT #divert sockets options IPFILTER #ipfilter support options IPFILTER_LOG #ipfilter logging options IPFILTER_LOOKUP #ipfilter pools options IPFILTER_DEFAULT_BLOCK #block all packets by default options IPSTEALTH #support for stealth forwarding options PF_DEFAULT_TO_DROP #drop everything by default options TCPDEBUG options TCPPCAP options TCP_BLACKBOX options TCP_HHOOK options RADIX_MPATH # The MBUF_STRESS_TEST option enables options which create # various random failures / extreme cases related to mbuf # functions. See mbuf(9) for a list of available test cases. # MBUF_PROFILING enables code to profile the mbuf chains # exiting the system (via participating interfaces) and # return a logarithmic histogram of monitored parameters # (e.g. packet size, wasted space, number of mbufs in chain). options MBUF_STRESS_TEST options MBUF_PROFILING # Statically link in accept filters options ACCEPT_FILTER_DATA options ACCEPT_FILTER_DNS options ACCEPT_FILTER_HTTP # TCP_SIGNATURE adds support for RFC 2385 (TCP-MD5) digests. These are # carried in TCP option 19. This option is commonly used to protect # TCP sessions (e.g. BGP) where IPSEC is not available nor desirable. # This is enabled on a per-socket basis using the TCP_MD5SIG socket option. # This requires the use of 'device crypto' and either 'options IPSEC' or # 'options IPSEC_SUPPORT'. options TCP_SIGNATURE #include support for RFC 2385 # DUMMYNET enables the "dummynet" bandwidth limiter. You need IPFIREWALL # as well. See dummynet(4) and ipfw(8) for more info. When you run # DUMMYNET it is advisable to also have at least "options HZ=1000" to achieve # a smooth scheduling of the traffic. options DUMMYNET ##################################################################### # FILESYSTEM OPTIONS # # Only the root filesystem needs to be statically compiled or preloaded # as module; everything else will be automatically loaded at mount # time. Some people still prefer to statically compile other # filesystems as well. # # NB: The UNION filesystem was known to be buggy in the past. It is now # being actively maintained, although there are still some issues being # resolved. # # One of these is mandatory: options FFS #Fast filesystem options NFSCL #Network File System client # The rest are optional: options AUTOFS #Automounter filesystem options CD9660 #ISO 9660 filesystem options FDESCFS #File descriptor filesystem options FUSE #FUSE support module options MSDOSFS #MS DOS File System (FAT, FAT32) options NFSLOCKD #Network Lock Manager options NFSD #Network Filesystem Server options KGSSAPI #Kernel GSSAPI implementation options NULLFS #NULL filesystem options PROCFS #Process filesystem (requires PSEUDOFS) options PSEUDOFS #Pseudo-filesystem framework options PSEUDOFS_TRACE #Debugging support for PSEUDOFS options SMBFS #SMB/CIFS filesystem options TMPFS #Efficient memory filesystem options UDF #Universal Disk Format options UNIONFS #Union filesystem # The xFS_ROOT options REQUIRE the associated ``options xFS'' options NFS_ROOT #NFS usable as root device # Soft updates is a technique for improving filesystem speed and # making abrupt shutdown less risky. # options SOFTUPDATES # Extended attributes allow additional data to be associated with files, # and is used for ACLs, Capabilities, and MAC labels. # See src/sys/ufs/ufs/README.extattr for more information. options UFS_EXTATTR options UFS_EXTATTR_AUTOSTART # Access Control List support for UFS filesystems. The current ACL # implementation requires extended attribute support, UFS_EXTATTR, # for the underlying filesystem. # See src/sys/ufs/ufs/README.acls for more information. options UFS_ACL # Directory hashing improves the speed of operations on very large # directories at the expense of some memory. options UFS_DIRHASH # Gjournal-based UFS journaling support. options UFS_GJOURNAL # Make space in the kernel for a root filesystem on a md device. # Define to the number of kilobytes to reserve for the filesystem. # This is now optional. # If not defined, the root filesystem passed in as the MFS_IMAGE makeoption # will be automatically embedded in the kernel during linking. Its exact size # will be consumed within the kernel. # If defined, the old way of embedding the filesystem in the kernel will be # used. That is to say MD_ROOT_SIZE KB will be allocated in the kernel and # later, the filesystem image passed in as the MFS_IMAGE makeoption will be # dd'd into the reserved space if it fits. options MD_ROOT_SIZE=10 # Make the md device a potential root device, either with preloaded # images of type mfs_root or md_root. options MD_ROOT # Write-protect the md root device so that it may not be mounted writeable. options MD_ROOT_READONLY # Disk quotas are supported when this option is enabled. options QUOTA #enable disk quotas # If you are running a machine just as a fileserver for PC and MAC # users, using SAMBA, you may consider setting this option # and keeping all those users' directories on a filesystem that is # mounted with the suiddir option. This gives new files the same # ownership as the directory (similar to group). It's a security hole # if you let these users run programs, so confine it to file-servers # (but it'll save you lots of headaches in those cases). Root owned # directories are exempt and X bits are cleared. The suid bit must be # set on the directory as well; see chmod(1). PC owners can't see/set # ownerships so they keep getting their toes trodden on. This saves # you all the support calls as the filesystem it's used on will act as # they expect: "It's my dir so it must be my file". # options SUIDDIR # NFS options: options NFS_MINATTRTIMO=3 # VREG attrib cache timeout in sec options NFS_MAXATTRTIMO=60 options NFS_MINDIRATTRTIMO=30 # VDIR attrib cache timeout in sec options NFS_MAXDIRATTRTIMO=60 options NFS_DEBUG # Enable NFS Debugging # # Add support for the EXT2FS filesystem of Linux fame. Be a bit # careful with this - the ext2fs code has a tendency to lag behind # changes and not be exercised very much, so mounting read/write could # be dangerous (and even mounting read only could result in panics.) # options EXT2FS # Cryptographically secure random number generator; /dev/random device random # The system memory devices; /dev/mem, /dev/kmem device mem # The kernel symbol table device; /dev/ksyms device ksyms # Optional character code conversion support with LIBICONV. # Each option requires their base file system and LIBICONV. options CD9660_ICONV options MSDOSFS_ICONV options UDF_ICONV ##################################################################### # POSIX P1003.1B # Real time extensions added in the 1993 POSIX # _KPOSIX_PRIORITY_SCHEDULING: Build in _POSIX_PRIORITY_SCHEDULING options _KPOSIX_PRIORITY_SCHEDULING # p1003_1b_semaphores are very experimental, # user should be ready to assist in debugging if problems arise. options P1003_1B_SEMAPHORES # POSIX message queue options P1003_1B_MQUEUE ##################################################################### # SECURITY POLICY PARAMETERS # Support for BSM audit options AUDIT # Support for Mandatory Access Control (MAC): options MAC options MAC_BIBA options MAC_BSDEXTENDED options MAC_IFOFF options MAC_LOMAC options MAC_MLS options MAC_NONE options MAC_PARTITION options MAC_PORTACL options MAC_SEEOTHERUIDS options MAC_STUB options MAC_TEST # Support for Capsicum options CAPABILITIES # fine-grained rights on file descriptors options CAPABILITY_MODE # sandboxes with no global namespace access ##################################################################### # CLOCK OPTIONS # The granularity of operation is controlled by the kernel option HZ whose # default value (1000 on most architectures) means a granularity of 1ms # (1s/HZ). Historically, the default was 100, but finer granularity is # required for DUMMYNET and other systems on modern hardware. There are # reasonable arguments that HZ should, in fact, be 100 still; consider, # that reducing the granularity too much might cause excessive overhead in # clock interrupt processing, potentially causing ticks to be missed and thus # actually reducing the accuracy of operation. options HZ=100 # Enable support for the kernel PLL to use an external PPS signal, # under supervision of [x]ntpd(8) # More info in ntpd documentation: http://www.eecis.udel.edu/~ntp options PPS_SYNC # Enable support for generic feed-forward clocks in the kernel. # The feed-forward clock support is an alternative to the feedback oriented # ntpd/system clock approach, and is to be used with a feed-forward # synchronization algorithm such as the RADclock: # More info here: http://www.synclab.org/radclock options FFCLOCK ##################################################################### # SCSI DEVICES # SCSI DEVICE CONFIGURATION # The SCSI subsystem consists of the `base' SCSI code, a number of # high-level SCSI device `type' drivers, and the low-level host-adapter # device drivers. The host adapters are listed in the ISA and PCI # device configuration sections below. # # It is possible to wire down your SCSI devices so that a given bus, # target, and LUN always come on line as the same device unit. In # earlier versions the unit numbers were assigned in the order that # the devices were probed on the SCSI bus. This means that if you # removed a disk drive, you may have had to rewrite your /etc/fstab # file, and also that you had to be careful when adding a new disk # as it may have been probed earlier and moved your device configuration # around. (See also option GEOM_VOL for a different solution to this # problem.) # This old behavior is maintained as the default behavior. The unit # assignment begins with the first non-wired down unit for a device # type. For example, if you wire a disk as "da3" then the first # non-wired disk will be assigned da4. # The syntax for wiring down devices is: hint.scbus.0.at="ahc0" hint.scbus.1.at="ahc1" hint.scbus.1.bus="0" hint.scbus.3.at="ahc2" hint.scbus.3.bus="0" hint.scbus.2.at="ahc2" hint.scbus.2.bus="1" hint.da.0.at="scbus0" hint.da.0.target="0" hint.da.0.unit="0" hint.da.1.at="scbus3" hint.da.1.target="1" hint.da.2.at="scbus2" hint.da.2.target="3" hint.sa.1.at="scbus1" hint.sa.1.target="6" # "units" (SCSI logical unit number) that are not specified are # treated as if specified as LUN 0. # All SCSI devices allocate as many units as are required. # The ch driver drives SCSI Media Changer ("jukebox") devices. # # The da driver drives SCSI Direct Access ("disk") and Optical Media # ("WORM") devices. # # The sa driver drives SCSI Sequential Access ("tape") devices. # # The cd driver drives SCSI Read Only Direct Access ("cd") devices. # # The ses driver drives SCSI Environment Services ("ses") and # SAF-TE ("SCSI Accessible Fault-Tolerant Enclosure") devices. # # The pt driver drives SCSI Processor devices. # # The sg driver provides a passthrough API that is compatible with the # Linux SG driver. It will work in conjunction with the COMPAT_LINUX # option to run linux SG apps. It can also stand on its own and provide # source level API compatibility for porting apps to FreeBSD. # # Target Mode support is provided here but also requires that a SIM # (SCSI Host Adapter Driver) provide support as well. # # The targ driver provides target mode support as a Processor type device. # It exists to give the minimal context necessary to respond to Inquiry # commands. There is a sample user application that shows how the rest # of the command support might be done in /usr/share/examples/scsi_target. # # The targbh driver provides target mode support and exists to respond # to incoming commands that do not otherwise have a logical unit assigned # to them. # # The pass driver provides a passthrough API to access the CAM subsystem. device scbus #base SCSI code device ch #SCSI media changers device da #SCSI direct access devices (aka disks) device sa #SCSI tapes device cd #SCSI CD-ROMs device ses #Enclosure Services (SES and SAF-TE) device pt #SCSI processor device targ #SCSI Target Mode Code device targbh #SCSI Target Mode Blackhole Device device pass #CAM passthrough driver device sg #Linux SCSI passthrough device ctl #CAM Target Layer # CAM OPTIONS: # debugging options: # CAMDEBUG Compile in all possible debugging. # CAM_DEBUG_COMPILE Debug levels to compile in. # CAM_DEBUG_FLAGS Debug levels to enable on boot. # CAM_DEBUG_BUS Limit debugging to the given bus. # CAM_DEBUG_TARGET Limit debugging to the given target. # CAM_DEBUG_LUN Limit debugging to the given lun. # CAM_DEBUG_DELAY Delay in us after printing each debug line. # # CAM_MAX_HIGHPOWER: Maximum number of concurrent high power (start unit) cmds # SCSI_NO_SENSE_STRINGS: When defined disables sense descriptions # SCSI_NO_OP_STRINGS: When defined disables opcode descriptions # SCSI_DELAY: The number of MILLISECONDS to freeze the SIM (scsi adapter) # queue after a bus reset, and the number of milliseconds to # freeze the device queue after a bus device reset. This # can be changed at boot and runtime with the # kern.cam.scsi_delay tunable/sysctl. options CAMDEBUG options CAM_DEBUG_COMPILE=-1 options CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_PROBE|CAM_DEBUG_PERIPH) options CAM_DEBUG_BUS=-1 options CAM_DEBUG_TARGET=-1 options CAM_DEBUG_LUN=-1 options CAM_DEBUG_DELAY=1 options CAM_MAX_HIGHPOWER=4 options SCSI_NO_SENSE_STRINGS options SCSI_NO_OP_STRINGS options SCSI_DELAY=5000 # Be pessimistic about Joe SCSI device options CAM_IOSCHED_DYNAMIC options CAM_TEST_FAILURE # Options for the CAM CDROM driver: # CHANGER_MIN_BUSY_SECONDS: Guaranteed minimum time quantum for a changer LUN # CHANGER_MAX_BUSY_SECONDS: Maximum time quantum per changer LUN, only # enforced if there is I/O waiting for another LUN # The compiled in defaults for these variables are 2 and 10 seconds, # respectively. # # These can also be changed on the fly with the following sysctl variables: # kern.cam.cd.changer.min_busy_seconds # kern.cam.cd.changer.max_busy_seconds # options CHANGER_MIN_BUSY_SECONDS=2 options CHANGER_MAX_BUSY_SECONDS=10 # Options for the CAM sequential access driver: # SA_IO_TIMEOUT: Timeout for read/write/wfm operations, in minutes # SA_SPACE_TIMEOUT: Timeout for space operations, in minutes # SA_REWIND_TIMEOUT: Timeout for rewind operations, in minutes # SA_ERASE_TIMEOUT: Timeout for erase operations, in minutes # SA_1FM_AT_EOD: Default to model which only has a default one filemark at EOT. options SA_IO_TIMEOUT=4 options SA_SPACE_TIMEOUT=60 options SA_REWIND_TIMEOUT=(2*60) options SA_ERASE_TIMEOUT=(4*60) options SA_1FM_AT_EOD # Optional timeout for the CAM processor target (pt) device # This is specified in seconds. The default is 60 seconds. options SCSI_PT_DEFAULT_TIMEOUT=60 # Optional enable of doing SES passthrough on other devices (e.g., disks) # # Normally disabled because a lot of newer SCSI disks report themselves # as having SES capabilities, but this can then clot up attempts to build # a topology with the SES device that's on the box these drives are in.... options SES_ENABLE_PASSTHROUGH ##################################################################### # MISCELLANEOUS DEVICES AND OPTIONS device pty #BSD-style compatibility pseudo ttys device nmdm #back-to-back tty devices device md #Memory/malloc disk device snp #Snoop device - to look at pty/vty/etc.. device ccd #Concatenated disk driver device firmware #firmware(9) support # Kernel side iconv library options LIBICONV # Size of the kernel message buffer. Should be N * pagesize. options MSGBUF_SIZE=40960 ##################################################################### # HARDWARE BUS CONFIGURATION # # PCI bus & PCI options: # device pci options PCI_HP # PCI-Express native HotPlug options PCI_IOV # PCI SR-IOV support ##################################################################### # HARDWARE DEVICE CONFIGURATION # For ISA the required hints are listed. # PCI, CardBus, SD/MMC and pccard are self identifying buses, so # no hints are needed. # # Mandatory devices: # # These options are valid for other keyboard drivers as well. options KBD_DISABLE_KEYMAP_LOAD # refuse to load a keymap options KBD_INSTALL_CDEV # install a CDEV entry in /dev device kbdmux # keyboard multiplexer options KBDMUX_DFLT_KEYMAP # specify the built-in keymap makeoptions KBDMUX_DFLT_KEYMAP=it.iso options FB_DEBUG # Frame buffer debugging device splash # Splash screen and screen saver support # Various screen savers. device blank_saver device daemon_saver device dragon_saver device fade_saver device fire_saver device green_saver device logo_saver device rain_saver device snake_saver device star_saver device warp_saver # The syscons console driver (SCO color console compatible). device sc hint.sc.0.at="isa" options MAXCONS=16 # number of virtual consoles options SC_ALT_MOUSE_IMAGE # simplified mouse cursor in text mode options SC_DFLT_FONT # compile font in makeoptions SC_DFLT_FONT=cp850 options SC_DISABLE_KDBKEY # disable `debug' key options SC_DISABLE_REBOOT # disable reboot key sequence options SC_HISTORY_SIZE=200 # number of history buffer lines options SC_MOUSE_CHAR=0x3 # char code for text mode mouse cursor options SC_PIXEL_MODE # add support for the raster text mode # The following options will let you change the default colors of syscons. options SC_NORM_ATTR=(FG_GREEN|BG_BLACK) options SC_NORM_REV_ATTR=(FG_YELLOW|BG_GREEN) options SC_KERNEL_CONS_ATTR=(FG_RED|BG_BLACK) options SC_KERNEL_CONS_REV_ATTR=(FG_BLACK|BG_RED) # The following options will let you change the default behavior of # cut-n-paste feature options SC_CUT_SPACES2TABS # convert leading spaces into tabs options SC_CUT_SEPCHARS=\"x09\" # set of characters that delimit words # (default is single space - \"x20\") # If you have a two button mouse, you may want to add the following option # to use the right button of the mouse to paste text. options SC_TWOBUTTON_MOUSE # You can selectively disable features in syscons. options SC_NO_CUTPASTE options SC_NO_FONT_LOADING options SC_NO_HISTORY options SC_NO_MODE_CHANGE options SC_NO_SYSMOUSE options SC_NO_SUSPEND_VTYSWITCH # `flags' for sc # 0x80 Put the video card in the VESA 800x600 dots, 16 color mode # 0x100 Probe for a keyboard device periodically if one is not present # Enable experimental features of the syscons terminal emulator (teken). options TEKEN_CONS25 # cons25-style terminal emulation options TEKEN_UTF8 # UTF-8 output handling # The vt video console driver. device vt options VT_ALT_TO_ESC_HACK=1 # Prepend ESC sequence to ALT keys options VT_MAXWINDOWS=16 # Number of virtual consoles options VT_TWOBUTTON_MOUSE # Use right mouse button to paste # The following options set the default framebuffer size. options VT_FB_DEFAULT_HEIGHT=480 options VT_FB_DEFAULT_WIDTH=640 # The following options will let you change the default vt terminal colors. options TERMINAL_NORM_ATTR=(FG_GREEN|BG_BLACK) options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK) # # Optional devices: # # # SCSI host adapters: # # adv: All Narrow SCSI bus AdvanSys controllers. # adw: Second Generation AdvanSys controllers including the ADV940UW. # aha: Adaptec 154x/1535/1640 # ahc: Adaptec 274x/284x/2910/293x/294x/394x/3950x/3960x/398X/4944/ # 19160x/29160x, aic7770/aic78xx # ahd: Adaptec 29320/39320 Controllers. # aic: Adaptec 6260/6360, APA-1460 (PC Card) # bt: Most Buslogic controllers: including BT-445, BT-54x, BT-64x, BT-74x, # BT-75x, BT-946, BT-948, BT-956, BT-958, SDC3211B, SDC3211F, SDC3222F # esp: Emulex ESP, NCR 53C9x and QLogic FAS families based controllers # including the AMD Am53C974 (found on devices such as the Tekram # DC-390(T)) and the Sun ESP and FAS families of controllers # isp: Qlogic ISP 1020, 1040 and 1040B PCI SCSI host adapters, # ISP 1240 Dual Ultra SCSI, ISP 1080 and 1280 (Dual) Ultra2, # ISP 12160 Ultra3 SCSI, # Qlogic ISP 2100 and ISP 2200 1Gb Fibre Channel host adapters. # Qlogic ISP 2300 and ISP 2312 2Gb Fibre Channel host adapters. # Qlogic ISP 2322 and ISP 6322 2Gb Fibre Channel host adapters. # ispfw: Firmware module for Qlogic host adapters # mpt: LSI-Logic MPT/Fusion 53c1020 or 53c1030 Ultra4 # or FC9x9 Fibre Channel host adapters. # ncr: NCR 53C810, 53C825 self-contained SCSI host adapters. # sym: Symbios/Logic 53C8XX family of PCI-SCSI I/O processors: # 53C810, 53C810A, 53C815, 53C825, 53C825A, 53C860, 53C875, # 53C876, 53C885, 53C895, 53C895A, 53C896, 53C897, 53C1510D, # 53C1010-33, 53C1010-66. # trm: Tekram DC395U/UW/F DC315U adapters. # # Note that the order is important in order for Buslogic ISA cards to be # probed correctly. # device bt hint.bt.0.at="isa" hint.bt.0.port="0x330" device adv hint.adv.0.at="isa" device adw device aha hint.aha.0.at="isa" device aic hint.aic.0.at="isa" device ahc device ahd device esp device iscsi_initiator device isp hint.isp.0.disable="1" hint.isp.0.role="3" hint.isp.0.prefer_iomap="1" hint.isp.0.prefer_memmap="1" hint.isp.0.fwload_disable="1" hint.isp.0.ignore_nvram="1" hint.isp.0.fullduplex="1" hint.isp.0.topology="lport" hint.isp.0.topology="nport" hint.isp.0.topology="lport-only" hint.isp.0.topology="nport-only" # we can't get u_int64_t types, nor can we get strings if it's got # a leading 0x, hence this silly dodge. hint.isp.0.portwnn="w50000000aaaa0000" hint.isp.0.nodewnn="w50000000aaaa0001" device ispfw device mpt device ncr device sym device trm # The aic7xxx driver will attempt to use memory mapped I/O for all PCI # controllers that have it configured only if this option is set. Unfortunately, # this doesn't work on some motherboards, which prevents it from being the # default. options AHC_ALLOW_MEMIO # Dump the contents of the ahc controller configuration PROM. options AHC_DUMP_EEPROM # Bitmap of units to enable targetmode operations. options AHC_TMODE_ENABLE # Compile in Aic7xxx Debugging code. options AHC_DEBUG # Aic7xxx driver debugging options. See sys/dev/aic7xxx/aic7xxx.h options AHC_DEBUG_OPTS # Print register bitfields in debug output. Adds ~128k to driver # See ahc(4). options AHC_REG_PRETTY_PRINT # Compile in aic79xx debugging code. options AHD_DEBUG # Aic79xx driver debugging options. Adds ~215k to driver. See ahd(4). options AHD_DEBUG_OPTS=0xFFFFFFFF # Print human-readable register definitions when debugging options AHD_REG_PRETTY_PRINT # Bitmap of units to enable targetmode operations. options AHD_TMODE_ENABLE # The adw driver will attempt to use memory mapped I/O for all PCI # controllers that have it configured only if this option is set. options ADW_ALLOW_MEMIO # Options used in dev/iscsi (Software iSCSI stack) # options ISCSI_INITIATOR_DEBUG=9 # Options used in dev/isp/ (Qlogic SCSI/FC driver). # # ISP_TARGET_MODE - enable target mode operation # options ISP_TARGET_MODE=1 # # ISP_DEFAULT_ROLES - default role # none=0 # target=1 # initiator=2 # both=3 (not supported currently) # # ISP_INTERNAL_TARGET (trivial internal disk target, for testing) # options ISP_DEFAULT_ROLES=0 # Options used in dev/sym/ (Symbios SCSI driver). #options SYM_SETUP_LP_PROBE_MAP #-Low Priority Probe Map (bits) # Allows the ncr to take precedence # 1 (1<<0) -> 810a, 860 # 2 (1<<1) -> 825a, 875, 885, 895 # 4 (1<<2) -> 895a, 896, 1510d #options SYM_SETUP_SCSI_DIFF #-HVD support for 825a, 875, 885 # disabled:0 (default), enabled:1 #options SYM_SETUP_PCI_PARITY #-PCI parity checking # disabled:0, enabled:1 (default) #options SYM_SETUP_MAX_LUN #-Number of LUNs supported # default:8, range:[1..64] # The 'dpt' driver provides support for old DPT controllers (http://www.dpt.com/). # These have hardware RAID-{0,1,5} support, and do multi-initiator I/O. # The DPT controllers are commonly re-licensed under other brand-names - # some controllers by Olivetti, Dec, HP, AT&T, SNI, AST, Alphatronic, NEC and # Compaq are actually DPT controllers. # # See src/sys/dev/dpt for debugging and other subtle options. # DPT_MEASURE_PERFORMANCE Enables a set of (semi)invasive metrics. Various # instruments are enabled. The tools in # /usr/sbin/dpt_* assume these to be enabled. # DPT_DEBUG_xxxx These are controllable from sys/dev/dpt/dpt.h # DPT_RESET_HBA Make "reset" actually reset the controller # instead of fudging it. Only enable this if you # are 100% certain you need it. device dpt # DPT options #!CAM# options DPT_MEASURE_PERFORMANCE options DPT_RESET_HBA # # Compaq "CISS" RAID controllers (SmartRAID 5* series) # These controllers have a SCSI-like interface, and require the # CAM infrastructure. # device ciss # # Intel Integrated RAID controllers. # This driver was developed and is maintained by Intel. Contacts # at Intel for this driver are # "Kannanthanam, Boji T" and # "Leubner, Achim" . # device iir # # Mylex AcceleRAID and eXtremeRAID controllers with v6 and later # firmware. These controllers have a SCSI-like interface, and require # the CAM infrastructure. # device mly # # Compaq Smart RAID, Mylex DAC960 and AMI MegaRAID controllers. Only # one entry is needed; the code will find and configure all supported # controllers. # device ida # Compaq Smart RAID device mlx # Mylex DAC960 device amr # AMI MegaRAID device amrp # SCSI Passthrough interface (optional, CAM req.) device mfi # LSI MegaRAID SAS device mfip # LSI MegaRAID SAS passthrough, requires CAM options MFI_DEBUG device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s # +# Microsemi smartpqi controllers. +# These controllers have a SCSI-like interface, and require the +# CAM infrastructure. +# +device smartpqi + +# # 3ware ATA RAID # device twe # 3ware ATA RAID # # Serial ATA host controllers: # # ahci: Advanced Host Controller Interface (AHCI) compatible # mvs: Marvell 88SX50XX/88SX60XX/88SX70XX/SoC controllers # siis: SiliconImage SiI3124/SiI3132/SiI3531 controllers # # These drivers are part of cam(4) subsystem. They supersede less featured # ata(4) subsystem drivers, supporting same hardware. device ahci device mvs device siis # # The 'ATA' driver supports all legacy ATA/ATAPI controllers, including # PC Card devices. You only need one "device ata" for it to find all # PCI and PC Card ATA/ATAPI devices on modern machines. # Alternatively, individual bus and chipset drivers may be chosen by using # the 'atacore' driver then selecting the drivers on a per vendor basis. # For example to build a system which only supports a VIA chipset, # omit 'ata' and include the 'atacore', 'atapci' and 'atavia' drivers. device ata # Modular ATA #device atacore # Core ATA functionality #device atacard # CARDBUS support #device ataisa # ISA bus support #device atapci # PCI bus support; only generic chipset support # PCI ATA chipsets #device ataacard # ACARD #device ataacerlabs # Acer Labs Inc. (ALI) #device ataamd # American Micro Devices (AMD) #device ataati # ATI #device atacenatek # Cenatek #device atacypress # Cypress #device atacyrix # Cyrix #device atahighpoint # HighPoint #device ataintel # Intel #device ataite # Integrated Technology Inc. (ITE) #device atajmicron # JMicron #device atamarvell # Marvell #device atamicron # Micron #device atanational # National #device atanetcell # NetCell #device atanvidia # nVidia #device atapromise # Promise #device ataserverworks # ServerWorks #device atasiliconimage # Silicon Image Inc. (SiI) (formerly CMD) #device atasis # Silicon Integrated Systems Corp.(SiS) #device atavia # VIA Technologies Inc. # # For older non-PCI, non-PnPBIOS systems, these are the hints lines to add: hint.ata.0.at="isa" hint.ata.0.port="0x1f0" hint.ata.0.irq="14" hint.ata.1.at="isa" hint.ata.1.port="0x170" hint.ata.1.irq="15" # # The following options are valid on the ATA driver: # # ATA_REQUEST_TIMEOUT: the number of seconds to wait for an ATA request # before timing out. #options ATA_REQUEST_TIMEOUT=10 # # Standard floppy disk controllers and floppy tapes, supports # the Y-E DATA External FDD (PC Card) # device fdc hint.fdc.0.at="isa" hint.fdc.0.port="0x3F0" hint.fdc.0.irq="6" hint.fdc.0.drq="2" # # FDC_DEBUG enables floppy debugging. Since the debug output is huge, you # gotta turn it actually on by setting the variable fd_debug with DDB, # however. options FDC_DEBUG # # Activate this line if you happen to have an Insight floppy tape. # Probing them proved to be dangerous for people with floppy disks only, # so it's "hidden" behind a flag: #hint.fdc.0.flags="1" # Specify floppy devices hint.fd.0.at="fdc0" hint.fd.0.drive="0" hint.fd.1.at="fdc0" hint.fd.1.drive="1" # # uart: newbusified driver for serial interfaces. It consolidates the sio(4), # sab(4) and zs(4) drivers. # device uart # Options for uart(4) options UART_PPS_ON_CTS # Do time pulse capturing using CTS # instead of DCD. options UART_POLL_FREQ # Set polling rate, used when hw has # no interrupt support (50 Hz default). # The following hint should only be used for pure ISA devices. It is not # needed otherwise. Use of hints is strongly discouraged. hint.uart.0.at="isa" # The following 3 hints are used when the UART is a system device (i.e., a # console or debug port), but only on platforms that don't have any other # means to pass the information to the kernel. The unit number of the hint # is only used to bundle the hints together. There is no relation to the # unit number of the probed UART. hint.uart.0.port="0x3f8" hint.uart.0.flags="0x10" hint.uart.0.baud="115200" # `flags' for serial drivers that support consoles like sio(4) and uart(4): # 0x10 enable console support for this unit. Other console flags # (if applicable) are ignored unless this is set. Enabling # console support does not make the unit the preferred console. # Boot with -h or set boot_serial=YES in the loader. For sio(4) # specifically, the 0x20 flag can also be set (see above). # Currently, at most one unit can have console support; the # first one (in config file order) with this flag set is # preferred. Setting this flag for sio0 gives the old behavior. # 0x80 use this port for serial line gdb support in ddb. Also known # as debug port. # # Options for serial drivers that support consoles: options BREAK_TO_DEBUGGER # A BREAK/DBG on the console goes to # ddb, if available. # Solaris implements a new BREAK which is initiated by a character # sequence CR ~ ^b which is similar to a familiar pattern used on # Sun servers by the Remote Console. There are FreeBSD extensions: # CR ~ ^p requests force panic and CR ~ ^r requests a clean reboot. options ALT_BREAK_TO_DEBUGGER # Serial Communications Controller # Supports the Siemens SAB 82532 and Zilog Z8530 multi-channel # communications controllers. device scc # PCI Universal Communications driver # Supports various multi port PCI I/O cards. device puc # # Network interfaces: # # MII bus support is required for many PCI Ethernet NICs, # namely those which use MII-compliant transceivers or implement # transceiver control interfaces that operate like an MII. Adding # "device miibus" to the kernel config pulls in support for the generic # miibus API, the common support for for bit-bang'ing the MII and all # of the PHY drivers, including a generic one for PHYs that aren't # specifically handled by an individual driver. Support for specific # PHYs may be built by adding "device mii", "device mii_bitbang" if # needed by the NIC driver and then adding the appropriate PHY driver. device mii # Minimal MII support device mii_bitbang # Common module for bit-bang'ing the MII device miibus # MII support w/ bit-bang'ing and all PHYs device acphy # Altima Communications AC101 device amphy # AMD AM79c873 / Davicom DM910{1,2} device atphy # Attansic/Atheros F1 device axphy # Asix Semiconductor AX88x9x device bmtphy # Broadcom BCM5201/BCM5202 and 3Com 3c905C device bnxt # Broadcom NetXtreme-C/NetXtreme-E device brgphy # Broadcom BCM54xx/57xx 1000baseTX device ciphy # Cicada/Vitesse CS/VSC8xxx device e1000phy # Marvell 88E1000 1000/100/10-BT device gentbi # Generic 10-bit 1000BASE-{LX,SX} fiber ifaces device icsphy # ICS ICS1889-1893 device ip1000phy # IC Plus IP1000A/IP1001 device jmphy # JMicron JMP211/JMP202 device lxtphy # Level One LXT-970 device mlphy # Micro Linear 6692 device nsgphy # NatSemi DP8361/DP83865/DP83891 device nsphy # NatSemi DP83840A device nsphyter # NatSemi DP83843/DP83815 device pnaphy # HomePNA device qsphy # Quality Semiconductor QS6612 device rdcphy # RDC Semiconductor R6040 device rgephy # RealTek 8169S/8110S/8211B/8211C device rlphy # RealTek 8139 device rlswitch # RealTek 8305 device smcphy # SMSC LAN91C111 device tdkphy # TDK 89Q2120 device tlphy # Texas Instruments ThunderLAN device truephy # LSI TruePHY device xmphy # XaQti XMAC II # an: Aironet 4500/4800 802.11 wireless adapters. Supports the PCMCIA, # PCI and ISA varieties. # ae: Support for gigabit ethernet adapters based on the Attansic/Atheros # L2 PCI-Express FastEthernet controllers. # age: Support for gigabit ethernet adapters based on the Attansic/Atheros # L1 PCI express gigabit ethernet controllers. # alc: Support for Atheros AR8131/AR8132 PCIe ethernet controllers. # ale: Support for Atheros AR8121/AR8113/AR8114 PCIe ethernet controllers. # ath: Atheros a/b/g WiFi adapters (requires ath_hal and wlan) # bce: Broadcom NetXtreme II (BCM5706/BCM5708) PCI/PCIe Gigabit Ethernet # adapters. # bfe: Broadcom BCM4401 Ethernet adapter. # bge: Support for gigabit ethernet adapters based on the Broadcom # BCM570x family of controllers, including the 3Com 3c996-T, # the Netgear GA302T, the SysKonnect SK-9D21 and SK-9D41, and # the embedded gigE NICs on Dell PowerEdge 2550 servers. # bnxt: Broadcom NetXtreme-C and NetXtreme-E PCIe 10/25/50G Ethernet adapters. # bxe: Broadcom NetXtreme II (BCM5771X/BCM578XX) PCIe 10Gb Ethernet # adapters. # bwi: Broadcom BCM430* and BCM431* family of wireless adapters. # bwn: Broadcom BCM43xx family of wireless adapters. # cas: Sun Cassini/Cassini+ and National Semiconductor DP83065 Saturn # cxgb: Chelsio T3 based 1GbE/10GbE PCIe Ethernet adapters. # cxgbe:Chelsio T4, T5, and T6-based 1/10/25/40/100GbE PCIe Ethernet # adapters. # cxgbev: Chelsio T4, T5, and T6-based PCIe Virtual Functions. # dc: Support for PCI fast ethernet adapters based on the DEC/Intel 21143 # and various workalikes including: # the ADMtek AL981 Comet and AN985 Centaur, the ASIX Electronics # AX88140A and AX88141, the Davicom DM9100 and DM9102, the Lite-On # 82c168 and 82c169 PNIC, the Lite-On/Macronix LC82C115 PNIC II # and the Macronix 98713/98713A/98715/98715A/98725 PMAC. This driver # replaces the old al, ax, dm, pn and mx drivers. List of brands: # Digital DE500-BA, Kingston KNE100TX, D-Link DFE-570TX, SOHOware SFA110, # SVEC PN102-TX, CNet Pro110B, 120A, and 120B, Compex RL100-TX, # LinkSys LNE100TX, LNE100TX V2.0, Jaton XpressNet, Alfa Inc GFC2204, # KNE110TX. # de: Digital Equipment DC21040 # em: Intel Pro/1000 Gigabit Ethernet 82542, 82543, 82544 based adapters. # ep: 3Com 3C509, 3C529, 3C556, 3C562D, 3C563D, 3C572, 3C574X, 3C579, 3C589 # and PC Card devices using these chipsets. # ex: Intel EtherExpress Pro/10 and other i82595-based adapters, # Olicom Ethernet PC Card devices. # fe: Fujitsu MB86960A/MB86965A Ethernet # fxp: Intel EtherExpress Pro/100B # (hint of prefer_iomap can be done to prefer I/O instead of Mem mapping) # gem: Apple GMAC/Sun ERI/Sun GEM # hme: Sun HME (Happy Meal Ethernet) # jme: JMicron JMC260 Fast Ethernet/JMC250 Gigabit Ethernet based adapters. # le: AMD Am7900 LANCE and Am79C9xx PCnet # lge: Support for PCI gigabit ethernet adapters based on the Level 1 # LXT1001 NetCellerator chipset. This includes the D-Link DGE-500SX, # SMC TigerCard 1000 (SMC9462SX), and some Addtron cards. # lio: Support for Cavium 23XX Ethernet adapters # malo: Marvell Libertas wireless NICs. # mwl: Marvell 88W8363 802.11n wireless NICs. # Requires the mwl firmware module # mwlfw: Marvell 88W8363 firmware # msk: Support for gigabit ethernet adapters based on the Marvell/SysKonnect # Yukon II Gigabit controllers, including 88E8021, 88E8022, 88E8061, # 88E8062, 88E8035, 88E8036, 88E8038, 88E8050, 88E8052, 88E8053, # 88E8055, 88E8056 and D-Link 560T/550SX. # lmc: Support for the LMC/SBE wide-area network interface cards. # mlx5: Mellanox ConnectX-4 and ConnectX-4 LX IB and Eth shared code module. # mlx5en:Mellanox ConnectX-4 and ConnectX-4 LX PCIe Ethernet adapters. # my: Myson Fast Ethernet (MTD80X, MTD89X) # nge: Support for PCI gigabit ethernet adapters based on the National # Semiconductor DP83820 and DP83821 chipset. This includes the # SMC EZ Card 1000 (SMC9462TX), D-Link DGE-500T, Asante FriendlyNet # GigaNIX 1000TA and 1000TPC, the Addtron AEG320T, the Surecom # EP-320G-TX and the Netgear GA622T. # oce: Emulex 10 Gbit adapters (OneConnect Ethernet) # pcn: Support for PCI fast ethernet adapters based on the AMD Am79c97x # PCnet-FAST, PCnet-FAST+, PCnet-FAST III, PCnet-PRO and PCnet-Home # chipsets. These can also be handled by the le(4) driver if the # pcn(4) driver is left out of the kernel. The le(4) driver does not # support the additional features like the MII bus and burst mode of # the PCnet-FAST and greater chipsets though. # ral: Ralink Technology IEEE 802.11 wireless adapter # re: RealTek 8139C+/8169/816xS/811xS/8101E PCI/PCIe Ethernet adapter # rl: Support for PCI fast ethernet adapters based on the RealTek 8129/8139 # chipset. Note that the RealTek driver defaults to using programmed # I/O to do register accesses because memory mapped mode seems to cause # severe lockups on SMP hardware. This driver also supports the # Accton EN1207D `Cheetah' adapter, which uses a chip called # the MPX 5030/5038, which is either a RealTek in disguise or a # RealTek workalike. Note that the D-Link DFE-530TX+ uses the RealTek # chipset and is supported by this driver, not the 'vr' driver. # rtwn: RealTek wireless adapters. # rtwnfw: RealTek wireless firmware. # sf: Support for Adaptec Duralink PCI fast ethernet adapters based on the # Adaptec AIC-6915 "starfire" controller. # This includes dual and quad port cards, as well as one 100baseFX card. # Most of these are 64-bit PCI devices, except for one single port # card which is 32-bit. # sge: Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet adapter # sis: Support for NICs based on the Silicon Integrated Systems SiS 900, # SiS 7016 and NS DP83815 PCI fast ethernet controller chips. # sk: Support for the SysKonnect SK-984x series PCI gigabit ethernet NICs. # This includes the SK-9841 and SK-9842 single port cards (single mode # and multimode fiber) and the SK-9843 and SK-9844 dual port cards # (also single mode and multimode). # The driver will autodetect the number of ports on the card and # attach each one as a separate network interface. # sn: Support for ISA and PC Card Ethernet devices using the # SMC91C90/92/94/95 chips. # ste: Sundance Technologies ST201 PCI fast ethernet controller, includes # the D-Link DFE-550TX. # stge: Support for gigabit ethernet adapters based on the Sundance/Tamarack # TC9021 family of controllers, including the Sundance ST2021/ST2023, # the Sundance/Tamarack TC9021, the D-Link DL-4000 and ASUS NX1101. # ti: Support for PCI gigabit ethernet NICs based on the Alteon Networks # Tigon 1 and Tigon 2 chipsets. This includes the Alteon AceNIC, the # 3Com 3c985, the Netgear GA620 and various others. Note that you will # probably want to bump up kern.ipc.nmbclusters a lot to use this driver. # tl: Support for the Texas Instruments TNETE100 series 'ThunderLAN' # cards and integrated ethernet controllers. This includes several # Compaq Netelligent 10/100 cards and the built-in ethernet controllers # in several Compaq Prosignia, Proliant and Deskpro systems. It also # supports several Olicom 10Mbps and 10/100 boards. # tx: SMC 9432 TX, BTX and FTX cards. (SMC EtherPower II series) # txp: Support for 3Com 3cR990 cards with the "Typhoon" chipset # vr: Support for various fast ethernet adapters based on the VIA # Technologies VT3043 `Rhine I' and VT86C100A `Rhine II' chips, # including the D-Link DFE520TX and D-Link DFE530TX (see 'rl' for # DFE530TX+), the Hawking Technologies PN102TX, and the AOpen/Acer ALN-320. # vte: DM&P Vortex86 RDC R6040 Fast Ethernet # vx: 3Com 3C590 and 3C595 # wb: Support for fast ethernet adapters based on the Winbond W89C840F chip. # Note: this is not the same as the Winbond W89C940F, which is a # NE2000 clone. # wi: Lucent WaveLAN/IEEE 802.11 PCMCIA adapters. Note: this supports both # the PCMCIA and ISA cards: the ISA card is really a PCMCIA to ISA # bridge with a PCMCIA adapter plugged into it. # xe: Xircom/Intel EtherExpress Pro100/16 PC Card ethernet controller, # Accton Fast EtherCard-16, Compaq Netelligent 10/100 PC Card, # Toshiba 10/100 Ethernet PC Card, Xircom 16-bit Ethernet + Modem 56 # xl: Support for the 3Com 3c900, 3c905, 3c905B and 3c905C (Fast) # Etherlink XL cards and integrated controllers. This includes the # integrated 3c905B-TX chips in certain Dell Optiplex and Dell # Precision desktop machines and the integrated 3c905-TX chips # in Dell Latitude laptop docking stations. # Also supported: 3Com 3c980(C)-TX, 3Com 3cSOHO100-TX, 3Com 3c450-TX # Order for ISA devices is important here device ep device ex device fe hint.fe.0.at="isa" hint.fe.0.port="0x300" device sn hint.sn.0.at="isa" hint.sn.0.port="0x300" hint.sn.0.irq="10" device an device wi device xe # PCI Ethernet NICs that use the common MII bus controller code. device ae # Attansic/Atheros L2 FastEthernet device age # Attansic/Atheros L1 Gigabit Ethernet device alc # Atheros AR8131/AR8132 Ethernet device ale # Atheros AR8121/AR8113/AR8114 Ethernet device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet device bfe # Broadcom BCM440x 10/100 Ethernet device bge # Broadcom BCM570xx Gigabit Ethernet device cas # Sun Cassini/Cassini+ and NS DP83065 Saturn device dc # DEC/Intel 21143 and various workalikes device et # Agere ET1310 10/100/Gigabit Ethernet device fxp # Intel EtherExpress PRO/100B (82557, 82558) hint.fxp.0.prefer_iomap="0" device gem # Apple GMAC/Sun ERI/Sun GEM device hme # Sun HME (Happy Meal Ethernet) device jme # JMicron JMC250 Gigabit/JMC260 Fast Ethernet device lge # Level 1 LXT1001 gigabit Ethernet device mlx5 # Shared code module between IB and Ethernet device mlx5en # Mellanox ConnectX-4 and ConnectX-4 LX device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet device my # Myson Fast Ethernet (MTD80X, MTD89X) device nge # NatSemi DP83820 gigabit Ethernet device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device pcn # AMD Am79C97x PCI 10/100 NICs device sf # Adaptec AIC-6915 (``Starfire'') device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) device stge # Sundance/Tamarack TC9021 gigabit Ethernet device tl # Texas Instruments ThunderLAN device tx # SMC EtherPower II (83c170 ``EPIC'') device vr # VIA Rhine, Rhine II device vte # DM&P Vortex86 RDC R6040 Fast Ethernet device wb # Winbond W89C840F device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') # PCI Ethernet NICs. device cxgb # Chelsio T3 10 Gigabit Ethernet device cxgb_t3fw # Chelsio T3 10 Gigabit Ethernet firmware device cxgbe # Chelsio T4-T6 1/10/25/40/100 Gigabit Ethernet device cxgbev # Chelsio T4-T6 Virtual Functions device de # DEC/Intel DC21x4x (``Tulip'') device em # Intel Pro/1000 Gigabit Ethernet device ixgb # Intel Pro/10Gbe PCI-X Ethernet device ix # Intel Pro/10Gbe PCIE Ethernet device ixv # Intel Pro/10Gbe PCIE Ethernet VF device le # AMD Am7900 LANCE and Am79C9xx PCnet device mxge # Myricom Myri-10G 10GbE NIC device nxge # Neterion Xframe 10GbE Server/Storage Adapter device oce # Emulex 10 GbE (OneConnect Ethernet) device ti # Alteon Networks Tigon I/II gigabit Ethernet device txp # 3Com 3cR990 (``Typhoon'') device vx # 3Com 3c590, 3c595 (``Vortex'') device vxge # Exar/Neterion XFrame 3100 10GbE # PCI WAN adapters. device lmc # PCI IEEE 802.11 Wireless NICs device ath # Atheros pci/cardbus NIC's device ath_hal # pci/cardbus chip support #device ath_ar5210 # AR5210 chips #device ath_ar5211 # AR5211 chips #device ath_ar5212 # AR5212 chips #device ath_rf2413 #device ath_rf2417 #device ath_rf2425 #device ath_rf5111 #device ath_rf5112 #device ath_rf5413 #device ath_ar5416 # AR5416 chips options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors # All of the AR5212 parts have a problem when paired with the AR71xx # CPUS. These parts have a bug that triggers a fatal bus error on the AR71xx # only. Details of the exact nature of the bug are sketchy, but some can be # found at https://forum.openwrt.org/viewtopic.php?pid=70060 on pages 4, 5 and # 6. This option enables this workaround. There is a performance penalty # for this work around, but without it things don't work at all. The DMA # from the card usually bursts 128 bytes, but on the affected CPUs, only # 4 are safe. options AH_RXCFG_SDMAMW_4BYTES #device ath_ar9160 # AR9160 chips #device ath_ar9280 # AR9280 chips #device ath_ar9285 # AR9285 chips device ath_rate_sample # SampleRate tx rate control for ath device bwi # Broadcom BCM430* BCM431* device bwn # Broadcom BCM43xx device malo # Marvell Libertas wireless NICs. device mwl # Marvell 88W8363 802.11n wireless NICs. device mwlfw device ral # Ralink Technology RT2500 wireless NICs. device rtwn # Realtek wireless NICs device rtwnfw # Use sf_buf(9) interface for jumbo buffers on ti(4) controllers. #options TI_SF_BUF_JUMBO # Turn on the header splitting option for the ti(4) driver firmware. This # only works for Tigon II chips, and has no effect for Tigon I chips. # This option requires the TI_SF_BUF_JUMBO option above. #options TI_JUMBO_HDRSPLIT # These two options allow manipulating the mbuf cluster size and mbuf size, # respectively. Be very careful with NIC driver modules when changing # these from their default values, because that can potentially cause a # mismatch between the mbuf size assumed by the kernel and the mbuf size # assumed by a module. The only driver that currently has the ability to # detect a mismatch is ti(4). options MCLSHIFT=12 # mbuf cluster shift in bits, 12 == 4KB options MSIZE=512 # mbuf size in bytes # # Sound drivers # # sound: The generic sound driver. # device sound # # snd_*: Device-specific drivers. # # The flags of the device tell the device a bit more info about the # device that normally is obtained through the PnP interface. # bit 2..0 secondary DMA channel; # bit 4 set if the board uses two dma channels; # bit 15..8 board type, overrides autodetection; leave it # zero if don't know what to put in (and you don't, # since this is unsupported at the moment...). # # snd_ad1816: Analog Devices AD1816 ISA PnP/non-PnP. # snd_als4000: Avance Logic ALS4000 PCI. # snd_atiixp: ATI IXP 200/300/400 PCI. # snd_audiocs: Crystal Semiconductor CS4231 SBus/EBus. Only # for sparc64. # snd_cmi: CMedia CMI8338/CMI8738 PCI. # snd_cs4281: Crystal Semiconductor CS4281 PCI. # snd_csa: Crystal Semiconductor CS461x/428x PCI. (except # 4281) # snd_ds1: Yamaha DS-1 PCI. # snd_emu10k1: Creative EMU10K1 PCI and EMU10K2 (Audigy) PCI. # snd_emu10kx: Creative SoundBlaster Live! and Audigy # snd_envy24: VIA Envy24 and compatible, needs snd_spicds. # snd_envy24ht: VIA Envy24HT and compatible, needs snd_spicds. # snd_es137x: Ensoniq AudioPCI ES137x PCI. # snd_ess: Ensoniq ESS ISA PnP/non-PnP, to be used in # conjunction with snd_sbc. # snd_fm801: Forte Media FM801 PCI. # snd_gusc: Gravis UltraSound ISA PnP/non-PnP. # snd_hda: Intel High Definition Audio (Controller) and # compatible. # snd_hdspe: RME HDSPe AIO and RayDAT. # snd_ich: Intel ICH AC'97 and some more audio controllers # embedded in a chipset, for example nVidia # nForce controllers. # snd_maestro: ESS Technology Maestro-1/2x PCI. # snd_maestro3: ESS Technology Maestro-3/Allegro PCI. # snd_mss: Microsoft Sound System ISA PnP/non-PnP. # snd_neomagic: Neomagic 256 AV/ZX PCI. # snd_sb16: Creative SoundBlaster16, to be used in # conjunction with snd_sbc. # snd_sb8: Creative SoundBlaster (pre-16), to be used in # conjunction with snd_sbc. # snd_sbc: Creative SoundBlaster ISA PnP/non-PnP. # Supports ESS and Avance ISA chips as well. # snd_solo: ESS Solo-1x PCI. # snd_spicds: SPI codec driver, needed by Envy24/Envy24HT drivers. # snd_t4dwave: Trident 4DWave DX/NX PCI, Sis 7018 PCI and Acer Labs # M5451 PCI. # snd_uaudio: USB audio. # snd_via8233: VIA VT8233x PCI. # snd_via82c686: VIA VT82C686A PCI. # snd_vibes: S3 Sonicvibes PCI. device snd_ad1816 device snd_als4000 device snd_atiixp #device snd_audiocs device snd_cmi device snd_cs4281 device snd_csa device snd_ds1 device snd_emu10k1 device snd_emu10kx device snd_envy24 device snd_envy24ht device snd_es137x device snd_ess device snd_fm801 device snd_gusc device snd_hda device snd_hdspe device snd_ich device snd_maestro device snd_maestro3 device snd_mss device snd_neomagic device snd_sb16 device snd_sb8 device snd_sbc device snd_solo device snd_spicds device snd_t4dwave device snd_uaudio device snd_via8233 device snd_via82c686 device snd_vibes # For non-PnP sound cards: hint.pcm.0.at="isa" hint.pcm.0.irq="10" hint.pcm.0.drq="1" hint.pcm.0.flags="0x0" hint.sbc.0.at="isa" hint.sbc.0.port="0x220" hint.sbc.0.irq="5" hint.sbc.0.drq="1" hint.sbc.0.flags="0x15" hint.gusc.0.at="isa" hint.gusc.0.port="0x220" hint.gusc.0.irq="5" hint.gusc.0.drq="1" hint.gusc.0.flags="0x13" # # Following options are intended for debugging/testing purposes: # # SND_DEBUG Enable extra debugging code that includes # sanity checking and possible increase of # verbosity. # # SND_DIAGNOSTIC Similar in a spirit of INVARIANTS/DIAGNOSTIC, # zero tolerance against inconsistencies. # # SND_FEEDER_MULTIFORMAT By default, only 16/32 bit feeders are compiled # in. This options enable most feeder converters # except for 8bit. WARNING: May bloat the kernel. # # SND_FEEDER_FULL_MULTIFORMAT Ditto, but includes 8bit feeders as well. # # SND_FEEDER_RATE_HP (feeder_rate) High precision 64bit arithmetic # as much as possible (the default trying to # avoid it). Possible slowdown. # # SND_PCM_64 (Only applicable for i386/32bit arch) # Process 32bit samples through 64bit # integer/arithmetic. Slight increase of dynamic # range at a cost of possible slowdown. # # SND_OLDSTEREO Only 2 channels are allowed, effectively # disabling multichannel processing. # options SND_DEBUG options SND_DIAGNOSTIC options SND_FEEDER_MULTIFORMAT options SND_FEEDER_FULL_MULTIFORMAT options SND_FEEDER_RATE_HP options SND_PCM_64 options SND_OLDSTEREO # # Miscellaneous hardware: # # bktr: Brooktree bt848/848a/849a/878/879 video capture and TV Tuner board # joy: joystick (including IO DATA PCJOY PC Card joystick) # cmx: OmniKey CardMan 4040 pccard smartcard reader device joy # PnP aware, hints for non-PnP only hint.joy.0.at="isa" hint.joy.0.port="0x201" device cmx # # The 'bktr' device is a PCI video capture device using the Brooktree # bt848/bt848a/bt849a/bt878/bt879 chipset. When used with a TV Tuner it forms a # TV card, e.g. Miro PC/TV, Hauppauge WinCast/TV WinTV, VideoLogic Captivator, # Intel Smart Video III, AverMedia, IMS Turbo, FlyVideo. # # options OVERRIDE_CARD=xxx # options OVERRIDE_TUNER=xxx # options OVERRIDE_MSP=1 # options OVERRIDE_DBX=1 # These options can be used to override the auto detection # The current values for xxx are found in src/sys/dev/bktr/bktr_card.h # Using sysctl(8) run-time overrides on a per-card basis can be made # # options BROOKTREE_SYSTEM_DEFAULT=BROOKTREE_PAL # or # options BROOKTREE_SYSTEM_DEFAULT=BROOKTREE_NTSC # Specifies the default video capture mode. # This is required for Dual Crystal (28&35MHz) boards where PAL is used # to prevent hangs during initialization, e.g. VideoLogic Captivator PCI. # # options BKTR_USE_PLL # This is required for PAL or SECAM boards with a 28MHz crystal and no 35MHz # crystal, e.g. some new Bt878 cards. # # options BKTR_GPIO_ACCESS # This enables IOCTLs which give user level access to the GPIO port. # # options BKTR_NO_MSP_RESET # Prevents the MSP34xx reset. Good if you initialize the MSP in another OS first # # options BKTR_430_FX_MODE # Switch Bt878/879 cards into Intel 430FX chipset compatibility mode. # # options BKTR_SIS_VIA_MODE # Switch Bt878/879 cards into SIS/VIA chipset compatibility mode which is # needed for some old SiS and VIA chipset motherboards. # This also allows Bt878/879 chips to work on old OPTi (<1997) chipset # motherboards and motherboards with bad or incomplete PCI 2.1 support. # As a rough guess, old = before 1998 # # options BKTR_NEW_MSP34XX_DRIVER # Use new, more complete initialization scheme for the msp34* soundchip. # Should fix stereo autodetection if the old driver does only output # mono sound. # # options BKTR_USE_FREEBSD_SMBUS # Compile with FreeBSD SMBus implementation # # Brooktree driver has been ported to the new I2C framework. Thus, # you'll need to have the following 3 lines in the kernel config. # device smbus # device iicbus # device iicbb # device iicsmb # The iic and smb devices are only needed if you want to control other # I2C slaves connected to the external connector of some cards. # device bktr # # PC Card/PCMCIA and Cardbus # # cbb: pci/cardbus bridge implementing YENTA interface # pccard: pccard slots # cardbus: cardbus slots device cbb device pccard device cardbus # # MMC/SD # # mmc MMC/SD bus # mmcsd MMC/SD memory card # sdhci Generic PCI SD Host Controller # device mmc device mmcsd device sdhci # # SMB bus # # System Management Bus support is provided by the 'smbus' device. # Access to the SMBus device is via the 'smb' device (/dev/smb*), # which is a child of the 'smbus' device. # # Supported devices: # smb standard I/O through /dev/smb* # # Supported SMB interfaces: # iicsmb I2C to SMB bridge with any iicbus interface # bktr brooktree848 I2C hardware interface # intpm Intel PIIX4 (82371AB, 82443MX) Power Management Unit # alpm Acer Aladdin-IV/V/Pro2 Power Management Unit # ichsmb Intel ICH SMBus controller chips (82801AA, 82801AB, 82801BA) # viapm VIA VT82C586B/596B/686A and VT8233 Power Management Unit # amdpm AMD 756 Power Management Unit # amdsmb AMD 8111 SMBus 2.0 Controller # nfpm NVIDIA nForce Power Management Unit # nfsmb NVIDIA nForce2/3/4 MCP SMBus 2.0 Controller # ismt Intel SMBus 2.0 controller chips (on Atom S1200, C2000) # device smbus # Bus support, required for smb below. device intpm device alpm device ichsmb device viapm device amdpm device amdsmb device nfpm device nfsmb device ismt device smb # SMBus peripheral devices # # jedec_dimm Asset and temperature reporting for DDR3 and DDR4 DIMMs # jedec_ts Temperature Sensor compliant with JEDEC Standard 21-C # device jedec_dimm device jedec_ts # I2C Bus # # Philips i2c bus support is provided by the `iicbus' device. # # Supported devices: # ic i2c network interface # iic i2c standard io # iicsmb i2c to smb bridge. Allow i2c i/o with smb commands. # iicoc simple polling driver for OpenCores I2C controller # # Supported interfaces: # bktr brooktree848 I2C software interface # # Other: # iicbb generic I2C bit-banging code (needed by lpbb, bktr) # device iicbus # Bus support, required for ic/iic/iicsmb below. device iicbb device ic device iic device iicsmb # smb over i2c bridge device iicoc # OpenCores I2C controller support # I2C peripheral devices # device ds1307 # Dallas DS1307 RTC and compatible device ds13rtc # All Dallas/Maxim ds13xx chips device ds1672 # Dallas DS1672 RTC device ds3231 # Dallas DS3231 RTC + temperature device icee # AT24Cxxx and compatible EEPROMs device lm75 # LM75 compatible temperature sensor device nxprtc # NXP RTCs: PCA/PFC212x PCA/PCF85xx device s35390a # Seiko Instruments S-35390A RTC # Parallel-Port Bus # # Parallel port bus support is provided by the `ppbus' device. # Multiple devices may be attached to the parallel port, devices # are automatically probed and attached when found. # # Supported devices: # vpo Iomega Zip Drive # Requires SCSI disk support ('scbus' and 'da'), best # performance is achieved with ports in EPP 1.9 mode. # lpt Parallel Printer # plip Parallel network interface # ppi General-purpose I/O ("Geek Port") + IEEE1284 I/O # pps Pulse per second Timing Interface # lpbb Philips official parallel port I2C bit-banging interface # pcfclock Parallel port clock driver. # # Supported interfaces: # ppc ISA-bus parallel port interfaces. # options PPC_PROBE_CHIPSET # Enable chipset specific detection # (see flags in ppc(4)) options DEBUG_1284 # IEEE1284 signaling protocol debug options PERIPH_1284 # Makes your computer act as an IEEE1284 # compliant peripheral options DONTPROBE_1284 # Avoid boot detection of PnP parallel devices options VP0_DEBUG # ZIP/ZIP+ debug options LPT_DEBUG # Printer driver debug options PPC_DEBUG # Parallel chipset level debug options PLIP_DEBUG # Parallel network IP interface debug options PCFCLOCK_VERBOSE # Verbose pcfclock driver options PCFCLOCK_MAX_RETRIES=5 # Maximum read tries (default 10) device ppc hint.ppc.0.at="isa" hint.ppc.0.irq="7" device ppbus device vpo device lpt device plip device ppi device pps device lpbb device pcfclock # # Etherswitch framework and drivers # # etherswitch The etherswitch(4) framework # miiproxy Proxy device for miibus(4) functionality # # Switch hardware support: # arswitch Atheros switches # ip17x IC+ 17x family switches # rtl8366r Realtek RTL8366 switches # ukswitch Multi-PHY switches # device etherswitch device miiproxy device arswitch device ip17x device rtl8366rb device ukswitch # Kernel BOOTP support options BOOTP # Use BOOTP to obtain IP address/hostname # Requires NFSCL and NFS_ROOT options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info options BOOTP_NFSV3 # Use NFS v3 to NFS mount root options BOOTP_COMPAT # Workaround for broken bootp daemons. options BOOTP_WIRED_TO=fxp0 # Use interface fxp0 for BOOTP options BOOTP_BLOCKSIZE=8192 # Override NFS block size # # Enable software watchdog routines, even if hardware watchdog is present. # By default, software watchdog timer is enabled only if no hardware watchdog # is present. # options SW_WATCHDOG # # Add the software deadlock resolver thread. # options DEADLKRES # # Disable swapping of stack pages. This option removes all # code which actually performs swapping, so it's not possible to turn # it back on at run-time. # # This is sometimes usable for systems which don't have any swap space # (see also sysctl "vm.disable_swapspace_pageouts") # #options NO_SWAPPING # Set the number of sf_bufs to allocate. sf_bufs are virtual buffers # for sendfile(2) that are used to map file VM pages, and normally # default to a quantity that is roughly 16*MAXUSERS+512. You would # typically want about 4 of these for each simultaneous file send. # options NSFBUFS=1024 # # Enable extra debugging code for locks. This stores the filename and # line of whatever acquired the lock in the lock itself, and changes a # number of function calls to pass around the relevant data. This is # not at all useful unless you are debugging lock code. Note that # modules should be recompiled as this option modifies KBI. # options DEBUG_LOCKS ##################################################################### # USB support # UHCI controller device uhci # OHCI controller device ohci # EHCI controller device ehci # XHCI controller device xhci # SL811 Controller #device slhci # General USB code (mandatory for USB) device usb # # USB Double Bulk Pipe devices device udbp # USB Fm Radio device ufm # USB temperature meter device ugold # USB LED device uled # Human Interface Device (anything with buttons and dials) device uhid # USB keyboard device ukbd # USB printer device ulpt # USB mass storage driver (Requires scbus and da) device umass # USB mass storage driver for device-side mode device usfs # USB support for Belkin F5U109 and Magic Control Technology serial adapters device umct # USB modem support device umodem # USB mouse device ums # USB touchpad(s) device atp device wsp # eGalax USB touch screen device uep # Diamond Rio 500 MP3 player device urio # # USB serial support device ucom # USB support for 3G modem cards by Option, Novatel, Huawei and Sierra device u3g # USB support for Technologies ARK3116 based serial adapters device uark # USB support for Belkin F5U103 and compatible serial adapters device ubsa # USB support for serial adapters based on the FT8U100AX and FT8U232AM device uftdi # USB support for some Windows CE based serial communication. device uipaq # USB support for Prolific PL-2303 serial adapters device uplcom # USB support for Silicon Laboratories CP2101/CP2102 based USB serial adapters device uslcom # USB Visor and Palm devices device uvisor # USB serial support for DDI pocket's PHS device uvscom # # USB ethernet support device uether # ADMtek USB ethernet. Supports the LinkSys USB100TX, # the Billionton USB100, the Melco LU-ATX, the D-Link DSB-650TX # and the SMC 2202USB. Also works with the ADMtek AN986 Pegasus # eval board. device aue # ASIX Electronics AX88172 USB 2.0 ethernet driver. Used in the # LinkSys USB200M and various other adapters. device axe # ASIX Electronics AX88178A/AX88179 USB 2.0/3.0 gigabit ethernet driver. device axge # # Devices which communicate using Ethernet over USB, particularly # Communication Device Class (CDC) Ethernet specification. Supports # Sharp Zaurus PDAs, some DOCSIS cable modems and so on. device cdce # # CATC USB-EL1201A USB ethernet. Supports the CATC Netmate # and Netmate II, and the Belkin F5U111. device cue # # Kawasaki LSI ethernet. Supports the LinkSys USB10T, # Entrega USB-NET-E45, Peracom Ethernet Adapter, the # 3Com 3c19250, the ADS Technologies USB-10BT, the ATen UC10T, # the Netgear EA101, the D-Link DSB-650, the SMC 2102USB # and 2104USB, and the Corega USB-T. device kue # # RealTek RTL8150 USB to fast ethernet. Supports the Melco LUA-KTX # and the GREEN HOUSE GH-USB100B. device rue # # Davicom DM9601E USB to fast ethernet. Supports the Corega FEther USB-TXC. device udav # # RealTek RTL8152/RTL8153 USB Ethernet driver device ure # # Moschip MCS7730/MCS7840 USB to fast ethernet. Supports the Sitecom LN030. device mos # # HSxPA devices from Option N.V device uhso # Realtek RTL8188SU/RTL8191SU/RTL8192SU wireless driver device rsu # # Ralink Technology RT2501USB/RT2601USB wireless driver device rum # Ralink Technology RT2700U/RT2800U/RT3000U wireless driver device run # # Atheros AR5523 wireless driver device uath # # Conexant/Intersil PrismGT wireless driver device upgt # # Ralink Technology RT2500USB wireless driver device ural # # RNDIS USB ethernet driver device urndis # Realtek RTL8187B/L wireless driver device urtw # # ZyDas ZD1211/ZD1211B wireless driver device zyd # # Sierra USB wireless driver device usie # # debugging options for the USB subsystem # options USB_DEBUG options U3G_DEBUG # options for ukbd: options UKBD_DFLT_KEYMAP # specify the built-in keymap makeoptions UKBD_DFLT_KEYMAP=jp # options for uplcom: options UPLCOM_INTR_INTERVAL=100 # interrupt pipe interval # in milliseconds # options for uvscom: options UVSCOM_DEFAULT_OPKTSIZE=8 # default output packet size options UVSCOM_INTR_INTERVAL=100 # interrupt pipe interval # in milliseconds ##################################################################### # FireWire support device firewire # FireWire bus code device sbp # SCSI over Firewire (Requires scbus and da) device sbp_targ # SBP-2 Target mode (Requires scbus and targ) device fwe # Ethernet over FireWire (non-standard!) device fwip # IP over FireWire (RFC2734 and RFC3146) ##################################################################### # dcons support (Dumb Console Device) device dcons # dumb console driver device dcons_crom # FireWire attachment options DCONS_BUF_SIZE=16384 # buffer size options DCONS_POLL_HZ=100 # polling rate options DCONS_FORCE_CONSOLE=0 # force to be the primary console options DCONS_FORCE_GDB=1 # force to be the gdb device ##################################################################### # crypto subsystem # # This is a port of the OpenBSD crypto framework. Include this when # configuring IPSEC and when you have a h/w crypto device to accelerate # user applications that link to OpenSSL. # # Drivers are ports from OpenBSD with some simple enhancements that have # been fed back to OpenBSD. device crypto # core crypto support # Only install the cryptodev device if you are running tests, or know # specifically why you need it. In most cases, it is not needed and # will make things slower. device cryptodev # /dev/crypto for access to h/w device rndtest # FIPS 140-2 entropy tester device ccr # Chelsio T6 device hifn # Hifn 7951, 7781, etc. options HIFN_DEBUG # enable debugging support: hw.hifn.debug options HIFN_RNDTEST # enable rndtest support device ubsec # Broadcom 5501, 5601, 58xx options UBSEC_DEBUG # enable debugging support: hw.ubsec.debug options UBSEC_RNDTEST # enable rndtest support ##################################################################### # # Embedded system options: # # An embedded system might want to run something other than init. options INIT_PATH=/sbin/init:/rescue/init # Debug options options BUS_DEBUG # enable newbus debugging options DEBUG_VFS_LOCKS # enable VFS lock debugging options SOCKBUF_DEBUG # enable sockbuf last record/mb tail checking options IFMEDIA_DEBUG # enable debugging in net/if_media.c # # Verbose SYSINIT # # Make the SYSINIT process performed by mi_startup() verbose. This is very # useful when porting to a new architecture. If DDB is also enabled, this # will print function names instead of addresses. options VERBOSE_SYSINIT ##################################################################### # SYSV IPC KERNEL PARAMETERS # # Maximum number of System V semaphores that can be used on the system at # one time. options SEMMNI=11 # Total number of semaphores system wide options SEMMNS=61 # Total number of undo structures in system options SEMMNU=31 # Maximum number of System V semaphores that can be used by a single process # at one time. options SEMMSL=61 # Maximum number of operations that can be outstanding on a single System V # semaphore at one time. options SEMOPM=101 # Maximum number of undo operations that can be outstanding on a single # System V semaphore at one time. options SEMUME=11 # Maximum number of shared memory pages system wide. options SHMALL=1025 # Maximum size, in bytes, of a single System V shared memory region. options SHMMAX=(SHMMAXPGS*PAGE_SIZE+1) options SHMMAXPGS=1025 # Minimum size, in bytes, of a single System V shared memory region. options SHMMIN=2 # Maximum number of shared memory regions that can be used on the system # at one time. options SHMMNI=33 # Maximum number of System V shared memory regions that can be attached to # a single process at one time. options SHMSEG=9 # Set the amount of time (in seconds) the system will wait before # rebooting automatically when a kernel panic occurs. If set to (-1), # the system will wait indefinitely until a key is pressed on the # console. options PANIC_REBOOT_WAIT_TIME=16 # Attempt to bypass the buffer cache and put data directly into the # userland buffer for read operation when O_DIRECT flag is set on the # file. Both offset and length of the read operation must be # multiples of the physical media sector size. # options DIRECTIO # Specify a lower limit for the number of swap I/O buffers. They are # (among other things) used when bypassing the buffer cache due to # DIRECTIO kernel option enabled and O_DIRECT flag set on file. # options NSWBUF_MIN=120 ##################################################################### # More undocumented options for linting. # Note that documenting these is not considered an affront. options CAM_DEBUG_DELAY # VFS cluster debugging. options CLUSTERDEBUG options DEBUG # Kernel filelock debugging. options LOCKF_DEBUG # System V compatible message queues # Please note that the values provided here are used to test kernel # building. The defaults in the sources provide almost the same numbers. # MSGSSZ must be a power of 2 between 8 and 1024. options MSGMNB=2049 # Max number of chars in queue options MSGMNI=41 # Max number of message queue identifiers options MSGSEG=2049 # Max number of message segments options MSGSSZ=16 # Size of a message segment options MSGTQL=41 # Max number of messages in system options NBUF=512 # Number of buffer headers options SCSI_NCR_DEBUG options SCSI_NCR_MAX_SYNC=10000 options SCSI_NCR_MAX_WIDE=1 options SCSI_NCR_MYADDR=7 options SC_DEBUG_LEVEL=5 # Syscons debug level options SC_RENDER_DEBUG # syscons rendering debugging options VFS_BIO_DEBUG # VFS buffer I/O debugging options KSTACK_MAX_PAGES=32 # Maximum pages to give the kernel stack options KSTACK_USAGE_PROF # Adaptec Array Controller driver options options AAC_DEBUG # Debugging levels: # 0 - quiet, only emit warnings # 1 - noisy, emit major function # points and things done # 2 - extremely noisy, emit trace # items in loops, etc. # Resource Accounting options RACCT # Resource Limits options RCTL # Yet more undocumented options for linting. # BKTR_ALLOC_PAGES has no effect except to cause warnings, and # BROOKTREE_ALLOC_PAGES hasn't actually been superseded by it, since the # driver still mostly spells this option BROOKTREE_ALLOC_PAGES. ##options BKTR_ALLOC_PAGES=(217*4+1) options BROOKTREE_ALLOC_PAGES=(217*4+1) options MAXFILES=999 # Random number generator # Only ONE of the below two may be used; they are mutually exclusive. # If neither is present, then the Fortuna algorithm is selected. #options RANDOM_YARROW # Yarrow CSPRNG (old default) #options RANDOM_LOADABLE # Allow the algorithm to be loaded as # a module. # Select this to allow high-rate but potentially expensive # harvesting of Slab-Allocator entropy. In very high-rate # situations the value of doing this is dubious at best. options RANDOM_ENABLE_UMA # slab allocator # Module to enable execution of application via emulators like QEMU options IMAGACT_BINMISC # zlib I/O stream support # This enables support for compressed core dumps. options GZIO # zstd I/O stream support # This enables support for Zstd compressed core dumps. options ZSTDIO # BHND(4) drivers options BHND_LOGLEVEL # Logging threshold level # evdev interface device evdev # input event device support options EVDEV_SUPPORT # evdev support in legacy drivers options EVDEV_DEBUG # enable event debug msgs device uinput # install /dev/uinput cdev options UINPUT_DEBUG # enable uinput debug msgs # Encrypted kernel crash dumps. options EKCD Index: head/sys/conf/files.amd64 =================================================================== --- head/sys/conf/files.amd64 (revision 333018) +++ head/sys/conf/files.amd64 (revision 333019) @@ -1,740 +1,756 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # # $FreeBSD$ # # 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. # # cloudabi32_vdso.o optional compat_cloudabi32 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S" \ compile-with "${CC} -x assembler-with-cpp -m32 -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi32_vdso.o" # cloudabi32_vdso_blob.o optional compat_cloudabi32 \ dependency "cloudabi32_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 cloudabi32_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi32_vdso_blob.o" # cloudabi64_vdso.o optional compat_cloudabi64 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_x86_64.S" \ compile-with "${CC} -x assembler-with-cpp -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_x86_64.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi64_vdso.o" # cloudabi64_vdso_blob.o optional compat_cloudabi64 \ dependency "cloudabi64_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 cloudabi64_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi64_vdso_blob.o" # linux32_genassym.o optional compat_linux32 \ dependency "$S/amd64/linux32/linux32_genassym.c" \ compile-with "${CC} ${CFLAGS:N-flto:N-fno-common} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "linux32_genassym.o" # linux32_assym.h optional compat_linux32 \ dependency "$S/kern/genassym.sh linux32_genassym.o" \ compile-with "sh $S/kern/genassym.sh linux32_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "linux32_assym.h" # linux32_locore.o optional compat_linux32 \ dependency "linux32_assym.h $S/amd64/linux32/linux32_locore.s" \ compile-with "${CC} -x assembler-with-cpp -DLOCORE -m32 -shared -s -pipe -I. -I$S -Werror -Wall -fPIC -fno-common -nostdinc -nostdlib -Wl,-T$S/amd64/linux32/linux32_vdso.lds.s -Wl,-soname=linux32_vdso.so,--eh-frame-hdr,-warn-common ${.IMPSRC} -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "linux32_locore.o" # linux32_vdso.so optional compat_linux32 \ dependency "linux32_locore.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 linux32_locore.o ${.TARGET}" \ no-implicit-rule \ clean "linux32_vdso.so" # ia32_genassym.o standard \ dependency "$S/compat/ia32/ia32_genassym.c" \ compile-with "${CC} ${CFLAGS:N-flto:N-fno-common} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "ia32_genassym.o" # ia32_assym.h standard \ dependency "$S/kern/genassym.sh ia32_genassym.o" \ compile-with "env NM='${NM}' NMFLAGS='${NMFLAGS}' sh $S/kern/genassym.sh ia32_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "ia32_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 ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "kbdcontrol -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -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 -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -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" # hpt27xx_lib.o optional hpt27xx \ dependency "$S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \ compile-with "uudecode < $S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \ no-implicit-rule # hptmvraid.o optional hptmv \ dependency "$S/dev/hptmv/amd64-elf.raid.o.uu" \ compile-with "uudecode < $S/dev/hptmv/amd64-elf.raid.o.uu" \ no-implicit-rule # hptnr_lib.o optional hptnr \ dependency "$S/dev/hptnr/amd64-elf.hptnr_lib.o.uu" \ compile-with "uudecode < $S/dev/hptnr/amd64-elf.hptnr_lib.o.uu" \ no-implicit-rule # hptrr_lib.o optional hptrr \ dependency "$S/dev/hptrr/amd64-elf.hptrr_lib.o.uu" \ compile-with "uudecode < $S/dev/hptrr/amd64-elf.hptrr_lib.o.uu" \ no-implicit-rule # amd64/acpica/acpi_machdep.c optional acpi acpi_wakecode.o optional acpi \ dependency "$S/amd64/acpica/acpi_wakecode.S assym.inc" \ compile-with "${NORMAL_S}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.o" acpi_wakecode.bin optional acpi \ dependency "acpi_wakecode.o" \ compile-with "${OBJCOPY} -S -O binary acpi_wakecode.o ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.bin" acpi_wakecode.h optional acpi \ dependency "acpi_wakecode.bin" \ compile-with "file2c -sx 'static char wakecode[] = {' '};' < acpi_wakecode.bin > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.h" acpi_wakedata.h optional acpi \ dependency "acpi_wakecode.o" \ compile-with '${NM} -n --defined-only acpi_wakecode.o | while read offset dummy what; do echo "#define $${what} 0x$${offset}"; done > ${.TARGET}' \ no-obj no-implicit-rule before-depend \ clean "acpi_wakedata.h" # #amd64/amd64/apic_vector.S standard amd64/amd64/atomic.c standard amd64/amd64/bios.c standard amd64/amd64/bpf_jit_machdep.c optional bpf_jitter amd64/amd64/cpu_switch.S standard amd64/amd64/db_disasm.c optional ddb amd64/amd64/db_interface.c optional ddb amd64/amd64/db_trace.c optional ddb amd64/amd64/efirt_machdep.c optional efirt amd64/amd64/elf_machdep.c standard amd64/amd64/exception.S standard amd64/amd64/fpu.c standard amd64/amd64/gdb_machdep.c optional gdb amd64/amd64/in_cksum.c optional inet | inet6 amd64/amd64/initcpu.c standard amd64/amd64/io.c optional io amd64/amd64/locore.S standard no-obj amd64/amd64/xen-locore.S optional xenhvm amd64/amd64/machdep.c standard amd64/amd64/mem.c optional mem amd64/amd64/minidump_machdep.c standard amd64/amd64/mp_machdep.c optional smp amd64/amd64/mpboot.S optional smp amd64/amd64/pmap.c standard amd64/amd64/prof_machdep.c optional profiling-routine amd64/amd64/ptrace_machdep.c standard amd64/amd64/sigtramp.S standard amd64/amd64/support.S standard amd64/amd64/sys_machdep.c standard amd64/amd64/trap.c standard amd64/amd64/uio_machdep.c standard amd64/amd64/uma_machdep.c standard amd64/amd64/vm_machdep.c standard amd64/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 amd64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64 amd64/pci/pci_cfgreg.c optional pci cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S optional zfs | dtrace compile-with "${ZFS_S}" cddl/dev/dtrace/amd64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/amd64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}" cddl/dev/dtrace/x86/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}" crypto/aesni/aeskeys_amd64.S optional aesni crypto/aesni/aesni.c optional aesni aesni_ghash.o optional aesni \ dependency "$S/crypto/aesni/aesni_ghash.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes -mpclmul ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_ghash.o" aesni_wrap.o optional aesni \ dependency "$S/crypto/aesni/aesni_wrap.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_wrap.o" crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | \ ipsec_support | netsmb intel_sha1.o optional aesni \ dependency "$S/crypto/aesni/intel_sha1.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -msha ${.IMPSRC}" \ no-implicit-rule \ clean "intel_sha1.o" intel_sha256.o optional aesni \ dependency "$S/crypto/aesni/intel_sha256.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -msha ${.IMPSRC}" \ no-implicit-rule \ clean "intel_sha256.o" crypto/via/padlock.c optional padlock crypto/via/padlock_cipher.c optional padlock crypto/via/padlock_hash.c optional padlock dev/acpica/acpi_if.m standard dev/acpica/acpi_hpet.c optional acpi dev/acpica/acpi_pci.c optional acpi pci dev/acpica/acpi_pci_link.c optional acpi pci dev/acpica/acpi_pcib.c optional acpi pci dev/acpica/acpi_pcib_acpi.c optional acpi pci dev/acpica/acpi_pcib_pci.c optional acpi pci dev/acpica/acpi_timer.c optional acpi dev/acpi_support/acpi_wmi_if.m standard dev/agp/agp_amd64.c optional agp dev/agp/agp_i810.c optional agp dev/agp/agp_via.c optional agp dev/amdsbwd/amdsbwd.c optional amdsbwd dev/amdsmn/amdsmn.c optional amdsmn | amdtemp dev/amdtemp/amdtemp.c optional amdtemp dev/arcmsr/arcmsr.c optional arcmsr pci dev/asmc/asmc.c optional asmc isa dev/atkbdc/atkbd.c optional atkbd atkbdc dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc dev/atkbdc/atkbdc.c optional atkbdc dev/atkbdc/atkbdc_isa.c optional atkbdc isa dev/atkbdc/atkbdc_subr.c optional atkbdc dev/atkbdc/psm.c optional psm atkbdc dev/bxe/bxe.c optional bxe pci dev/bxe/bxe_stats.c optional bxe pci dev/bxe/bxe_debug.c optional bxe pci dev/bxe/ecore_sp.c optional bxe pci dev/bxe/bxe_elink.c optional bxe pci dev/bxe/57710_init_values.c optional bxe pci dev/bxe/57711_init_values.c optional bxe pci dev/bxe/57712_init_values.c optional bxe pci dev/coretemp/coretemp.c optional coretemp dev/cpuctl/cpuctl.c optional cpuctl dev/dpms/dpms.c optional dpms # There are no systems with isa slots, so all ed isa entries should go.. dev/ed/if_ed_3c503.c optional ed isa ed_3c503 dev/ed/if_ed_isa.c optional ed isa dev/ed/if_ed_wd80x3.c optional ed isa dev/ed/if_ed_hpp.c optional ed isa ed_hpp dev/ed/if_ed_sic.c optional ed isa ed_sic dev/fb/fb.c optional fb | vga dev/fb/s3_pci.c optional s3pci dev/fb/vesa.c optional vga vesa dev/fb/vga.c optional vga dev/ichwd/ichwd.c optional ichwd dev/if_ndis/if_ndis.c optional ndis dev/if_ndis/if_ndis_pccard.c optional ndis pccard dev/if_ndis/if_ndis_pci.c optional ndis cardbus | ndis pci dev/if_ndis/if_ndis_usb.c optional ndis usb dev/imcsmb/imcsmb.c optional imcsmb dev/imcsmb/imcsmb_pci.c optional imcsmb pci dev/intel/spi.c optional intelspi dev/io/iodev.c optional io dev/ioat/ioat.c optional ioat pci dev/ioat/ioat_test.c optional ioat pci dev/ipmi/ipmi.c optional ipmi dev/ipmi/ipmi_acpi.c optional ipmi acpi dev/ipmi/ipmi_isa.c optional ipmi isa dev/ipmi/ipmi_kcs.c optional ipmi dev/ipmi/ipmi_smic.c optional ipmi dev/ipmi/ipmi_smbus.c optional ipmi smbus dev/ipmi/ipmi_smbios.c optional ipmi dev/ipmi/ipmi_ssif.c optional ipmi smbus dev/ipmi/ipmi_pci.c optional ipmi pci dev/ipmi/ipmi_linux.c optional ipmi compat_linux32 dev/ixl/if_ixl.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_main.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_qmgr.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_iov.c optional ixl pci pci_iov \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_i2c.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_iw.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/if_ixlv.c optional ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixlvc.c optional ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_txrx.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_osdep.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_lan_hmc.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_hmc.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_common.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_nvm.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_adminq.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/fdc/fdc.c optional fdc dev/fdc/fdc_acpi.c optional fdc dev/fdc/fdc_isa.c optional fdc isa dev/fdc/fdc_pccard.c optional fdc pccard dev/gpio/bytgpio.c optional bytgpio dev/gpio/chvgpio.c optional chvgpio dev/hpt27xx/hpt27xx_os_bsd.c optional hpt27xx dev/hpt27xx/hpt27xx_osm_bsd.c optional hpt27xx dev/hpt27xx/hpt27xx_config.c optional hpt27xx dev/hptmv/entry.c optional hptmv dev/hptmv/mv.c optional hptmv dev/hptmv/gui_lib.c optional hptmv dev/hptmv/hptproc.c optional hptmv dev/hptmv/ioctl.c optional hptmv dev/hptnr/hptnr_os_bsd.c optional hptnr dev/hptnr/hptnr_osm_bsd.c optional hptnr dev/hptnr/hptnr_config.c optional hptnr dev/hptrr/hptrr_os_bsd.c optional hptrr dev/hptrr/hptrr_osm_bsd.c optional hptrr dev/hptrr/hptrr_config.c optional hptrr dev/hwpmc/hwpmc_amd.c optional hwpmc dev/hwpmc/hwpmc_intel.c optional hwpmc dev/hwpmc/hwpmc_core.c optional hwpmc dev/hwpmc/hwpmc_uncore.c optional hwpmc dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc dev/hyperv/input/hv_kbd.c optional hyperv dev/hyperv/input/hv_kbdc.c optional hyperv dev/hyperv/pcib/vmbus_pcib.c optional hyperv pci dev/hyperv/netvsc/hn_nvs.c optional hyperv dev/hyperv/netvsc/hn_rndis.c optional hyperv dev/hyperv/netvsc/if_hn.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv dev/hyperv/utilities/hv_kvp.c optional hyperv dev/hyperv/utilities/hv_snapshot.c optional hyperv dev/hyperv/utilities/vmbus_heartbeat.c optional hyperv dev/hyperv/utilities/vmbus_ic.c optional hyperv dev/hyperv/utilities/vmbus_shutdown.c optional hyperv dev/hyperv/utilities/vmbus_timesync.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv pci dev/hyperv/vmbus/vmbus_br.c optional hyperv dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/vmbus_res.c optional hyperv dev/hyperv/vmbus/vmbus_xact.c optional hyperv dev/hyperv/vmbus/amd64/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/amd64/vmbus_vector.S optional hyperv dev/nctgpio/nctgpio.c optional nctgpio dev/nfe/if_nfe.c optional nfe pci dev/ntb/if_ntb/if_ntb.c optional if_ntb dev/ntb/ntb_transport.c optional ntb_transport | if_ntb dev/ntb/ntb.c optional ntb | ntb_transport | if_ntb | ntb_hw_intel | ntb_hw_plx | ntb_hw dev/ntb/ntb_if.m optional ntb | ntb_transport | if_ntb | ntb_hw_intel | ntb_hw_plx | ntb_hw dev/ntb/ntb_hw/ntb_hw_intel.c optional ntb_hw_intel | ntb_hw dev/ntb/ntb_hw/ntb_hw_plx.c optional ntb_hw_plx | ntb_hw dev/nvd/nvd.c optional nvd nvme dev/nvme/nvme.c optional nvme dev/nvme/nvme_ctrlr.c optional nvme dev/nvme/nvme_ctrlr_cmd.c optional nvme dev/nvme/nvme_ns.c optional nvme dev/nvme/nvme_ns_cmd.c optional nvme dev/nvme/nvme_qpair.c optional nvme dev/nvme/nvme_sim.c optional nvme scbus dev/nvme/nvme_sysctl.c optional nvme dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/nvram/nvram.c optional nvram isa dev/random/ivy.c optional rdrand_rng dev/random/nehemiah.c optional padlock_rng dev/qlxge/qls_dbg.c optional qlxge pci dev/qlxge/qls_dump.c optional qlxge pci dev/qlxge/qls_hw.c optional qlxge pci dev/qlxge/qls_ioctl.c optional qlxge pci dev/qlxge/qls_isr.c optional qlxge pci dev/qlxge/qls_os.c optional qlxge pci dev/qlxgb/qla_dbg.c optional qlxgb pci dev/qlxgb/qla_hw.c optional qlxgb pci dev/qlxgb/qla_ioctl.c optional qlxgb pci dev/qlxgb/qla_isr.c optional qlxgb pci dev/qlxgb/qla_misc.c optional qlxgb pci dev/qlxgb/qla_os.c optional qlxgb pci dev/qlxgbe/ql_dbg.c optional qlxgbe pci dev/qlxgbe/ql_hw.c optional qlxgbe pci dev/qlxgbe/ql_ioctl.c optional qlxgbe pci dev/qlxgbe/ql_isr.c optional qlxgbe pci dev/qlxgbe/ql_misc.c optional qlxgbe pci dev/qlxgbe/ql_os.c optional qlxgbe pci dev/qlxgbe/ql_reset.c optional qlxgbe pci dev/qlnx/qlnxe/ecore_cxt.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_dbg_fw_funcs.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_dcbx.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_dev.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_hw.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_init_fw_funcs.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_init_ops.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_int.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_l2.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_mcp.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_sp_commands.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/ecore_spq.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/qlnx_ioctl.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/qlnx/qlnxe/qlnx_os.c optional qlnxe pci \ compile-with "${LINUXKPI_C}" dev/sfxge/common/ef10_ev.c optional sfxge pci dev/sfxge/common/ef10_filter.c optional sfxge pci dev/sfxge/common/ef10_intr.c optional sfxge pci dev/sfxge/common/ef10_mac.c optional sfxge pci dev/sfxge/common/ef10_mcdi.c optional sfxge pci dev/sfxge/common/ef10_nic.c optional sfxge pci dev/sfxge/common/ef10_nvram.c optional sfxge pci dev/sfxge/common/ef10_phy.c optional sfxge pci dev/sfxge/common/ef10_rx.c optional sfxge pci dev/sfxge/common/ef10_tx.c optional sfxge pci dev/sfxge/common/ef10_vpd.c optional sfxge pci dev/sfxge/common/efx_bootcfg.c optional sfxge pci dev/sfxge/common/efx_crc32.c optional sfxge pci dev/sfxge/common/efx_ev.c optional sfxge pci dev/sfxge/common/efx_filter.c optional sfxge pci dev/sfxge/common/efx_hash.c optional sfxge pci dev/sfxge/common/efx_intr.c optional sfxge pci dev/sfxge/common/efx_lic.c optional sfxge pci dev/sfxge/common/efx_mac.c optional sfxge pci dev/sfxge/common/efx_mcdi.c optional sfxge pci dev/sfxge/common/efx_mon.c optional sfxge pci dev/sfxge/common/efx_nic.c optional sfxge pci dev/sfxge/common/efx_nvram.c optional sfxge pci dev/sfxge/common/efx_phy.c optional sfxge pci dev/sfxge/common/efx_port.c optional sfxge pci dev/sfxge/common/efx_rx.c optional sfxge pci dev/sfxge/common/efx_sram.c optional sfxge pci dev/sfxge/common/efx_tx.c optional sfxge pci dev/sfxge/common/efx_vpd.c optional sfxge pci dev/sfxge/common/hunt_nic.c optional sfxge pci dev/sfxge/common/mcdi_mon.c optional sfxge pci dev/sfxge/common/medford_nic.c optional sfxge pci dev/sfxge/common/siena_mac.c optional sfxge pci dev/sfxge/common/siena_mcdi.c optional sfxge pci dev/sfxge/common/siena_nic.c optional sfxge pci dev/sfxge/common/siena_nvram.c optional sfxge pci dev/sfxge/common/siena_phy.c optional sfxge pci dev/sfxge/common/siena_sram.c optional sfxge pci dev/sfxge/common/siena_vpd.c optional sfxge pci dev/sfxge/sfxge.c optional sfxge pci dev/sfxge/sfxge_dma.c optional sfxge pci dev/sfxge/sfxge_ev.c optional sfxge pci dev/sfxge/sfxge_intr.c optional sfxge pci dev/sfxge/sfxge_mcdi.c optional sfxge pci dev/sfxge/sfxge_nvram.c optional sfxge pci dev/sfxge/sfxge_port.c optional sfxge pci dev/sfxge/sfxge_rx.c optional sfxge pci dev/sfxge/sfxge_tx.c optional sfxge pci dev/sio/sio.c optional sio dev/sio/sio_isa.c optional sio isa dev/sio/sio_pccard.c optional sio pccard dev/sio/sio_pci.c optional sio pci dev/sio/sio_puc.c optional sio puc +dev/smartpqi/smartpqi_cam.c optional smartpqi +dev/smartpqi/smartpqi_cmd.c optional smartpqi +dev/smartpqi/smartpqi_discovery.c optional smartpqi +dev/smartpqi/smartpqi_event.c optional smartpqi +dev/smartpqi/smartpqi_helper.c optional smartpqi +dev/smartpqi/smartpqi_init.c optional smartpqi +dev/smartpqi/smartpqi_intr.c optional smartpqi +dev/smartpqi/smartpqi_ioctl.c optional smartpqi +dev/smartpqi/smartpqi_main.c optional smartpqi +dev/smartpqi/smartpqi_mem.c optional smartpqi +dev/smartpqi/smartpqi_misc.c optional smartpqi +dev/smartpqi/smartpqi_queue.c optional smartpqi +dev/smartpqi/smartpqi_request.c optional smartpqi +dev/smartpqi/smartpqi_response.c optional smartpqi +dev/smartpqi/smartpqi_sis.c optional smartpqi +dev/smartpqi/smartpqi_tag.c optional smartpqi dev/speaker/spkr.c optional speaker dev/syscons/apm/apm_saver.c optional apm_saver apm dev/syscons/scterm-teken.c optional sc dev/syscons/scvesactl.c optional sc vga vesa dev/syscons/scvgarndr.c optional sc vga dev/syscons/scvtb.c optional sc dev/tpm/tpm.c optional tpm dev/tpm/tpm_acpi.c optional tpm acpi dev/tpm/tpm_isa.c optional tpm isa dev/uart/uart_cpu_x86.c optional uart dev/viawd/viawd.c optional viawd dev/vmware/vmxnet3/if_vmx.c optional vmx dev/vmware/vmci/vmci.c optional vmci dev/vmware/vmci/vmci_datagram.c optional vmci dev/vmware/vmci/vmci_doorbell.c optional vmci dev/vmware/vmci/vmci_driver.c optional vmci dev/vmware/vmci/vmci_event.c optional vmci dev/vmware/vmci/vmci_hashtable.c optional vmci dev/vmware/vmci/vmci_kernel_if.c optional vmci dev/vmware/vmci/vmci_qpair.c optional vmci dev/vmware/vmci/vmci_queue_pair.c optional vmci dev/vmware/vmci/vmci_resource.c optional vmci dev/wbwd/wbwd.c optional wbwd dev/xen/pci/xen_acpi_pci.c optional xenhvm dev/xen/pci/xen_pci.c optional xenhvm dev/isci/isci.c optional isci dev/isci/isci_controller.c optional isci dev/isci/isci_domain.c optional isci dev/isci/isci_interrupt.c optional isci dev/isci/isci_io_request.c optional isci dev/isci/isci_logger.c optional isci dev/isci/isci_oem_parameters.c optional isci dev/isci/isci_remote_device.c optional isci dev/isci/isci_sysctl.c optional isci dev/isci/isci_task_request.c optional isci dev/isci/isci_timer.c optional isci dev/isci/scil/sati.c optional isci dev/isci/scil/sati_abort_task_set.c optional isci dev/isci/scil/sati_atapi.c optional isci dev/isci/scil/sati_device.c optional isci dev/isci/scil/sati_inquiry.c optional isci dev/isci/scil/sati_log_sense.c optional isci dev/isci/scil/sati_lun_reset.c optional isci dev/isci/scil/sati_mode_pages.c optional isci dev/isci/scil/sati_mode_select.c optional isci dev/isci/scil/sati_mode_sense.c optional isci dev/isci/scil/sati_mode_sense_10.c optional isci dev/isci/scil/sati_mode_sense_6.c optional isci dev/isci/scil/sati_move.c optional isci dev/isci/scil/sati_passthrough.c optional isci dev/isci/scil/sati_read.c optional isci dev/isci/scil/sati_read_buffer.c optional isci dev/isci/scil/sati_read_capacity.c optional isci dev/isci/scil/sati_reassign_blocks.c optional isci dev/isci/scil/sati_report_luns.c optional isci dev/isci/scil/sati_request_sense.c optional isci dev/isci/scil/sati_start_stop_unit.c optional isci dev/isci/scil/sati_synchronize_cache.c optional isci dev/isci/scil/sati_test_unit_ready.c optional isci dev/isci/scil/sati_unmap.c optional isci dev/isci/scil/sati_util.c optional isci dev/isci/scil/sati_verify.c optional isci dev/isci/scil/sati_write.c optional isci dev/isci/scil/sati_write_and_verify.c optional isci dev/isci/scil/sati_write_buffer.c optional isci dev/isci/scil/sati_write_long.c optional isci dev/isci/scil/sci_abstract_list.c optional isci dev/isci/scil/sci_base_controller.c optional isci dev/isci/scil/sci_base_domain.c optional isci dev/isci/scil/sci_base_iterator.c optional isci dev/isci/scil/sci_base_library.c optional isci dev/isci/scil/sci_base_logger.c optional isci dev/isci/scil/sci_base_memory_descriptor_list.c optional isci dev/isci/scil/sci_base_memory_descriptor_list_decorator.c optional isci dev/isci/scil/sci_base_object.c optional isci dev/isci/scil/sci_base_observer.c optional isci dev/isci/scil/sci_base_phy.c optional isci dev/isci/scil/sci_base_port.c optional isci dev/isci/scil/sci_base_remote_device.c optional isci dev/isci/scil/sci_base_request.c optional isci dev/isci/scil/sci_base_state_machine.c optional isci dev/isci/scil/sci_base_state_machine_logger.c optional isci dev/isci/scil/sci_base_state_machine_observer.c optional isci dev/isci/scil/sci_base_subject.c optional isci dev/isci/scil/sci_util.c optional isci dev/isci/scil/scic_sds_controller.c optional isci dev/isci/scil/scic_sds_library.c optional isci dev/isci/scil/scic_sds_pci.c optional isci dev/isci/scil/scic_sds_phy.c optional isci dev/isci/scil/scic_sds_port.c optional isci dev/isci/scil/scic_sds_port_configuration_agent.c optional isci dev/isci/scil/scic_sds_remote_device.c optional isci dev/isci/scil/scic_sds_remote_node_context.c optional isci dev/isci/scil/scic_sds_remote_node_table.c optional isci dev/isci/scil/scic_sds_request.c optional isci dev/isci/scil/scic_sds_sgpio.c optional isci dev/isci/scil/scic_sds_smp_remote_device.c optional isci dev/isci/scil/scic_sds_smp_request.c optional isci dev/isci/scil/scic_sds_ssp_request.c optional isci dev/isci/scil/scic_sds_stp_packet_request.c optional isci dev/isci/scil/scic_sds_stp_remote_device.c optional isci dev/isci/scil/scic_sds_stp_request.c optional isci dev/isci/scil/scic_sds_unsolicited_frame_control.c optional isci dev/isci/scil/scif_sas_controller.c optional isci dev/isci/scil/scif_sas_controller_state_handlers.c optional isci dev/isci/scil/scif_sas_controller_states.c optional isci dev/isci/scil/scif_sas_domain.c optional isci dev/isci/scil/scif_sas_domain_state_handlers.c optional isci dev/isci/scil/scif_sas_domain_states.c optional isci dev/isci/scil/scif_sas_high_priority_request_queue.c optional isci dev/isci/scil/scif_sas_internal_io_request.c optional isci dev/isci/scil/scif_sas_io_request.c optional isci dev/isci/scil/scif_sas_io_request_state_handlers.c optional isci dev/isci/scil/scif_sas_io_request_states.c optional isci dev/isci/scil/scif_sas_library.c optional isci dev/isci/scil/scif_sas_remote_device.c optional isci dev/isci/scil/scif_sas_remote_device_ready_substate_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_ready_substates.c optional isci dev/isci/scil/scif_sas_remote_device_starting_substate_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_starting_substates.c optional isci dev/isci/scil/scif_sas_remote_device_state_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_states.c optional isci dev/isci/scil/scif_sas_request.c optional isci dev/isci/scil/scif_sas_smp_activity_clear_affiliation.c optional isci dev/isci/scil/scif_sas_smp_io_request.c optional isci dev/isci/scil/scif_sas_smp_phy.c optional isci dev/isci/scil/scif_sas_smp_remote_device.c optional isci dev/isci/scil/scif_sas_stp_io_request.c optional isci dev/isci/scil/scif_sas_stp_remote_device.c optional isci dev/isci/scil/scif_sas_stp_task_request.c optional isci dev/isci/scil/scif_sas_task_request.c optional isci dev/isci/scil/scif_sas_task_request_state_handlers.c optional isci dev/isci/scil/scif_sas_task_request_states.c optional isci dev/isci/scil/scif_sas_timer.c optional isci isa/syscons_isa.c optional sc isa/vga_isa.c optional vga kern/kern_clocksource.c standard kern/link_elf_obj.c standard libkern/x86/crc32_sse42.c standard libkern/memmove.c standard libkern/memset.c standard # # IA32 binary support # #amd64/ia32/ia32_exception.S optional compat_freebsd32 amd64/ia32/ia32_reg.c optional compat_freebsd32 amd64/ia32/ia32_signal.c optional compat_freebsd32 amd64/ia32/ia32_sigtramp.S optional compat_freebsd32 amd64/ia32/ia32_syscall.c optional compat_freebsd32 amd64/ia32/ia32_misc.c optional compat_freebsd32 compat/ia32/ia32_sysvec.c optional compat_freebsd32 compat/linprocfs/linprocfs.c optional linprocfs compat/linsysfs/linsysfs.c optional linsysfs # # Linux/i386 binary support # amd64/linux32/linux32_dummy.c optional compat_linux32 amd64/linux32/linux32_machdep.c optional compat_linux32 amd64/linux32/linux32_support.s optional compat_linux32 \ dependency "linux32_assym.h" amd64/linux32/linux32_sysent.c optional compat_linux32 amd64/linux32/linux32_sysvec.c optional compat_linux32 compat/linux/linux_emul.c optional compat_linux32 compat/linux/linux_errno.c optional compat_linux32 compat/linux/linux_file.c optional compat_linux32 compat/linux/linux_fork.c optional compat_linux32 compat/linux/linux_futex.c optional compat_linux32 compat/linux/linux_getcwd.c optional compat_linux32 compat/linux/linux_ioctl.c optional compat_linux32 compat/linux/linux_ipc.c optional compat_linux32 compat/linux/linux_mib.c optional compat_linux32 compat/linux/linux_misc.c optional compat_linux32 compat/linux/linux_mmap.c optional compat_linux32 compat/linux/linux_signal.c optional compat_linux32 compat/linux/linux_socket.c optional compat_linux32 compat/linux/linux_stats.c optional compat_linux32 compat/linux/linux_sysctl.c optional compat_linux32 compat/linux/linux_time.c optional compat_linux32 compat/linux/linux_timer.c optional compat_linux32 compat/linux/linux_uid16.c optional compat_linux32 compat/linux/linux_util.c optional compat_linux32 compat/linux/linux_vdso.c optional compat_linux32 compat/linux/linux_common.c optional compat_linux32 compat/linux/linux_event.c optional compat_linux32 compat/linux/linux.c optional compat_linux32 dev/amr/amr_linux.c optional compat_linux32 amr dev/mfi/mfi_linux.c optional compat_linux32 mfi # # Windows NDIS driver support # compat/ndis/kern_ndis.c optional ndisapi pci compat/ndis/kern_windrv.c optional ndisapi pci compat/ndis/subr_hal.c optional ndisapi pci compat/ndis/subr_ndis.c optional ndisapi pci compat/ndis/subr_ntoskrnl.c optional ndisapi pci compat/ndis/subr_pe.c optional ndisapi pci compat/ndis/subr_usbd.c optional ndisapi pci compat/ndis/winx64_wrap.S optional ndisapi pci # # x86 real mode BIOS emulator, required by dpms/pci/vesa # compat/x86bios/x86bios.c optional x86bios | dpms | pci | vesa contrib/x86emu/x86emu.c optional x86bios | dpms | pci | vesa # # bvm console # dev/bvm/bvm_console.c optional bvmconsole dev/bvm/bvm_dbg.c optional bvmdebug # # x86 shared code between IA32 and AMD64 architectures # x86/acpica/OsdEnvironment.c optional acpi x86/acpica/acpi_apm.c optional acpi x86/acpica/acpi_wakeup.c optional acpi x86/acpica/madt.c optional acpi x86/acpica/srat.c optional acpi x86/bios/smbios.c optional smbios x86/bios/vpd.c optional vpd x86/cpufreq/powernow.c optional cpufreq x86/cpufreq/est.c optional cpufreq x86/cpufreq/hwpstate.c optional cpufreq x86/cpufreq/p4tcc.c optional cpufreq x86/iommu/busdma_dmar.c optional acpi acpi_dmar pci x86/iommu/intel_ctx.c optional acpi acpi_dmar pci x86/iommu/intel_drv.c optional acpi acpi_dmar pci x86/iommu/intel_fault.c optional acpi acpi_dmar pci x86/iommu/intel_gas.c optional acpi acpi_dmar pci x86/iommu/intel_idpgtbl.c optional acpi acpi_dmar pci x86/iommu/intel_intrmap.c optional acpi acpi_dmar pci x86/iommu/intel_qi.c optional acpi acpi_dmar pci x86/iommu/intel_quirks.c optional acpi acpi_dmar pci x86/iommu/intel_utils.c optional acpi acpi_dmar pci x86/isa/atpic.c optional atpic isa x86/isa/atrtc.c standard x86/isa/clock.c standard x86/isa/elcr.c optional atpic isa | mptable x86/isa/isa.c standard x86/isa/isa_dma.c standard x86/isa/nmi.c standard x86/isa/orm.c optional isa x86/pci/pci_bus.c optional pci x86/pci/qpi.c optional pci x86/x86/autoconf.c standard x86/x86/bus_machdep.c standard x86/x86/busdma_bounce.c standard x86/x86/busdma_machdep.c standard x86/x86/cpu_machdep.c standard x86/x86/dump_machdep.c standard x86/x86/fdt_machdep.c optional fdt x86/x86/identcpu.c standard x86/x86/intr_machdep.c standard x86/x86/io_apic.c standard x86/x86/legacy.c standard x86/x86/local_apic.c standard x86/x86/mca.c standard x86/x86/x86_mem.c optional mem x86/x86/mptable.c optional mptable x86/x86/mptable_pci.c optional mptable pci x86/x86/mp_x86.c optional smp x86/x86/mp_watchdog.c optional mp_watchdog smp x86/x86/msi.c optional pci x86/x86/nexus.c standard x86/x86/pvclock.c standard x86/x86/stack_machdep.c optional ddb | stack x86/x86/tsc.c standard x86/x86/delay.c standard x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xenhvm x86/xen/pv.c optional xenhvm x86/xen/pvcpu_enum.c optional xenhvm x86/xen/xen_apic.c optional xenhvm x86/xen/xenpv.c optional xenhvm x86/xen/xen_nexus.c optional xenhvm x86/xen/xen_msi.c optional xenhvm x86/xen/xen_pci_bus.c optional xenhvm Index: head/sys/dev/smartpqi/smartpqi_cam.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_cam.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_cam.c (revision 333019) @@ -0,0 +1,1205 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ +/* + * CAM interface for smartpqi driver + */ + +#include "smartpqi_includes.h" + +/* + * Set cam sim properties of the smartpqi adapter. + */ +static void update_sim_properties(struct cam_sim *sim, struct ccb_pathinq *cpi) +{ + + pqisrc_softstate_t *softs = (struct pqisrc_softstate *) + cam_sim_softc(sim); + DBG_FUNC("IN\n"); + + cpi->version_num = 1; + cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; + cpi->target_sprt = 0; + cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED; + cpi->hba_eng_cnt = 0; + cpi->max_lun = PQI_MAX_MULTILUN; + cpi->max_target = 1088; + cpi->maxio = (softs->pqi_cap.max_sg_elem - 1) * PAGE_SIZE; + cpi->initiator_id = 255; + strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); + strncpy(cpi->hba_vid, "Microsemi", HBA_IDLEN); + strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); + cpi->unit_number = cam_sim_unit(sim); + cpi->bus_id = cam_sim_bus(sim); + cpi->base_transfer_speed = 1200000; /* Base bus speed in KB/sec */ + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_SPC4; + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->ccb_h.status = CAM_REQ_CMP; + + DBG_FUNC("OUT\n"); +} + +/* + * Get transport settings of the smartpqi adapter + */ +static void get_transport_settings(struct pqisrc_softstate *softs, + struct ccb_trans_settings *cts) +{ + struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; + struct ccb_trans_settings_sas *sas = &cts->xport_specific.sas; + struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; + + DBG_FUNC("IN\n"); + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_SPC4; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + spi->valid = CTS_SPI_VALID_DISC; + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + scsi->valid = CTS_SCSI_VALID_TQ; + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; + sas->valid = CTS_SAS_VALID_SPEED; + cts->ccb_h.status = CAM_REQ_CMP; + + DBG_FUNC("OUT\n"); +} + +/* + * Add the target to CAM layer and rescan, when a new device is found + */ +void os_add_device(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device) { + union ccb *ccb; + + DBG_FUNC("IN\n"); + + if(softs->os_specific.sim_registered) { + if ((ccb = xpt_alloc_ccb_nowait()) == NULL) { + DBG_ERR("rescan failed (can't allocate CCB)\n"); + return; + } + + if (xpt_create_path(&ccb->ccb_h.path, NULL, + cam_sim_path(softs->os_specific.sim), + device->target, device->lun) != CAM_REQ_CMP) { + DBG_ERR("rescan failed (can't create path)\n"); + xpt_free_ccb(ccb); + return; + } + xpt_rescan(ccb); + } + + DBG_FUNC("OUT\n"); +} + +/* + * Remove the device from CAM layer when deleted or hot removed + */ +void os_remove_device(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) { + struct cam_path *tmppath; + + DBG_FUNC("IN\n"); + + if(softs->os_specific.sim_registered) { + if (xpt_create_path(&tmppath, NULL, + cam_sim_path(softs->os_specific.sim), + device->target, device->lun) != CAM_REQ_CMP) { + DBG_ERR("unable to create path for async event"); + return; + } + xpt_async(AC_LOST_DEVICE, tmppath, NULL); + xpt_free_path(tmppath); + pqisrc_free_device(softs, device); + OS_SLEEP(10000); + } + + DBG_FUNC("OUT\n"); + +} + +/* + * Function to release the frozen simq + */ +static void pqi_release_camq( rcb_t *rcb ) +{ + pqisrc_softstate_t *softs; + struct ccb_scsiio *csio; + + csio = (struct ccb_scsiio *)&rcb->cm_ccb->csio; + softs = rcb->softs; + + DBG_FUNC("IN\n"); + + if (softs->os_specific.pqi_flags & PQI_FLAG_BUSY) { + softs->os_specific.pqi_flags &= ~PQI_FLAG_BUSY; + if (csio->ccb_h.status & CAM_RELEASE_SIMQ) + xpt_release_simq(xpt_path_sim(csio->ccb_h.path), 0); + else + csio->ccb_h.status |= CAM_RELEASE_SIMQ; + } + + DBG_FUNC("OUT\n"); +} + +/* + * Function to dma-unmap the completed request + */ +static void pqi_unmap_request(void *arg) +{ + pqisrc_softstate_t *softs; + rcb_t *rcb; + + DBG_IO("IN rcb = %p\n", arg); + + rcb = (rcb_t *)arg; + softs = rcb->softs; + + if (!(rcb->cm_flags & PQI_CMD_MAPPED)) + return; + + if (rcb->bcount != 0 ) { + if (rcb->data_dir == SOP_DATA_DIR_FROM_DEVICE) + bus_dmamap_sync(softs->os_specific.pqi_buffer_dmat, + rcb->cm_datamap, + BUS_DMASYNC_POSTREAD); + if (rcb->data_dir == SOP_DATA_DIR_TO_DEVICE) + bus_dmamap_sync(softs->os_specific.pqi_buffer_dmat, + rcb->cm_datamap, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(softs->os_specific.pqi_buffer_dmat, + rcb->cm_datamap); + } + rcb->cm_flags &= ~PQI_CMD_MAPPED; + + if(rcb->sgt && rcb->nseg) + os_mem_free(rcb->softs, (void*)rcb->sgt, + rcb->nseg*sizeof(sgt_t)); + + pqisrc_put_tag(&softs->taglist, rcb->tag); + + DBG_IO("OUT\n"); +} + +/* + * Construct meaningful LD name for volume here. + */ +static void +smartpqi_fix_ld_inquiry(pqisrc_softstate_t *softs, struct ccb_scsiio *csio) +{ + struct scsi_inquiry_data *inq = NULL; + uint8_t *cdb = NULL; + pqi_scsi_dev_t *device = NULL; + + DBG_FUNC("IN\n"); + + cdb = (csio->ccb_h.flags & CAM_CDB_POINTER) ? + (uint8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes; + if(cdb[0] == INQUIRY && + (cdb[1] & SI_EVPD) == 0 && + (csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN && + csio->dxfer_len >= SHORT_INQUIRY_LENGTH) { + + inq = (struct scsi_inquiry_data *)csio->data_ptr; + + device = softs->device_list[csio->ccb_h.target_id][csio->ccb_h.target_lun]; + + /* Let the disks be probed and dealt with via CAM. Only for LD + let it fall through and inquiry be tweaked */ + if( !device || !pqisrc_is_logical_device(device) || + (device->devtype != DISK_DEVICE) || + pqisrc_is_external_raid_device(device)) { + return; + } + + strncpy(inq->vendor, "MSCC", + SID_VENDOR_SIZE); + strncpy(inq->product, + pqisrc_raidlevel_to_string(device->raid_level), + SID_PRODUCT_SIZE); + strncpy(inq->revision, device->volume_offline?"OFF":"OK", + SID_REVISION_SIZE); + } + + DBG_FUNC("OUT\n"); +} + +/* + * Handle completion of a command - pass results back through the CCB + */ +void +os_io_response_success(rcb_t *rcb) +{ + struct ccb_scsiio *csio; + + DBG_IO("IN rcb = %p\n", rcb); + + if (rcb == NULL) + panic("rcb is null"); + + csio = (struct ccb_scsiio *)&rcb->cm_ccb->csio; + + if (csio == NULL) + panic("csio is null"); + + rcb->status = REQUEST_SUCCESS; + csio->ccb_h.status = CAM_REQ_CMP; + + smartpqi_fix_ld_inquiry(rcb->softs, csio); + pqi_release_camq(rcb); + pqi_unmap_request(rcb); + xpt_done((union ccb *)csio); + + DBG_IO("OUT\n"); +} + +/* + * Error response handling for raid IO + */ +void os_raid_response_error(rcb_t *rcb, raid_path_error_info_elem_t *err_info) +{ + struct ccb_scsiio *csio; + pqisrc_softstate_t *softs; + + DBG_IO("IN\n"); + + csio = (struct ccb_scsiio *)&rcb->cm_ccb->csio; + + if (csio == NULL) + panic("csio is null"); + + softs = rcb->softs; + + ASSERT(err_info != NULL); + csio->scsi_status = err_info->status; + csio->ccb_h.status = CAM_REQ_CMP_ERR; + + if (csio->ccb_h.func_code == XPT_SCSI_IO) { + /* + * Handle specific SCSI status values. + */ + switch(csio->scsi_status) { + case PQI_RAID_STATUS_QUEUE_FULL: + csio->ccb_h.status = CAM_REQ_CMP; + DBG_ERR("Queue Full error"); + break; + /* check condition, sense data included */ + case PQI_RAID_STATUS_CHECK_CONDITION: + { + uint16_t sense_data_len = + LE_16(err_info->sense_data_len); + uint8_t *sense_data = NULL; + if (sense_data_len) + sense_data = err_info->data; + memset(&csio->sense_data, 0, csio->sense_len); + sense_data_len = (sense_data_len > + csio->sense_len) ? + csio->sense_len : + sense_data_len; + if (sense_data) + memcpy(&csio->sense_data, sense_data, + sense_data_len); + if (csio->sense_len > sense_data_len) + csio->sense_resid = csio->sense_len + - sense_data_len; + else + csio->sense_resid = 0; + csio->ccb_h.status = CAM_SCSI_STATUS_ERROR + | CAM_AUTOSNS_VALID + | CAM_REQ_CMP_ERR; + + } + break; + + case PQI_RAID_DATA_IN_OUT_UNDERFLOW: + { + uint32_t resid = 0; + resid = rcb->bcount-err_info->data_out_transferred; + csio->resid = resid; + csio->ccb_h.status = CAM_REQ_CMP; + break; + } + default: + csio->ccb_h.status = CAM_REQ_CMP; + break; + } + } + + if (softs->os_specific.pqi_flags & PQI_FLAG_BUSY) { + softs->os_specific.pqi_flags &= ~PQI_FLAG_BUSY; + if (csio->ccb_h.status & CAM_RELEASE_SIMQ) + xpt_release_simq(xpt_path_sim(csio->ccb_h.path), 0); + else + csio->ccb_h.status |= CAM_RELEASE_SIMQ; + } + + pqi_unmap_request(rcb); + xpt_done((union ccb *)csio); + + DBG_IO("OUT\n"); +} + + +/* + * Error response handling for aio. + */ +void os_aio_response_error(rcb_t *rcb, aio_path_error_info_elem_t *err_info) +{ + struct ccb_scsiio *csio; + pqisrc_softstate_t *softs; + + DBG_IO("IN\n"); + + if (rcb == NULL) + panic("rcb is null"); + + rcb->status = REQUEST_SUCCESS; + csio = (struct ccb_scsiio *)&rcb->cm_ccb->csio; + if (csio == NULL) + panic("csio is null"); + + softs = rcb->softs; + + switch (err_info->service_resp) { + case PQI_AIO_SERV_RESPONSE_COMPLETE: + csio->ccb_h.status = err_info->status; + break; + case PQI_AIO_SERV_RESPONSE_FAILURE: + switch(err_info->status) { + case PQI_AIO_STATUS_IO_ABORTED: + csio->ccb_h.status = CAM_REQ_ABORTED; + DBG_WARN_BTL(rcb->dvp, "IO aborted\n"); + break; + case PQI_AIO_STATUS_UNDERRUN: + csio->ccb_h.status = CAM_REQ_CMP; + csio->resid = + LE_32(err_info->resd_count); + break; + case PQI_AIO_STATUS_OVERRUN: + csio->ccb_h.status = CAM_REQ_CMP; + break; + case PQI_AIO_STATUS_AIO_PATH_DISABLED: + DBG_WARN_BTL(rcb->dvp,"AIO Path Disabled\n"); + rcb->dvp->offload_enabled = false; + csio->ccb_h.status |= CAM_REQUEUE_REQ; + break; + case PQI_AIO_STATUS_IO_ERROR: + case PQI_AIO_STATUS_IO_NO_DEVICE: + case PQI_AIO_STATUS_INVALID_DEVICE: + default: + DBG_WARN_BTL(rcb->dvp,"IO Error/Invalid/No device\n"); + csio->ccb_h.status |= + CAM_SCSI_STATUS_ERROR; + break; + } + break; + case PQI_AIO_SERV_RESPONSE_TMF_COMPLETE: + case PQI_AIO_SERV_RESPONSE_TMF_SUCCEEDED: + csio->ccb_h.status = CAM_REQ_CMP; + break; + case PQI_AIO_SERV_RESPONSE_TMF_REJECTED: + case PQI_AIO_SERV_RESPONSE_TMF_INCORRECT_LUN: + DBG_WARN_BTL(rcb->dvp,"TMF rejected/Incorrect Lun\n"); + csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; + break; + default: + DBG_WARN_BTL(rcb->dvp,"Scsi Status Error\n"); + csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; + break; + } + if(err_info->data_pres == DATA_PRESENT_SENSE_DATA ) { + csio->scsi_status = PQI_AIO_STATUS_CHECK_CONDITION; + uint8_t *sense_data = NULL; + unsigned sense_data_len = LE_16(err_info->data_len); + if (sense_data_len) + sense_data = err_info->data; + DBG_ERR_BTL(rcb->dvp, "SCSI_STATUS_CHECK_COND sense size %u\n", + sense_data_len); + memset(&csio->sense_data, 0, csio->sense_len); + if (sense_data) + memcpy(&csio->sense_data, sense_data, ((sense_data_len > + csio->sense_len) ? csio->sense_len : sense_data_len)); + if (csio->sense_len > sense_data_len) + csio->sense_resid = csio->sense_len - sense_data_len; + else + csio->sense_resid = 0; + csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; + } + + smartpqi_fix_ld_inquiry(softs, csio); + pqi_release_camq(rcb); + pqi_unmap_request(rcb); + xpt_done((union ccb *)csio); + DBG_IO("OUT\n"); +} + +/* + * Command-mapping helper function - populate this command's s/g table. + */ +static void +pqi_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + pqisrc_softstate_t *softs; + rcb_t *rcb; + + rcb = (rcb_t *)arg; + softs = rcb->softs; + + if( error || nseg > softs->pqi_cap.max_sg_elem ) + { + xpt_freeze_simq(softs->os_specific.sim, 1); + rcb->cm_ccb->ccb_h.status |= (CAM_REQUEUE_REQ| + CAM_RELEASE_SIMQ); + DBG_ERR_BTL(rcb->dvp, "map failed err = %d or nseg(%d) > sgelem(%d)\n", + error, nseg, softs->pqi_cap.max_sg_elem); + pqi_unmap_request(rcb); + xpt_done((union ccb *)rcb->cm_ccb); + return; + } + + rcb->sgt = os_mem_alloc(softs, nseg * sizeof(rcb_t)); + rcb->nseg = nseg; + if (rcb->sgt != NULL) { + for (int i = 0; i < nseg; i++) { + rcb->sgt[i].addr = segs[i].ds_addr; + rcb->sgt[i].len = segs[i].ds_len; + rcb->sgt[i].flags = 0; + } + } + + if (rcb->data_dir == SOP_DATA_DIR_FROM_DEVICE) + bus_dmamap_sync(softs->os_specific.pqi_buffer_dmat, + rcb->cm_datamap, BUS_DMASYNC_PREREAD); + if (rcb->data_dir == SOP_DATA_DIR_TO_DEVICE) + bus_dmamap_sync(softs->os_specific.pqi_buffer_dmat, + rcb->cm_datamap, BUS_DMASYNC_PREWRITE); + + /* Call IO functions depending on pd or ld */ + rcb->status = REQUEST_PENDING; + + error = pqisrc_build_send_io(softs, rcb); + + if (error) { + rcb->req_pending = false; + xpt_freeze_simq(softs->os_specific.sim, 1); + rcb->cm_ccb->ccb_h.status |= (CAM_REQUEUE_REQ + |CAM_RELEASE_SIMQ); + DBG_ERR_BTL(rcb->dvp, "Build IO failed, error = %d\n", error); + pqi_unmap_request(rcb); + xpt_done((union ccb *)rcb->cm_ccb); + return; + } +} + +/* + * Function to dma-map the request buffer + */ +static int pqi_map_request( rcb_t *rcb ) +{ + pqisrc_softstate_t *softs = rcb->softs; + int error = PQI_STATUS_SUCCESS; + union ccb *ccb = rcb->cm_ccb; + + DBG_FUNC("IN\n"); + + /* check that mapping is necessary */ + if (rcb->cm_flags & PQI_CMD_MAPPED) + return(0); + rcb->cm_flags |= PQI_CMD_MAPPED; + + if (rcb->bcount) { + error = bus_dmamap_load_ccb(softs->os_specific.pqi_buffer_dmat, + rcb->cm_datamap, ccb, pqi_request_map_helper, rcb, 0); + if (error != 0){ + DBG_ERR_BTL(rcb->dvp, "bus_dmamap_load_ccb failed = %d count = %d\n", + error, rcb->bcount); + return error; + } + } else { + /* + * Set up the command to go to the controller. If there are no + * data buffers associated with the command then it can bypass + * busdma. + */ + /* Call IO functions depending on pd or ld */ + rcb->status = REQUEST_PENDING; + + error = pqisrc_build_send_io(softs, rcb); + + } + + DBG_FUNC("OUT error = %d\n", error); + + return error; +} + +/* + * Function to clear the request control block + */ +void os_reset_rcb( rcb_t *rcb ) +{ + rcb->error_info = NULL; + rcb->req = NULL; + rcb->status = -1; + rcb->tag = INVALID_ELEM; + rcb->dvp = NULL; + rcb->cdbp = NULL; + rcb->softs = NULL; + rcb->cm_flags = 0; + rcb->cm_data = NULL; + rcb->bcount = 0; + rcb->nseg = 0; + rcb->sgt = NULL; + rcb->cm_ccb = NULL; + rcb->encrypt_enable = false; + rcb->ioaccel_handle = 0; + rcb->resp_qid = 0; + rcb->req_pending = false; +} + +/* + * Callback function for the lun rescan + */ +static void smartpqi_lunrescan_cb(struct cam_periph *periph, union ccb *ccb) +{ + xpt_free_path(ccb->ccb_h.path); + xpt_free_ccb(ccb); +} + + +/* + * Function to rescan the lun + */ +static void smartpqi_lun_rescan(struct pqisrc_softstate *softs, int target, + int lun) +{ + union ccb *ccb = NULL; + cam_status status = 0; + struct cam_path *path = NULL; + + DBG_FUNC("IN\n"); + + ccb = xpt_alloc_ccb_nowait(); + status = xpt_create_path(&path, NULL, + cam_sim_path(softs->os_specific.sim), target, lun); + if (status != CAM_REQ_CMP) { + DBG_ERR("xpt_create_path status(%d) != CAM_REQ_CMP \n", + status); + xpt_free_ccb(ccb); + return; + } + + bzero(ccb, sizeof(union ccb)); + xpt_setup_ccb(&ccb->ccb_h, path, 5); + ccb->ccb_h.func_code = XPT_SCAN_LUN; + ccb->ccb_h.cbfcnp = smartpqi_lunrescan_cb; + ccb->crcn.flags = CAM_FLAG_NONE; + + xpt_action(ccb); + + DBG_FUNC("OUT\n"); +} + +/* + * Function to rescan the lun under each target + */ +void smartpqi_target_rescan(struct pqisrc_softstate *softs) +{ + int target = 0, lun = 0; + + DBG_FUNC("IN\n"); + + for(target = 0; target < PQI_MAX_DEVICES; target++){ + for(lun = 0; lun < PQI_MAX_MULTILUN; lun++){ + if(softs->device_list[target][lun]){ + smartpqi_lun_rescan(softs, target, lun); + } + } + } + + DBG_FUNC("OUT\n"); +} + +/* + * Set the mode of tagged command queueing for the current task. + */ +uint8_t os_get_task_attr(rcb_t *rcb) +{ + union ccb *ccb = rcb->cm_ccb; + uint8_t tag_action = SOP_TASK_ATTRIBUTE_SIMPLE; + + switch(ccb->csio.tag_action) { + case MSG_HEAD_OF_Q_TAG: + tag_action = SOP_TASK_ATTRIBUTE_HEAD_OF_QUEUE; + break; + case MSG_ORDERED_Q_TAG: + tag_action = SOP_TASK_ATTRIBUTE_ORDERED; + break; + case MSG_SIMPLE_Q_TAG: + default: + tag_action = SOP_TASK_ATTRIBUTE_SIMPLE; + break; + } + return tag_action; +} + +/* + * Complete all outstanding commands + */ +void os_complete_outstanding_cmds_nodevice(pqisrc_softstate_t *softs) +{ + int tag = 0; + + DBG_FUNC("IN\n"); + + for (tag = 1; tag < softs->max_outstanding_io; tag++) { + rcb_t *prcb = &softs->rcb[tag]; + if(prcb->req_pending && prcb->cm_ccb ) { + prcb->req_pending = false; + prcb->cm_ccb->ccb_h.status = CAM_REQ_ABORTED | CAM_REQ_CMP; + xpt_done((union ccb *)prcb->cm_ccb); + prcb->cm_ccb = NULL; + } + } + + DBG_FUNC("OUT\n"); +} + +/* + * IO handling functionality entry point + */ +static int pqisrc_io_start(struct cam_sim *sim, union ccb *ccb) +{ + rcb_t *rcb; + uint32_t tag, no_transfer = 0; + pqisrc_softstate_t *softs = (struct pqisrc_softstate *) + cam_sim_softc(sim); + int32_t error = PQI_STATUS_FAILURE; + pqi_scsi_dev_t *dvp; + + DBG_FUNC("IN\n"); + + if( softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun] == NULL ) { + ccb->ccb_h.status = CAM_DEV_NOT_THERE; + DBG_INFO("Device = %d not there\n", ccb->ccb_h.target_id); + return PQI_STATUS_FAILURE; + } + + dvp = softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun]; + /* Check controller state */ + if (IN_PQI_RESET(softs)) { + ccb->ccb_h.status = CAM_SCSI_BUS_RESET + | CAM_BUSY | CAM_REQ_INPROG; + DBG_WARN("Device = %d BUSY/IN_RESET\n", ccb->ccb_h.target_id); + return error; + } + /* Check device state */ + if (pqisrc_ctrl_offline(softs) || DEV_GONE(dvp)) { + ccb->ccb_h.status = CAM_DEV_NOT_THERE | CAM_REQ_CMP; + DBG_WARN("Device = %d GONE/OFFLINE\n", ccb->ccb_h.target_id); + return error; + } + /* Check device reset */ + if (DEV_RESET(dvp)) { + ccb->ccb_h.status = CAM_SCSI_BUSY | CAM_REQ_INPROG | CAM_BUSY; + DBG_WARN("Device %d reset returned busy\n", ccb->ccb_h.target_id); + return error; + } + + if (dvp->expose_device == false) { + ccb->ccb_h.status = CAM_DEV_NOT_THERE; + DBG_INFO("Device = %d not exposed\n", ccb->ccb_h.target_id); + return error; + } + + tag = pqisrc_get_tag(&softs->taglist); + if( tag == INVALID_ELEM ) { + DBG_ERR("Get Tag failed\n"); + xpt_freeze_simq(softs->os_specific.sim, 1); + softs->os_specific.pqi_flags |= PQI_FLAG_BUSY; + ccb->ccb_h.status |= (CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ); + return PQI_STATUS_FAILURE; + } + + DBG_IO("tag = %d &softs->taglist : %p\n", tag, &softs->taglist); + + rcb = &softs->rcb[tag]; + os_reset_rcb( rcb ); + rcb->tag = tag; + rcb->softs = softs; + rcb->cmdlen = ccb->csio.cdb_len; + ccb->ccb_h.sim_priv.entries[0].ptr = rcb; + + switch (ccb->ccb_h.flags & CAM_DIR_MASK) { + case CAM_DIR_IN: + rcb->data_dir = SOP_DATA_DIR_FROM_DEVICE; + break; + case CAM_DIR_OUT: + rcb->data_dir = SOP_DATA_DIR_TO_DEVICE; + break; + case CAM_DIR_NONE: + no_transfer = 1; + break; + default: + DBG_ERR("Unknown Dir\n"); + break; + } + rcb->cm_ccb = ccb; + rcb->dvp = softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun]; + + if (!no_transfer) { + rcb->cm_data = (void *)ccb->csio.data_ptr; + rcb->bcount = ccb->csio.dxfer_len; + } else { + rcb->cm_data = NULL; + rcb->bcount = 0; + } + /* + * Submit the request to the adapter. + * + * Note that this may fail if we're unable to map the request (and + * if we ever learn a transport layer other than simple, may fail + * if the adapter rejects the command). + */ + if ((error = pqi_map_request(rcb)) != 0) { + rcb->req_pending = false; + xpt_freeze_simq(softs->os_specific.sim, 1); + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; + if (error == EINPROGRESS) { + DBG_WARN("In Progress on %d\n", ccb->ccb_h.target_id); + error = 0; + } else { + ccb->ccb_h.status |= CAM_REQUEUE_REQ; + DBG_WARN("Requeue req error = %d target = %d\n", error, + ccb->ccb_h.target_id); + pqi_unmap_request(rcb); + } + } + + DBG_FUNC("OUT error = %d\n", error); + return error; +} + +/* + * Abort a task, task management functionality + */ +static int +pqisrc_scsi_abort_task(pqisrc_softstate_t *softs, union ccb *ccb) +{ + rcb_t *rcb = ccb->ccb_h.sim_priv.entries[0].ptr; + uint32_t abort_tag = rcb->tag; + uint32_t tag = 0; + int rval = PQI_STATUS_SUCCESS; + uint16_t qid; + + DBG_FUNC("IN\n"); + + qid = (uint16_t)rcb->resp_qid; + + tag = pqisrc_get_tag(&softs->taglist); + rcb = &softs->rcb[tag]; + rcb->tag = tag; + rcb->resp_qid = qid; + + rval = pqisrc_send_tmf(softs, rcb->dvp, rcb, abort_tag, + SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK); + + if (PQI_STATUS_SUCCESS == rval) { + rval = rcb->status; + if (REQUEST_SUCCESS == rval) { + ccb->ccb_h.status = CAM_REQ_ABORTED; + } + } + pqisrc_put_tag(&softs->taglist, abort_tag); + pqisrc_put_tag(&softs->taglist,rcb->tag); + + DBG_FUNC("OUT rval = %d\n", rval); + + return rval; +} + +/* + * Abort a taskset, task management functionality + */ +static int +pqisrc_scsi_abort_task_set(pqisrc_softstate_t *softs, union ccb *ccb) +{ + rcb_t *rcb = NULL; + uint32_t tag = 0; + int rval = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); + + tag = pqisrc_get_tag(&softs->taglist); + rcb = &softs->rcb[tag]; + rcb->tag = tag; + + rval = pqisrc_send_tmf(softs, rcb->dvp, rcb, 0, + SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK_SET); + + if (rval == PQI_STATUS_SUCCESS) { + rval = rcb->status; + } + + pqisrc_put_tag(&softs->taglist,rcb->tag); + + DBG_FUNC("OUT rval = %d\n", rval); + + return rval; +} + +/* + * Target reset task management functionality + */ +static int +pqisrc_target_reset( pqisrc_softstate_t *softs, union ccb *ccb) +{ + pqi_scsi_dev_t *devp = softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun]; + rcb_t *rcb = NULL; + uint32_t tag = 0; + int rval = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); + + if (devp == NULL) { + DBG_ERR("bad target t%d\n", ccb->ccb_h.target_id); + return (-1); + } + + tag = pqisrc_get_tag(&softs->taglist); + rcb = &softs->rcb[tag]; + rcb->tag = tag; + + devp->reset_in_progress = true; + rval = pqisrc_send_tmf(softs, devp, rcb, 0, + SOP_TASK_MANAGEMENT_LUN_RESET); + if (PQI_STATUS_SUCCESS == rval) { + rval = rcb->status; + } + devp->reset_in_progress = false; + pqisrc_put_tag(&softs->taglist,rcb->tag); + + DBG_FUNC("OUT rval = %d\n", rval); + + return ((rval == REQUEST_SUCCESS) ? + PQI_STATUS_SUCCESS : PQI_STATUS_FAILURE); +} + +/* + * cam entry point of the smartpqi module. + */ +static void smartpqi_cam_action(struct cam_sim *sim, union ccb *ccb) +{ + struct pqisrc_softstate *softs = cam_sim_softc(sim); + struct ccb_hdr *ccb_h = &ccb->ccb_h; + + DBG_FUNC("IN\n"); + + switch (ccb_h->func_code) { + case XPT_SCSI_IO: + { + if(!pqisrc_io_start(sim, ccb)) { + return; + } + break; + } + case XPT_CALC_GEOMETRY: + { + struct ccb_calc_geometry *ccg; + ccg = &ccb->ccg; + if (ccg->block_size == 0) { + ccb->ccb_h.status &= ~CAM_SIM_QUEUED; + ccb->ccb_h.status = CAM_REQ_INVALID; + break; + } + cam_calc_geometry(ccg, /* extended */ 1); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_PATH_INQ: + { + update_sim_properties(sim, &ccb->cpi); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + } + case XPT_GET_TRAN_SETTINGS: + get_transport_settings(softs, &ccb->cts); + ccb->ccb_h.status = CAM_REQ_CMP; + break; + case XPT_ABORT: + if(pqisrc_scsi_abort_task(softs, ccb)) { + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + xpt_done(ccb); + DBG_ERR("Abort task failed on %d\n", + ccb->ccb_h.target_id); + return; + } + break; + case XPT_TERM_IO: + if (pqisrc_scsi_abort_task_set(softs, ccb)) { + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + DBG_ERR("Abort task set failed on %d\n", + ccb->ccb_h.target_id); + xpt_done(ccb); + return; + } + break; + case XPT_RESET_DEV: + if(pqisrc_target_reset(softs, ccb)) { + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + DBG_ERR("Target reset failed on %d\n", + ccb->ccb_h.target_id); + xpt_done(ccb); + return; + } else { + ccb->ccb_h.status = CAM_REQ_CMP; + } + break; + case XPT_RESET_BUS: + ccb->ccb_h.status = CAM_REQ_CMP; + break; + case XPT_SET_TRAN_SETTINGS: + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + return; + default: + DBG_WARN("UNSUPPORTED FUNC CODE\n"); + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + break; + } + xpt_done(ccb); + + DBG_FUNC("OUT\n"); +} + +/* + * Function to poll the response, when interrupts are unavailable + * This also serves supporting crash dump. + */ +static void smartpqi_poll(struct cam_sim *sim) +{ + struct pqisrc_softstate *softs = cam_sim_softc(sim); + int i; + + for (i = 1; i < softs->intr_count; i++ ) + pqisrc_process_response_queue(softs, i); +} + +/* + * Function to adjust the queue depth of a device + */ +void smartpqi_adjust_queue_depth(struct cam_path *path, uint32_t queue_depth) +{ + struct ccb_relsim crs; + + DBG_INFO("IN\n"); + + xpt_setup_ccb(&crs.ccb_h, path, 5); + crs.ccb_h.func_code = XPT_REL_SIMQ; + crs.ccb_h.flags = CAM_DEV_QFREEZE; + crs.release_flags = RELSIM_ADJUST_OPENINGS; + crs.openings = queue_depth; + xpt_action((union ccb *)&crs); + if(crs.ccb_h.status != CAM_REQ_CMP) { + printf("XPT_REL_SIMQ failed stat=%d\n", crs.ccb_h.status); + } + + DBG_INFO("OUT\n"); +} + +/* + * Function to register async callback for setting queue depth + */ +static void +smartpqi_async(void *callback_arg, u_int32_t code, + struct cam_path *path, void *arg) +{ + struct pqisrc_softstate *softs; + softs = (struct pqisrc_softstate*)callback_arg; + + DBG_FUNC("IN\n"); + + switch (code) { + case AC_FOUND_DEVICE: + { + struct ccb_getdev *cgd; + cgd = (struct ccb_getdev *)arg; + if (cgd == NULL) { + break; + } + uint32_t t_id = cgd->ccb_h.target_id; + + if (t_id <= (PQI_CTLR_INDEX - 1)) { + if (softs != NULL) { + pqi_scsi_dev_t *dvp = softs->device_list[t_id][cgd->ccb_h.target_lun]; + smartpqi_adjust_queue_depth(path, + dvp->queue_depth); + } + } + break; + } + default: + break; + } + + DBG_FUNC("OUT\n"); +} + +/* + * Function to register sim with CAM layer for smartpqi driver + */ +int register_sim(struct pqisrc_softstate *softs, int card_index) +{ + int error = 0; + int max_transactions; + union ccb *ccb = NULL; + cam_status status = 0; + struct ccb_setasync csa; + struct cam_sim *sim; + + DBG_FUNC("IN\n"); + + max_transactions = softs->max_io_for_scsi_ml; + softs->os_specific.devq = cam_simq_alloc(max_transactions); + if (softs->os_specific.devq == NULL) { + DBG_ERR("cam_simq_alloc failed txns = %d\n", + max_transactions); + return PQI_STATUS_FAILURE; + } + + sim = cam_sim_alloc(smartpqi_cam_action, \ + smartpqi_poll, "smartpqi", softs, \ + card_index, &softs->os_specific.cam_lock, \ + 1, max_transactions, softs->os_specific.devq); + if (sim == NULL) { + DBG_ERR("cam_sim_alloc failed txns = %d\n", + max_transactions); + cam_simq_free(softs->os_specific.devq); + return PQI_STATUS_FAILURE; + } + + softs->os_specific.sim = sim; + mtx_lock(&softs->os_specific.cam_lock); + status = xpt_bus_register(sim, softs->os_specific.pqi_dev, 0); + if (status != CAM_SUCCESS) { + DBG_ERR("xpt_bus_register failed status=%d\n", status); + cam_sim_free(softs->os_specific.sim, FALSE); + cam_simq_free(softs->os_specific.devq); + mtx_unlock(&softs->os_specific.cam_lock); + return PQI_STATUS_FAILURE; + } + + softs->os_specific.sim_registered = TRUE; + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + DBG_ERR("xpt_create_path failed\n"); + return PQI_STATUS_FAILURE; + } + + if (xpt_create_path(&ccb->ccb_h.path, NULL, + cam_sim_path(softs->os_specific.sim), + CAM_TARGET_WILDCARD, + CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + DBG_ERR("xpt_create_path failed\n"); + xpt_free_ccb(ccb); + xpt_bus_deregister(cam_sim_path(softs->os_specific.sim)); + cam_sim_free(softs->os_specific.sim, TRUE); + mtx_unlock(&softs->os_specific.cam_lock); + return PQI_STATUS_FAILURE; + } + /* + * Callback to set the queue depth per target which is + * derived from the FW. + */ + softs->os_specific.path = ccb->ccb_h.path; + xpt_setup_ccb(&csa.ccb_h, softs->os_specific.path, 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = AC_FOUND_DEVICE; + csa.callback = smartpqi_async; + csa.callback_arg = softs; + xpt_action((union ccb *)&csa); + if (csa.ccb_h.status != CAM_REQ_CMP) { + DBG_ERR("Unable to register smartpqi_aysnc handler: %d!\n", + csa.ccb_h.status); + } + + mtx_unlock(&softs->os_specific.cam_lock); + DBG_INFO("OUT\n"); + return error; +} + +/* + * Function to deregister smartpqi sim from cam layer + */ +void deregister_sim(struct pqisrc_softstate *softs) +{ + struct ccb_setasync csa; + + DBG_FUNC("IN\n"); + + if (softs->os_specific.mtx_init) { + mtx_lock(&softs->os_specific.cam_lock); + } + + + xpt_setup_ccb(&csa.ccb_h, softs->os_specific.path, 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = smartpqi_async; + csa.callback_arg = softs; + xpt_action((union ccb *)&csa); + xpt_free_path(softs->os_specific.path); + + xpt_release_simq(softs->os_specific.sim, 0); + + xpt_bus_deregister(cam_sim_path(softs->os_specific.sim)); + softs->os_specific.sim_registered = FALSE; + + if (softs->os_specific.sim) { + cam_sim_free(softs->os_specific.sim, FALSE); + softs->os_specific.sim = NULL; + } + if (softs->os_specific.mtx_init) { + mtx_unlock(&softs->os_specific.cam_lock); + } + if (softs->os_specific.devq != NULL) { + cam_simq_free(softs->os_specific.devq); + } + if (softs->os_specific.mtx_init) { + mtx_destroy(&softs->os_specific.cam_lock); + softs->os_specific.mtx_init = FALSE; + } + + mtx_destroy(&softs->os_specific.map_lock); + + DBG_FUNC("OUT\n"); +} + +static void smartpqi_cam_action(struct cam_sim *, union ccb *); +static void smartpqi_poll(struct cam_sim *); + Property changes on: head/sys/dev/smartpqi/smartpqi_cam.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_cmd.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_cmd.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_cmd.c (revision 333019) @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* + * Function to submit the request to the adapter. + */ + +int pqisrc_submit_cmnd(pqisrc_softstate_t *softs, + ib_queue_t *ib_q, void *req) +{ + char *slot = NULL; + uint32_t offset; + iu_header_t *hdr = (iu_header_t *)req; + uint32_t iu_len = hdr->iu_length + 4 ; /* header size */ + int i = 0; + DBG_FUNC("IN\n"); + + PQI_LOCK(&ib_q->lock); + + /* Check queue full */ + if ((ib_q->pi_local + 1) % ib_q->num_elem == *(ib_q->ci_virt_addr)) { + DBG_WARN("OUT Q full\n"); + PQI_UNLOCK(&ib_q->lock); + return PQI_STATUS_QFULL; + } + + /* Get the slot */ + offset = ib_q->pi_local * ib_q->elem_size; + slot = ib_q->array_virt_addr + offset; + + /* Copy the IU */ + memcpy(slot, req, iu_len); + DBG_INFO("IU : \n"); + for(i = 0; i< iu_len; i++) + DBG_INFO(" IU [ %d ] : %x\n", i, *((unsigned char *)(slot + i))); + + /* Update the local PI */ + ib_q->pi_local = (ib_q->pi_local + 1) % ib_q->num_elem; + DBG_INFO("ib_q->pi_local : %x IU size : %d\n", + ib_q->pi_local, hdr->iu_length); + DBG_INFO("*ib_q->ci_virt_addr: %x\n", + *(ib_q->ci_virt_addr)); + + /* Inform the fw about the new IU */ + PCI_MEM_PUT32(softs, ib_q->pi_register_abs, ib_q->pi_register_offset, ib_q->pi_local); + PQI_UNLOCK(&ib_q->lock); + DBG_FUNC("OUT\n"); + return PQI_STATUS_SUCCESS; +} Property changes on: head/sys/dev/smartpqi/smartpqi_cmd.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_defines.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_defines.h (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_defines.h (revision 333019) @@ -0,0 +1,1004 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#ifndef _PQI_DEFINES_H +#define _PQI_DEFINES_H + +#define PQI_STATUS_FAILURE -1 +#define PQI_STATUS_TIMEOUT -2 +#define PQI_STATUS_QFULL -3 +#define PQI_STATUS_SUCCESS 0 + +#define PQISRC_CMD_TIMEOUT_CNT 1200000 /* 500usec * 1200000 = 5 min */ + +/* #define SHARE_EVENT_QUEUE_FOR_IO 1 */ + +#define INVALID_ELEM 0xffff +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#define PQISRC_ROUNDUP(x, y) (((x) + (y) - 1) / (y) * (y)) +#define PQISRC_DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) + +#define ALIGN_BOUNDARY(a, n) { \ + if (a % n) \ + a = a + (n - a % n); \ + } + +/* Busy wait timeout on a condition */ +#define COND_BUSYWAIT(cond, timeout /* in millisecond */) { \ + if (!(cond)) { \ + while (timeout) { \ + OS_BUSYWAIT(1000); \ + if (cond) \ + break; \ + timeout--; \ + } \ + } \ + } + +/* Wait timeout on a condition*/ +#define COND_WAIT(cond, timeout /* in millisecond */) { \ + if (!(cond)) { \ + while (timeout) { \ + OS_SLEEP(1000); \ + if (cond) \ + break; \ + timeout--; \ + } \ + } \ + } + +#define FILL_QUEUE_ARRAY_ADDR(q,virt,dma) { \ + q->array_virt_addr = virt; \ + q->array_dma_addr = dma; \ + } + +#define true 1 +#define false 0 + +enum INTR_TYPE { + LOCK_INTR, + LOCK_SLEEP +}; + +#define LOCKNAME_SIZE 32 + +#define INTR_TYPE_FIXED 0x1 +#define INTR_TYPE_MSI 0x2 +#define INTR_TYPE_MSIX 0x4 +#define SIS_ENABLE_MSIX 0x40 + +#define DMA_TO_VIRT(mem) ((mem)->virt_addr) +#define DMA_PHYS_LOW(mem) (((mem)->dma_addr) & 0x00000000ffffffff) +#define DMA_PHYS_HIGH(mem) ((((mem)->dma_addr) & 0xffffffff00000000) >> 32) + + +typedef enum REQUEST_STATUS { + REQUEST_SUCCESS = 0, + REQUEST_PENDING = -1, + REQUEST_FAILED = -2, +}REQUEST_STATUS_T; + +typedef enum IO_PATH { + AIO_PATH, + RAID_PATH +}IO_PATH_T; + +typedef enum device_type +{ + DISK_DEVICE, + TAPE_DEVICE, + ROM_DEVICE = 5, + MEDIUM_CHANGER_DEVICE = 8, + RAID_DEVICE = 0x0c, + ENCLOSURE_DEVICE, + ZBC_DEVICE = 0x14 +} device_type_t; + +typedef enum controller_state { + PQI_UP_RUNNING, + PQI_BUS_RESET, +}controller_state_t; + + +#define PQISRC_MAX_MSIX_SUPPORTED 64 + +/* SIS Specific */ +#define PQISRC_INIT_STRUCT_REVISION 9 +#define PQISRC_SECTOR_SIZE 512 +#define PQISRC_BLK_SIZE PQISRC_SECTOR_SIZE +#define PQISRC_DEFAULT_DMA_ALIGN 4 +#define PQISRC_DMA_ALIGN_MASK (PQISRC_DEFAULT_DMA_ALIGN - 1) +#define PQISRC_ERR_BUF_DMA_ALIGN 32 +#define PQISRC_ERR_BUF_ELEM_SIZE MAX(sizeof(raid_path_error_info_elem_t),sizeof(aio_path_error_info_elem_t)) +#define PQISRC_INIT_STRUCT_DMA_ALIGN 16 + +#define SIS_CMD_GET_ADAPTER_PROPERTIES 0x19 +#define SIS_CMD_GET_COMM_PREFERRED_SETTINGS 0x26 +#define SIS_CMD_GET_PQI_CAPABILITIES 0x3000 +#define SIS_CMD_INIT_BASE_STRUCT_ADDRESS 0x1b + +#define SIS_SUPPORT_EXT_OPT 0x00800000 +#define SIS_SUPPORT_PQI 0x00000004 +#define SIS_SUPPORT_PQI_RESET_QUIESCE 0x00000008 + +#define SIS_PQI_RESET_QUIESCE 0x1000000 + +#define SIS_STATUS_OK_TIMEOUT 120000 /* in milli sec, 5 sec */ + +#define SIS_CMD_COMPLETE_TIMEOUT 30000 /* in milli sec, 30 secs */ +#define SIS_POLL_START_WAIT_TIME 20000 /* in micro sec, 20 milli sec */ +#define SIS_DB_BIT_CLEAR_TIMEOUT_CNT 120000 /* 500usec * 120000 = 60 sec */ + +#define SIS_ENABLE_TIMEOUT 3000 +#define REENABLE_SIS 0x1 +#define TRIGGER_NMI_SIS 0x800000 +/*SIS Register status defines */ + +#define PQI_CTRL_KERNEL_UP_AND_RUNNING 0x80 +#define PQI_CTRL_KERNEL_PANIC 0x100 + +#define SIS_CTL_TO_HOST_DB_DISABLE_ALL 0xFFFFFFFF +#define SIS_CTL_TO_HOST_DB_CLEAR 0x00001000 +#define SIS_CMD_SUBMIT 0x00000200 /* Bit 9 */ +#define SIS_CMD_COMPLETE 0x00001000 /* Bit 12 */ +#define SIS_CMD_STATUS_SUCCESS 0x1 + +/* PQI specific */ + +/* defines */ +#define PQISRC_PQI_REG_OFFSET 0x4000 +#define PQISRC_MAX_OUTSTANDING_REQ 4096 +#define PQISRC_MAX_ADMIN_IB_QUEUE_ELEM_NUM 16 +#define PQISRC_MAX_ADMIN_OB_QUEUE_ELEM_NUM 16 + + + +#define PQI_MIN_OP_IB_QUEUE_ID 1 +#define PQI_OP_EVENT_QUEUE_ID 1 +#define PQI_MIN_OP_OB_QUEUE_ID 2 + +#define PQISRC_MAX_SUPPORTED_OP_IB_Q 128 +#define PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q (PQISRC_MAX_SUPPORTED_OP_IB_Q / 2) +#define PQISRC_MAX_SUPPORTED_OP_AIO_IB_Q (PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q) +#define PQISRC_MAX_OP_IB_QUEUE_ELEM_NUM (PQISRC_MAX_OUTSTANDING_REQ / PQISRC_MAX_SUPPORTED_OP_IB_Q) +#define PQISRC_MAX_OP_OB_QUEUE_ELEM_NUM PQISRC_MAX_OUTSTANDING_REQ +#define PQISRC_MIN_OP_OB_QUEUE_ELEM_NUM 2 +#define PQISRC_MAX_SUPPORTED_OP_OB_Q 64 +#define PQISRC_OP_MAX_IBQ_ELEM_SIZE 8 /* 8 * 16 = 128 bytes */ +#define PQISRC_OP_MIN_IBQ_ELEM_SIZE 2 /* 2 * 16 = 32 bytes */ +#define PQISRC_OP_OBQ_ELEM_SIZE 1 /* 16 bytes */ +#define PQISRC_ADMIN_IBQ_ELEM_SIZE 2 /* 2 * 16 = 32 bytes */ +#define PQISRC_INTR_COALSC_GRAN 0 +#define PQISRC_PROTO_BIT_MASK 0 +#define PQISRC_SGL_SUPPORTED_BIT_MASK 0 + +#define PQISRC_NUM_EVENT_Q_ELEM 32 +#define PQISRC_EVENT_Q_ELEM_SIZE 32 + +/* PQI Registers state status */ + +#define PQI_RESET_ACTION_RESET 0x1 +#define PQI_RESET_ACTION_COMPLETED 0x2 +#define PQI_RESET_TYPE_NO_RESET 0x0 +#define PQI_RESET_TYPE_SOFT_RESET 0x1 +#define PQI_RESET_TYPE_FIRM_RESET 0x2 +#define PQI_RESET_TYPE_HARD_RESET 0x3 + +#define PQI_RESET_POLL_INTERVAL 100000 /*100 msec*/ + +enum pqisrc_ctrl_mode{ + CTRL_SIS_MODE = 0, + CTRL_PQI_MODE +}; + +/* PQI device performing internal initialization (e.g., POST). */ +#define PQI_DEV_STATE_POWER_ON_AND_RESET 0x0 +/* Upon entry to this state PQI device initialization begins. */ +#define PQI_DEV_STATE_PQI_STATUS_AVAILABLE 0x1 +/* PQI device Standard registers are available to the driver. */ +#define PQI_DEV_STATE_ALL_REGISTERS_READY 0x2 +/* PQI device is initialized and ready to process any PCI transactions. */ +#define PQI_DEV_STATE_ADMIN_QUEUE_PAIR_READY 0x3 +/* The PQI Device Error register indicates the error. */ +#define PQI_DEV_STATE_ERROR 0x4 + +#define PQI_DEV_STATE_AT_INIT ( PQI_DEV_STATE_PQI_STATUS_AVAILABLE | \ + PQI_DEV_STATE_ALL_REGISTERS_READY | \ + PQI_DEV_STATE_ADMIN_QUEUE_PAIR_READY ) + +#define PQISRC_PQI_DEVICE_SIGNATURE "PQI DREG" +#define PQI_ADMINQ_ELEM_ARRAY_ALIGN 64 +#define PQI_ADMINQ_CI_PI_ALIGN 64 +#define PQI_OPQ_ELEM_ARRAY_ALIGN 64 +#define PQI_OPQ_CI_PI_ALIGN 4 +#define PQI_ADDR_ALIGN_MASK_64 0x3F /* lsb 6 bits */ +#define PQI_ADDR_ALIGN_MASK_4 0x3 /* lsb 2 bits */ + +#define PQISRC_PQIMODE_READY_TIMEOUT (30 * 1000 ) /* 30 secs */ +#define PQISRC_MODE_READY_POLL_INTERVAL 1000 /* 1 msec */ + +#define PRINT_PQI_SIGNATURE(sign) { int i = 0; \ + char si[9]; \ + for(i=0;i<8;i++) \ + si[i] = *((char *)&(sign)+i); \ + si[i] = '\0'; \ + DBG_INFO("Signature is %s",si); \ + } +#define PQI_CONF_TABLE_MAX_LEN ((uint16_t)~0) +#define PQI_CONF_TABLE_SIGNATURE "CFGTABLE" + +/* PQI configuration table section IDs */ +#define PQI_CONF_TABLE_SECTION_GENERAL_INFO 0 +#define PQI_CONF_TABLE_SECTION_FIRMWARE_FEATURES 1 +#define PQI_CONF_TABLE_SECTION_FIRMWARE_ERRATA 2 +#define PQI_CONF_TABLE_SECTION_DEBUG 3 +#define PQI_CONF_TABLE_SECTION_HEARTBEAT 4 + +#define CTRLR_HEARTBEAT_CNT(softs) LE_64(PCI_MEM_GET64(softs, softs->heartbeat_counter_abs_addr, softs->heartbeat_counter_off)) +#define PQI_NEW_HEARTBEAT_MECHANISM(softs) 1 + + /* pqi-2r00a table 36 */ +#define PQI_ADMIN_QUEUE_MSIX_DISABLE (0x80000000) +#define PQI_ADMIN_QUEUE_MSIX_ENABLE (0 << 31) + +#define PQI_ADMIN_QUEUE_CONF_FUNC_CREATE_Q_PAIR 0x01 +#define PQI_ADMIN_QUEUE_CONF_FUNC_DEL_Q_PAIR 0x02 +#define PQI_ADMIN_QUEUE_CONF_FUNC_STATUS_IDLE 0x00 +#define PQISRC_ADMIN_QUEUE_CREATE_TIMEOUT 1000 /* in miLLI sec, 1 sec, 100 ms is standard */ +#define PQISRC_ADMIN_QUEUE_DELETE_TIMEOUT 100 /* 100 ms is standard */ +#define PQISRC_ADMIN_CMD_RESP_TIMEOUT 3000 /* 3 sec */ +#define PQISRC_RAIDPATH_CMD_TIMEOUT 30000 /* 30 sec */ + +#define REPORT_PQI_DEV_CAP_DATA_BUF_SIZE sizeof(pqi_dev_cap_t) +#define REPORT_MANUFACTURER_INFO_DATA_BUF_SIZE 0x80 /* Data buffer size specified in bytes 0-1 of data buffer. 128 bytes. */ +/* PQI IUs */ +/* Admin IU request length not including header. */ +#define PQI_STANDARD_IU_LENGTH 0x003C /* 60 bytes. */ +#define PQI_IU_TYPE_GENERAL_ADMIN_REQUEST 0x60 +#define PQI_IU_TYPE_GENERAL_ADMIN_RESPONSE 0xe0 + +/* PQI / Vendor specific IU */ +#define PQI_FUNCTION_REPORT_DEV_CAP 0x00 +#define PQI_REQUEST_IU_TASK_MANAGEMENT 0x13 +#define PQI_IU_TYPE_RAID_PATH_IO_REQUEST 0x14 +#define PQI_IU_TYPE_AIO_PATH_IO_REQUEST 0x15 +#define PQI_REQUEST_IU_GENERAL_ADMIN 0x60 +#define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72 +#define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73 +#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81 +#define PQI_RESPONSE_IU_TASK_MANAGEMENT 0x93 +#define PQI_RESPONSE_IU_GENERAL_ADMIN 0xe0 + +#define PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS 0xf0 +#define PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS 0xf1 +#define PQI_RESPONSE_IU_RAID_PATH_IO_ERROR 0xf2 +#define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR 0xf3 +#define PQI_RESPONSE_IU_AIO_PATH_IS_OFF 0xf4 +#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT 0xf6 +#define PQI_REQUEST_HEADER_LENGTH 4 +#define PQI_FUNCTION_CREATE_OPERATIONAL_IQ 0x10 +#define PQI_FUNCTION_CREATE_OPERATIONAL_OQ 0x11 +#define PQI_FUNCTION_DELETE_OPERATIONAL_IQ 0x12 +#define PQI_FUNCTION_DELETE_OPERATIONAL_OQ 0x13 +#define PQI_FUNCTION_CHANGE_OPERATIONAL_IQ_PROP 0x14 +#define PQI_CHANGE_OP_IQ_PROP_ASSIGN_AIO 1 + +#define PQI_DEFAULT_IB_QUEUE 0 +/* Interface macros */ + +#define GET_FW_STATUS(softs) \ + (PCI_MEM_GET32(softs, &softs->ioa_reg->scratchpad3_fw_status, LEGACY_SIS_OMR)) + +#define SIS_IS_KERNEL_PANIC(softs) \ + (GET_FW_STATUS(softs) & PQI_CTRL_KERNEL_PANIC) + +#define SIS_IS_KERNEL_UP(softs) \ + (GET_FW_STATUS(softs) & PQI_CTRL_KERNEL_UP_AND_RUNNING) + +#define PQI_GET_CTRL_MODE(softs) \ + (PCI_MEM_GET32(softs, &softs->ioa_reg->scratchpad0, LEGACY_SIS_SCR0)) + +#define PQI_SAVE_CTRL_MODE(softs, mode) \ + PCI_MEM_PUT32(softs, &softs->ioa_reg->scratchpad0, LEGACY_SIS_SCR0, mode) + +#define PQISRC_MAX_TARGETID 1024 +#define PQISRC_MAX_TARGETLUN 64 + +/* Vendor specific IU Type for Event config Cmds */ +#define PQI_REQUEST_IU_REPORT_EVENT_CONFIG 0x72 +#define PQI_REQUEST_IU_SET_EVENT_CONFIG 0x73 +#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT 0xf6 +#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81 +#define PQI_MANAGEMENT_CMD_RESP_TIMEOUT 3000 +#define PQISRC_EVENT_ACK_RESP_TIMEOUT 1000 + + +/* Supported Event types by controller */ +#define PQI_NUM_SUPPORTED_EVENTS 7 + +#define PQI_EVENT_TYPE_HOTPLUG 0x1 +#define PQI_EVENT_TYPE_HARDWARE 0x2 +#define PQI_EVENT_TYPE_PHYSICAL_DEVICE 0x4 +#define PQI_EVENT_TYPE_LOGICAL_DEVICE 0x5 +#define PQI_EVENT_TYPE_AIO_STATE_CHANGE 0xfd +#define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE 0xfe +#define PQI_EVENT_TYPE_HEARTBEAT 0xff + +/* for indexing into the pending_events[] field of struct pqisrc_softstate */ +#define PQI_EVENT_HEARTBEAT 0 +#define PQI_EVENT_HOTPLUG 1 +#define PQI_EVENT_HARDWARE 2 +#define PQI_EVENT_PHYSICAL_DEVICE 3 +#define PQI_EVENT_LOGICAL_DEVICE 4 +#define PQI_EVENT_AIO_STATE_CHANGE 5 +#define PQI_EVENT_AIO_CONFIG_CHANGE 6 + +#define PQI_MAX_HEARTBEAT_REQUESTS 5 + + +/* Device flags */ +#define PQISRC_DFLAG_VALID (1 << 0) +#define PQISRC_DFLAG_CONFIGURING (1 << 1) + +#define MAX_EMBEDDED_SG_IN_FIRST_IU 4 +#define MAX_EMBEDDED_SG_IN_IU 8 +#define SG_FLAG_LAST 0x40000000 +#define SG_FLAG_CHAIN 0x80000000 + +#define IN_PQI_RESET(softs) (softs->ctlr_state & PQI_BUS_RESET) +#define DEV_GONE(dev) (!dev || (dev->invalid == true)) +#define IS_AIO_PATH(dev) (dev->aio_enabled) +#define IS_RAID_PATH(dev) (!dev->aio_enabled) + +#define DEV_RESET(dvp) (dvp->reset_in_progress) + +/* SOP data direction flags */ +#define SOP_DATA_DIR_NONE 0x00 +#define SOP_DATA_DIR_FROM_DEVICE 0x01 +#define SOP_DATA_DIR_TO_DEVICE 0x02 +#define SOP_DATA_DIR_BIDIRECTIONAL 0x03 +#define SOP_PARTIAL_DATA_BUFFER 0x04 + +#define PQISRC_DMA_VALID (1 << 0) +#define PQISRC_CMD_NO_INTR (1 << 1) + +#define SOP_TASK_ATTRIBUTE_SIMPLE 0 +#define SOP_TASK_ATTRIBUTE_HEAD_OF_QUEUE 1 +#define SOP_TASK_ATTRIBUTE_ORDERED 2 +#define SOP_TASK_ATTRIBUTE_ACA 4 + +#define SOP_TASK_MANAGEMENT_FUNCTION_COMPLETE 0x0 +#define SOP_TASK_MANAGEMENT_FUNCTION_REJECTED 0x4 +#define SOP_TASK_MANAGEMENT_FUNCTION_FAILED 0x5 +#define SOP_TASK_MANAGEMENT_FUNCTION_SUCCEEDED 0x8 +#define SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK 0x01 +#define SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK_SET 0x02 +#define SOP_TASK_MANAGEMENT_LUN_RESET 0x8 + + +/* Additional CDB bytes */ +#define PQI_ADDITIONAL_CDB_BYTES_0 0 /* 16 byte CDB */ +#define PQI_ADDITIONAL_CDB_BYTES_4 1 /* 20 byte CDB */ +#define PQI_ADDITIONAL_CDB_BYTES_8 2 /* 24 byte CDB */ +#define PQI_ADDITIONAL_CDB_BYTES_12 3 /* 28 byte CDB */ +#define PQI_ADDITIONAL_CDB_BYTES_16 4 /* 32 byte CDB */ + +#define PQI_PROTOCOL_SOP 0x0 + +#define PQI_AIO_STATUS_GOOD 0x0 +#define PQI_AIO_STATUS_CHECK_CONDITION 0x2 +#define PQI_AIO_STATUS_CONDITION_MET 0x4 +#define PQI_AIO_STATUS_DEVICE_BUSY 0x8 +#define PQI_AIO_STATUS_INT_GOOD 0x10 +#define PQI_AIO_STATUS_INT_COND_MET 0x14 +#define PQI_AIO_STATUS_RESERV_CONFLICT 0x18 +#define PQI_AIO_STATUS_CMD_TERMINATED 0x22 +#define PQI_AIO_STATUS_QUEUE_FULL 0x28 +#define PQI_AIO_STATUS_TASK_ABORTED 0x40 +#define PQI_AIO_STATUS_UNDERRUN 0x51 +#define PQI_AIO_STATUS_OVERRUN 0x75 +/* Status when Target Failure */ +#define PQI_AIO_STATUS_IO_ERROR 0x1 +#define PQI_AIO_STATUS_IO_ABORTED 0x2 +#define PQI_AIO_STATUS_IO_NO_DEVICE 0x3 +#define PQI_AIO_STATUS_INVALID_DEVICE 0x4 +#define PQI_AIO_STATUS_AIO_PATH_DISABLED 0xe + +/* Service Response */ +#define PQI_AIO_SERV_RESPONSE_COMPLETE 0 +#define PQI_AIO_SERV_RESPONSE_FAILURE 1 +#define PQI_AIO_SERV_RESPONSE_TMF_COMPLETE 2 +#define PQI_AIO_SERV_RESPONSE_TMF_SUCCEEDED 3 +#define PQI_AIO_SERV_RESPONSE_TMF_REJECTED 4 +#define PQI_AIO_SERV_RESPONSE_TMF_INCORRECT_LUN 5 + +#define PQI_TMF_WAIT_DELAY 10000000 /* 10 seconds */ + +#define PQI_RAID_STATUS_GOOD PQI_AIO_STATUS_GOOD +#define PQI_RAID_STATUS_CHECK_CONDITION PQI_AIO_STATUS_CHECK_CONDITION +#define PQI_RAID_STATUS_CONDITION_MET PQI_AIO_STATUS_CONDITION_MET +#define PQI_RAID_STATUS_DEVICE_BUSY PQI_AIO_STATUS_DEVICE_BUSY +#define PQI_RAID_STATUS_INT_GOOD PQI_AIO_STATUS_INT_GOOD +#define PQI_RAID_STATUS_INT_COND_MET PQI_AIO_STATUS_INT_COND_MET +#define PQI_RAID_STATUS_RESERV_CONFLICT PQI_AIO_STATUS_RESERV_CONFLICT +#define PQI_RAID_STATUS_CMD_TERMINATED PQI_AIO_STATUS_CMD_TERMINATED +#define PQI_RAID_STATUS_QUEUE_FULL PQI_AIO_STATUS_QUEUE_FULL +#define PQI_RAID_STATUS_TASK_ABORTED PQI_AIO_STATUS_TASK_ABORTED +#define PQI_RAID_STATUS_UNDERRUN PQI_AIO_STATUS_UNDERRUN +#define PQI_RAID_STATUS_OVERRUN PQI_AIO_STATUS_OVERRUN + +/* VPD inquiry pages */ +#define SCSI_VPD_SUPPORTED_PAGES 0x0 /* standard page */ +#define SCSI_VPD_DEVICE_ID 0x83 /* standard page */ +#define SA_VPD_PHYS_DEVICE_ID 0xc0 /* vendor-specific page */ +#define SA_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */ +#define SA_VPD_LV_IOACCEL_STATUS 0xc2 /* vendor-specific page */ +#define SA_VPD_LV_STATUS 0xc3 /* vendor-specific page */ + +#define VPD_PAGE (1 << 8) + + +/* logical volume states */ +#define SA_LV_OK 0x0 +#define SA_LV_NOT_AVAILABLE 0xb +#define SA_LV_UNDERGOING_ERASE 0xf +#define SA_LV_UNDERGOING_RPI 0x12 +#define SA_LV_PENDING_RPI 0x13 +#define SA_LV_ENCRYPTED_NO_KEY 0x14 +#define SA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER 0x15 +#define SA_LV_UNDERGOING_ENCRYPTION 0x16 +#define SA_LV_UNDERGOING_ENCRYPTION_REKEYING 0x17 +#define SA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER 0x18 +#define SA_LV_PENDING_ENCRYPTION 0x19 +#define SA_LV_PENDING_ENCRYPTION_REKEYING 0x1a +#define SA_LV_STATUS_VPD_UNSUPPORTED 0xff + +/* + * assume worst case: SATA queue depth of 31 minus 4 internal firmware commands + */ +#define PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH 27 + +/* 0 = no limit */ +#define PQI_LOGICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH 0 + + + +#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" + +#define SA_CACHE_FLUSH 0x1 +#define SA_INQUIRY 0x12 +#define SA_REPORT_LOG 0xc2 /* Report Logical LUNs */ +#define SA_REPORT_PHYS 0xc3 /* Report Physical LUNs */ +#define SA_CISS_READ 0xc0 +#define SA_GET_RAID_MAP 0xc8 + +#define SA_REPORT_LOG_EXTENDED 0x1 +#define SA_REPORT_PHYS_EXTENDED 0x2 + +#define SA_CACHE_FLUSH_BUF_LEN 4 + +#define REPORT_LUN_DEV_FLAG_AIO_ENABLED 0x8 +#define PQI_MAX_TRANSFER_SIZE (4 * 1024U * 1024U) +#define RAID_MAP_MAX_ENTRIES 1024 +#define RAID_MAP_ENCRYPTION_ENABLED 0x1 +#define PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH 27 + +#define ASC_LUN_NOT_READY 0x4 +#define ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS 0x4 +#define ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ 0x2 + + +#define OBDR_SIG_OFFSET 43 +#define OBDR_TAPE_SIG "$DR-10" +#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1) +#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN) + + +#define IOACCEL_STATUS_BYTE 4 +#define OFFLOAD_CONFIGURED_BIT 0x1 +#define OFFLOAD_ENABLED_BIT 0x2 + +#define PQI_RAID_DATA_IN_OUT_GOOD 0x0 +#define PQI_RAID_DATA_IN_OUT_UNDERFLOW 0x1 +#define PQI_RAID_DATA_IN_OUT_UNSOLICITED_ABORT 0xf3 +#define PQI_RAID_DATA_IN_OUT_ABORTED 0xf4 + +#define PQI_PHYSICAL_DEVICE_BUS 0 +#define PQI_RAID_VOLUME_BUS 1 +#define PQI_HBA_BUS 2 +#define PQI_EXTERNAL_RAID_VOLUME_BUS 3 +#define PQI_MAX_BUS PQI_EXTERNAL_RAID_VOLUME_BUS + +#define TEST_UNIT_READY 0x00 +#define SCSI_VPD_HEADER_LENGTH 64 + + +#define PQI_MAX_MULTILUN 256 +#define PQI_MAX_LOGICALS 64 +#define PQI_MAX_PHYSICALS 1024 +#define PQI_MAX_DEVICES (PQI_MAX_LOGICALS + PQI_MAX_PHYSICALS + 1) /* 1 for controller device entry */ + + +#define PQI_CTLR_INDEX (PQI_MAX_DEVICES - 1) +#define PQI_PD_INDEX(t) (t + PQI_MAX_LOGICALS) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define MAX_TARGET_DEVICES 1024 + +#define PQI_NO_MEM 2 + +typedef enum pqisrc_device_status { + DEVICE_NOT_FOUND, + DEVICE_CHANGED, + DEVICE_UNCHANGED, +} device_status_t; + +#define SA_RAID_0 0 +#define SA_RAID_4 1 +#define SA_RAID_1 2 /* also used for RAID 10 */ +#define SA_RAID_5 3 /* also used for RAID 50 */ +#define SA_RAID_51 4 +#define SA_RAID_6 5 /* also used for RAID 60 */ +#define SA_RAID_ADM 6 /* also used for RAID 1+0 ADM */ +#define SA_RAID_MAX SA_RAID_ADM +#define SA_RAID_UNKNOWN 0xff + +/* BMIC commands */ +#define BMIC_IDENTIFY_CONTROLLER 0x11 +#define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15 +#define BMIC_READ 0x26 +#define BMIC_WRITE 0x27 +#define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64 +#define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66 +#define BMIC_CACHE_FLUSH 0xc2 +#define BMIC_FLASH_FIRMWARE 0xf7 +#define BMIC_WRITE_HOST_WELLNESS 0xa5 + + +#define MASKED_DEVICE(lunid) ((lunid)[3] & 0xC0) +#define BMIC_GET_LEVEL_2_BUS(lunid) ((lunid)[7] & 0x3F) +#define BMIC_GET_LEVEL_TWO_TARGET(lunid) ((lunid)[6]) +#define BMIC_GET_DRIVE_NUMBER(lunid) \ + (((BMIC_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \ + BMIC_GET_LEVEL_TWO_TARGET((lunid))) +#define NON_DISK_PHYS_DEV(rle) \ + (((reportlun_ext_entry_t *)(rle))->device_flags & 0x1) + +#define NO_TIMEOUT ((unsigned long) -1) + +#define BMIC_DEVICE_TYPE_SATA 0x1 + +/* No of IO slots required for internal requests */ +#define PQI_RESERVED_IO_SLOTS_SYNC_REQUESTS 3 +#define PQI_RESERVED_IO_SLOTS_TMF 1 +#define PQI_RESERVED_IO_SLOTS_CNT (PQI_NUM_SUPPORTED_EVENTS + \ + PQI_RESERVED_IO_SLOTS_TMF + \ + PQI_RESERVED_IO_SLOTS_SYNC_REQUESTS) + +static inline uint16_t GET_LE16(const uint8_t *p) +{ + return p[0] | p[1] << 8; +} + +static inline uint32_t GET_LE32(const uint8_t *p) +{ + return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; +} + +static inline uint64_t GET_LE64(const uint8_t *p) +{ + return (((uint64_t)GET_LE32(p + 4) << 32) | + GET_LE32(p)); +} + +static inline uint16_t GET_BE16(const uint8_t *p) +{ + return p[0] << 8 | p[1]; +} + +static inline uint32_t GET_BE32(const uint8_t *p) +{ + return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; +} + +static inline uint64_t GET_BE64(const uint8_t *p) +{ + return (((uint64_t)GET_BE32(p) << 32) | + GET_BE32(p + 4)); +} + +static inline void PUT_BE16(uint16_t val, uint8_t *p) +{ + *p++ = val >> 8; + *p++ = val; +} + +static inline void PUT_BE32(uint32_t val, uint8_t *p) +{ + PUT_BE16(val >> 16, p); + PUT_BE16(val, p + 2); +} + +static inline void PUT_BE64(uint64_t val, uint8_t *p) +{ + PUT_BE32(val >> 32, p); + PUT_BE32(val, p + 4); +} + + +#define OS_FREEBSD +#define SIS_POLL_WAIT + +#define OS_ATTRIBUTE_PACKED __attribute__((__packed__)) +#define OS_ATTRIBUTE_ALIGNED(n) __attribute__((aligned(n))) + + +/* Management Interface */ +#define CCISS_IOC_MAGIC 'C' +#define SMARTPQI_IOCTL_BASE 'M' +#define CCISS_GETDRIVVER _IOWR(SMARTPQI_IOCTL_BASE, 0, driver_info) +#define CCISS_GETPCIINFO _IOWR(SMARTPQI_IOCTL_BASE, 1, pqi_pci_info_t) +#define SMARTPQI_PASS_THRU _IOWR(SMARTPQI_IOCTL_BASE, 2, IOCTL_Command_struct) +#define CCISS_PASSTHRU _IOWR('C', 210, IOCTL_Command_struct) +#define CCISS_REGNEWD _IO(CCISS_IOC_MAGIC, 14) + +/*IOCTL pci_info structure */ +typedef struct pqi_pci_info +{ + unsigned char bus; + unsigned char dev_fn; + unsigned short domain; + uint32_t board_id; + uint32_t chip_id; +}pqi_pci_info_t; + +typedef struct _driver_info +{ + unsigned char major_version; + unsigned char minor_version; + unsigned char release_version; + unsigned long build_revision; + unsigned long max_targets; + unsigned long max_io; + unsigned long max_transfer_length; +}driver_info, *pdriver_info; + +typedef uint8_t *passthru_buf_type_t; + + +#define PQISRC_DRIVER_MAJOR 1 +#define PQISRC_DRIVER_MINOR 0 +#define PQISRC_DRIVER_RELEASE 1 +# define PQISRC_DRIVER_REVISION 239 + +#define STR(s) # s +#define PQISRC_VERSION(a, b, c, d) STR(a.b.c-d) +#define PQISRC_DRIVER_VERSION PQISRC_VERSION(PQISRC_DRIVER_MAJOR, \ + PQISRC_DRIVER_MINOR, \ + PQISRC_DRIVER_RELEASE, \ + PQISRC_DRIVER_REVISION) + +/* End Management interface */ + +#ifdef ASSERT +#undef ASSERT +#endif + +#define ASSERT(cond) {\ + if (!(cond)) { \ + printf("Assertion failed at file %s line %d\n",__FILE__,__LINE__); \ + } \ + } + + +#define PQI_MAX_MSIX 64 /* vectors */ +#define PQI_MSI_CTX_SIZE sizeof(pqi_intr_ctx)+1 +#define IS_POLLING_REQUIRED(softs) if (cold) {\ + pqisrc_process_event_intr_src(softs, 0);\ + pqisrc_process_response_queue(softs, 1);\ + } + +#define OS_GET_TASK_ATTR(rcb) os_get_task_attr(rcb) +#define OS_FW_HEARTBEAT_TIMER_INTERVAL (5) + +typedef struct PCI_ACC_HANDLE { + bus_space_tag_t pqi_btag; + bus_space_handle_t pqi_bhandle; +} PCI_ACC_HANDLE_T; + +/* + * Legacy SIS Register definitions for the Adaptec PMC SRC/SRCv/smartraid adapters. + */ +/* accessible via BAR0 */ +#define LEGACY_SIS_IOAR 0x18 /* IOA->host interrupt register */ +#define LEGACY_SIS_IDBR 0x20 /* inbound doorbell register */ +#define LEGACY_SIS_IISR 0x24 /* inbound interrupt status register */ +#define LEGACY_SIS_OIMR 0x34 /* outbound interrupt mask register */ +#define LEGACY_SIS_ODBR_R 0x9c /* outbound doorbell register read */ +#define LEGACY_SIS_ODBR_C 0xa0 /* outbound doorbell register clear */ + +#define LEGACY_SIS_SCR0 0xb0 /* scratchpad 0 */ +#define LEGACY_SIS_OMR 0xbc /* outbound message register */ +#define LEGACY_SIS_IQUE64_L 0xc0 /* inbound queue address 64-bit (low) */ +#define LEGACY_SIS_IQUE64_H 0xc4 /* inbound queue address 64-bit (high)*/ +#define LEGACY_SIS_ODBR_MSI 0xc8 /* MSI register for sync./AIF */ +#define LEGACY_SIS_IQN_L 0xd0 /* inbound queue native mode (low) */ +#define LEGACY_SIS_IQN_H 0xd4 /* inbound queue native mode (high)*/ +#define LEGACY_SIS_MAILBOX 0x7fc60 /* mailbox (20 bytes) */ +#define LEGACY_SIS_SRCV_MAILBOX 0x1000 /* mailbox (20 bytes) */ + +#define LEGACY_SIS_ODR_SHIFT 12 /* outbound doorbell shift */ +#define LEGACY_SIS_IDR_SHIFT 9 /* inbound doorbell shift */ + + +/* + * PQI Register definitions for the smartraid adapters + */ +/* accessible via BAR0 */ +#define PQI_SIGNATURE 0x4000 +#define PQI_ADMINQ_CONFIG 0x4008 +#define PQI_ADMINQ_CAP 0x4010 +#define PQI_LEGACY_INTR_STATUS 0x4018 +#define PQI_LEGACY_INTR_MASK_SET 0x401C +#define PQI_LEGACY_INTR_MASK_CLR 0x4020 +#define PQI_DEV_STATUS 0x4040 +#define PQI_ADMIN_IBQ_PI_OFFSET 0x4048 +#define PQI_ADMIN_OBQ_CI_OFFSET 0x4050 +#define PQI_ADMIN_IBQ_ELEM_ARRAY_ADDR 0x4058 +#define PQI_ADMIN_OBQ_ELEM_ARRAY_ADDR 0x4060 +#define PQI_ADMIN_IBQ_CI_ADDR 0x4068 +#define PQI_ADMIN_OBQ_PI_ADDR 0x4070 +#define PQI_ADMINQ_PARAM 0x4078 +#define PQI_DEV_ERR 0x4080 +#define PQI_DEV_ERR_DETAILS 0x4088 +#define PQI_DEV_RESET 0x4090 +#define PQI_POWER_ACTION 0x4094 + +/* Busy wait micro seconds */ +#define OS_BUSYWAIT(x) DELAY(x) +#define OS_SLEEP(timeout) \ + DELAY(timeout); + +#define OS_HOST_WELLNESS_TIMEOUT (24 * 3600) + + +#define LE_16(x) htole16(x) +#define LE_32(x) htole32(x) +#define LE_64(x) htole64(x) +#define BE_16(x) htobe16(x) +#define BE_32(x) htobe32(x) +#define BE_64(x) htobe64(x) + +#define PQI_HWIF_SRCV 0 +#define PQI_HWIF_UNKNOWN -1 + + +#define SMART_STATE_SUSPEND (1<<0) +#define SMART_STATE_UNUSED0 (1<<1) +#define SMART_STATE_INTERRUPTS_ON (1<<2) +#define SMART_STATE_AIF_SLEEPER (1<<3) +#define SMART_STATE_RESET (1<<4) + +#define PQI_FLAG_BUSY (1<<0) +#define PQI_MSI_ENABLED (1<<1) +#define PQI_SIM_REGISTERED (1<<2) +#define PQI_MTX_INIT (1<<3) + + +#define PQI_CMD_MAPPED (1<<2) + +/* Interrupt context to get oq_id */ +typedef struct pqi_intr_ctx { + int oq_id; + device_t pqi_dev; +}pqi_intr_ctx_t; + +typedef uint8_t os_dev_info_t; + +typedef struct OS_SPECIFIC { + device_t pqi_dev; + struct resource *pqi_regs_res0; /* reg. if. window */ + int pqi_regs_rid0; /* resource ID */ + bus_dma_tag_t pqi_parent_dmat; /* parent DMA tag */ + bus_dma_tag_t pqi_buffer_dmat; + + /* controller hardware interface */ + int pqi_hwif; + struct resource *pqi_irq[PQI_MAX_MSIX]; /* interrupt */ + int pqi_irq_rid[PQI_MAX_MSIX]; + void *intrcookie[PQI_MAX_MSIX]; + bool intr_registered[PQI_MAX_MSIX]; + bool msi_enabled; /* MSI/MSI-X enabled */ + pqi_intr_ctx_t *msi_ctx; + int oq_id; + int pqi_state; + uint32_t pqi_flags; + struct mtx cam_lock; + struct mtx map_lock; + int mtx_init; + int sim_registered; + struct cam_devq *devq; + struct cam_sim *sim; + struct cam_path *path; + struct task event_task; + struct cdev *cdev; + struct callout_handle wellness_periodic; /* periodic event handling */ + struct callout_handle heartbeat_timeout_id; /* heart beat event handling */ + eventhandler_tag eh; +} OS_SPECIFIC_T; + +typedef bus_addr_t dma_addr_t; + +/* Atomic */ +typedef volatile uint64_t OS_ATOMIC64_T; +#define OS_ATOMIC64_SET(_softs, target, val) atomic_set_long(&(_softs)->target, val) +#define OS_ATOMIC64_READ(_softs, target) atomic_load_acq_64(&(_softs)->target) +#define OS_ATOMIC64_INC(_softs, target) atomic_add_64(&(_softs)->target, 1) + +/* Register access macros */ +#define PCI_MEM_GET32( _softs, _absaddr, _offset ) \ + bus_space_read_4(_softs->pci_mem_handle.pqi_btag, \ + _softs->pci_mem_handle.pqi_bhandle, _offset) + +#define PCI_MEM_GET64( _softs, _absaddr, _offset ) \ + bus_space_read_8(_softs->pci_mem_handle.pqi_btag, \ + _softs->pci_mem_handle.pqi_bhandle, _offset) + +#define PCI_MEM_PUT32( _softs, _absaddr, _offset, _val ) \ + bus_space_write_4(_softs->pci_mem_handle.pqi_btag, \ + _softs->pci_mem_handle.pqi_bhandle, _offset, _val) + +#define PCI_MEM_PUT64( _softs, _absaddr, _offset, _val ) \ + bus_space_write_8(_softs->pci_mem_handle.pqi_btag, \ + _softs->pci_mem_handle.pqi_bhandle, _offset, _val) + +#define PCI_MEM_GET_BUF(_softs, _absaddr, _offset, buf, size) \ + bus_space_read_region_1(_softs->pci_mem_handle.pqi_btag,\ + _softs->pci_mem_handle.pqi_bhandle, _offset, buf, size) + +/* Lock */ +typedef struct mtx OS_LOCK_T; +typedef struct sema OS_SEMA_LOCK_T; + +#define OS_ACQUIRE_SPINLOCK(_lock) mtx_lock_spin(_lock) +#define OS_RELEASE_SPINLOCK(_lock) mtx_unlock_spin(_lock) + +#define PQI_LOCK(_lock) OS_ACQUIRE_SPINLOCK(_lock) +#define PQI_UNLOCK(_lock) OS_RELEASE_SPINLOCK(_lock) + +#define OS_INIT_PQILOCK(_softs,_lock,_lockname) os_init_spinlock(_softs,_lock,_lockname) +#define OS_UNINIT_PQILOCK(_lock) os_uninit_spinlock(_lock) + +#define OS_GET_CDBP(rcb) ((rcb->cm_ccb->ccb_h.flags & CAM_CDB_POINTER) ? rcb->cm_ccb->csio.cdb_io.cdb_ptr : rcb->cm_ccb->csio.cdb_io.cdb_bytes) +#define GET_SCSI_BUFFLEN(rcb) (rcb->cm_ccb->csio.dxfer_len) + +#define OS_GET_IO_QINDEX(softs,rcb) curcpu % softs->num_op_obq +#define OS_GET_IO_RESP_QID(softs,rcb) (softs->op_ob_q[(OS_GET_IO_QINDEX(softs,rcb))].q_id) +#define OS_GET_IO_REQ_QINDEX(softs,rcb) OS_GET_IO_QINDEX(softs,rcb) +#define OS_GET_TMF_RESP_QID OS_GET_IO_RESP_QID +#define OS_GET_TMF_REQ_QINDEX OS_GET_IO_REQ_QINDEX +/* sg elements addr, len, flags */ +#define OS_GET_IO_SG_COUNT(rcb) rcb->nseg +#define OS_GET_IO_SG_ADDR(rcb,i) rcb->sgt[i].addr +#define OS_GET_IO_SG_LEN(rcb,i) rcb->sgt[i].len + +/* scsi commands used in pqilib for RAID bypass*/ +#define SCMD_READ_6 READ_6 +#define SCMD_WRITE_6 WRITE_6 +#define SCMD_READ_10 READ_10 +#define SCMD_WRITE_10 WRITE_10 +#define SCMD_READ_12 READ_12 +#define SCMD_WRITE_12 WRITE_12 +#define SCMD_READ_16 READ_16 +#define SCMD_WRITE_16 WRITE_16 + +/* Debug facility */ + +#define PQISRC_LOG_LEVEL 0x30 + +static int logging_level = PQISRC_LOG_LEVEL; + +#define PQISRC_FLAGS_MASK 0x0000ffff +#define PQISRC_FLAGS_INIT 0x00000001 +#define PQISRC_FLAGS_INFO 0x00000002 +#define PQISRC_FLAGS_FUNC 0x00000004 +#define PQISRC_FLAGS_TRACEIO 0x00000008 +#define PQISRC_FLAGS_WARN 0x00000010 +#define PQISRC_FLAGS_ERROR 0x00000020 + + +#define DBG_INIT(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_INIT) { \ + printf("[INIT]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \ + } \ + }while(0); + +#define DBG_INFO(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_INFO) { \ + printf("[INFO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \ + } \ + }while(0); + +#define DBG_FUNC(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_FUNC) { \ + printf("[FUNC]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \ + } \ + }while(0); + +#define DBG_TRACEIO(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_TRACEIO) { \ + printf("[TRACEIO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \ + } \ + }while(0); + +#define DBG_WARN(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_WARN) { \ + printf("[WARN]:[%u:%u.%u][CPU %d][%s][%d]:"fmt,softs->bus_id,softs->device_id,softs->func_id,curcpu,__func__,__LINE__,##args);\ + } \ + }while(0); + +#define DBG_ERR(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_ERROR) { \ + printf("[ERROR]::[%u:%u.%u][CPU %d][%s][%d]:"fmt,softs->bus_id,softs->device_id,softs->func_id,curcpu,__func__,__LINE__,##args); \ + } \ + }while(0); +#define DBG_IO(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_TRACEIO) { \ + printf("[IO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \ + } \ + }while(0); + +#define DBG_ERR_BTL(device,fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_ERROR) { \ + printf("[ERROR]::[%u:%u.%u][%u,%u,%u][CPU %d][%s][%d]:"fmt, softs->bus_id, softs->device_id, softs->func_id, device->bus, device->target, device->lun,curcpu,__func__,__LINE__,##args); \ + } \ + }while(0); + +#define DBG_WARN_BTL(device,fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_WARN) { \ + printf("[WARN]:[%u:%u.%u][%u,%u,%u][CPU %d][%s][%d]:"fmt, softs->bus_id, softs->device_id, softs->func_id, device->bus, device->target, device->lun,curcpu,__func__,__LINE__,##args);\ + } \ + }while(0); + +#endif // _PQI_DEFINES_H Property changes on: head/sys/dev/smartpqi/smartpqi_defines.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_discovery.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_discovery.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_discovery.c (revision 333019) @@ -0,0 +1,1806 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* Validate the scsi sense response code */ +static inline boolean_t pqisrc_scsi_sense_valid(const struct sense_header_scsi *sshdr) +{ + DBG_FUNC("IN\n"); + + if (!sshdr) + return false; + + DBG_FUNC("OUT\n"); + + return (sshdr->response_code & 0x70) == 0x70; +} + +/* Update scsi sense info to a local buffer*/ +boolean_t pqisrc_update_scsi_sense(const uint8_t *buff, int len, + struct sense_header_scsi *header) +{ + + DBG_FUNC("IN\n"); + + if (!buff || !len) + return false; + + memset(header, 0, sizeof(struct sense_header_scsi)); + + header->response_code = (buff[0] & 0x7f); + + if (!pqisrc_scsi_sense_valid(header)) + return false; + + if (header->response_code >= 0x72) { + /* descriptor format */ + if (len > 1) + header->sense_key = (buff[1] & 0xf); + if (len > 2) + header->asc = buff[2]; + if (len > 3) + header->ascq = buff[3]; + if (len > 7) + header->additional_length = buff[7]; + } else { + /* fixed format */ + if (len > 2) + header->sense_key = (buff[2] & 0xf); + if (len > 7) { + len = (len < (buff[7] + 8)) ? + len : (buff[7] + 8); + if (len > 12) + header->asc = buff[12]; + if (len > 13) + header->ascq = buff[13]; + } + } + + DBG_FUNC("OUT\n"); + + return true; +} + +/* + * Function used to build the internal raid request and analyze the response + */ +int pqisrc_build_send_raid_request(pqisrc_softstate_t *softs, pqisrc_raid_req_t *request, + void *buff, size_t datasize, uint8_t cmd, uint16_t vpd_page, uint8_t *scsi3addr, + raid_path_error_info_elem_t *error_info) +{ + + uint8_t *cdb; + int ret = PQI_STATUS_SUCCESS; + uint32_t tag = 0; + struct dma_mem device_mem; + sgt_t *sgd; + + ib_queue_t *ib_q = &softs->op_raid_ib_q[PQI_DEFAULT_IB_QUEUE]; + ob_queue_t *ob_q = &softs->op_ob_q[PQI_DEFAULT_IB_QUEUE]; + + rcb_t *rcb = NULL; + + DBG_FUNC("IN\n"); + + memset(&device_mem, 0, sizeof(struct dma_mem)); + + /* for TUR datasize: 0 buff: NULL */ + if (datasize) { + device_mem.tag = "device_mem"; + device_mem.size = datasize; + device_mem.align = PQISRC_DEFAULT_DMA_ALIGN; + + ret = os_dma_mem_alloc(softs, &device_mem); + + if (ret) { + DBG_ERR("failed to allocate dma memory for device_mem return code %d\n", ret); + return ret; + } + + sgd = (sgt_t *)&request->sg_descriptors[0]; + + sgd->addr = device_mem.dma_addr; + sgd->len = datasize; + sgd->flags = SG_FLAG_LAST; + + } + + /* Build raid path request */ + request->header.iu_type = PQI_IU_TYPE_RAID_PATH_IO_REQUEST; + + request->header.iu_length = LE_16(offsetof(pqisrc_raid_req_t, + sg_descriptors[1]) - PQI_REQUEST_HEADER_LENGTH); + request->buffer_length = LE_32(datasize); + memcpy(request->lun_number, scsi3addr, sizeof(request->lun_number)); + request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; + request->additional_cdb_bytes_usage = PQI_ADDITIONAL_CDB_BYTES_0; + + cdb = request->cdb; + + switch (cmd) { + case SA_INQUIRY: + request->data_direction = SOP_DATA_DIR_TO_DEVICE; + cdb[0] = SA_INQUIRY; + if (vpd_page & VPD_PAGE) { + cdb[1] = 0x1; + cdb[2] = (uint8_t)vpd_page; + } + cdb[4] = (uint8_t)datasize; + break; + case SA_REPORT_LOG: + case SA_REPORT_PHYS: + request->data_direction = SOP_DATA_DIR_TO_DEVICE; + cdb[0] = cmd; + if (cmd == SA_REPORT_PHYS) + cdb[1] = SA_REPORT_PHYS_EXTENDED; + else + cdb[1] = SA_REPORT_LOG_EXTENDED; + cdb[8] = (uint8_t)((datasize) >> 8); + cdb[9] = (uint8_t)datasize; + break; + case TEST_UNIT_READY: + request->data_direction = SOP_DATA_DIR_NONE; + break; + case SA_GET_RAID_MAP: + request->data_direction = SOP_DATA_DIR_TO_DEVICE; + cdb[0] = SA_CISS_READ; + cdb[1] = cmd; + cdb[8] = (uint8_t)((datasize) >> 8); + cdb[9] = (uint8_t)datasize; + break; + case SA_CACHE_FLUSH: + request->data_direction = SOP_DATA_DIR_FROM_DEVICE; + cdb[0] = BMIC_WRITE; + cdb[6] = BMIC_CACHE_FLUSH; + cdb[7] = (uint8_t)((datasize) << 8); + cdb[8] = (uint8_t)((datasize) >> 8); + break; + case BMIC_IDENTIFY_CONTROLLER: + case BMIC_IDENTIFY_PHYSICAL_DEVICE: + request->data_direction = SOP_DATA_DIR_TO_DEVICE; + cdb[0] = BMIC_READ; + cdb[6] = cmd; + cdb[7] = (uint8_t)((datasize) << 8); + cdb[8] = (uint8_t)((datasize) >> 8); + break; + case BMIC_WRITE_HOST_WELLNESS: + request->data_direction = SOP_DATA_DIR_FROM_DEVICE; + memcpy(device_mem.virt_addr, buff, datasize); + cdb[0] = BMIC_WRITE; + cdb[6] = cmd; + cdb[7] = (uint8_t)((datasize) << 8); + cdb[8] = (uint8_t)((datasize) >> 8); + break; + case BMIC_SENSE_SUBSYSTEM_INFORMATION: + request->data_direction = SOP_DATA_DIR_TO_DEVICE; + cdb[0] = BMIC_READ; + cdb[6] = cmd; + cdb[7] = (uint8_t)((datasize) << 8); + cdb[8] = (uint8_t)((datasize) >> 8); + break; + default: + DBG_ERR("unknown command 0x%x", cmd); + break; + } + + tag = pqisrc_get_tag(&softs->taglist); + if (INVALID_ELEM == tag) { + DBG_ERR("Tag not available\n"); + ret = PQI_STATUS_FAILURE; + goto err_notag; + } + + ((pqisrc_raid_req_t *)request)->request_id = tag; + ((pqisrc_raid_req_t *)request)->error_index = ((pqisrc_raid_req_t *)request)->request_id; + ((pqisrc_raid_req_t *)request)->response_queue_id = ob_q->q_id; + rcb = &softs->rcb[tag]; + rcb->success_cmp_callback = pqisrc_process_internal_raid_response_success; + rcb->error_cmp_callback = pqisrc_process_internal_raid_response_error; + + rcb->req_pending = true; + rcb->tag = tag; + /* Submit Command */ + ret = pqisrc_submit_cmnd(softs, ib_q, request); + + if (ret != PQI_STATUS_SUCCESS) { + DBG_ERR("Unable to submit command\n"); + goto err_out; + } + + ret = pqisrc_wait_on_condition(softs, rcb); + if (ret != PQI_STATUS_SUCCESS) { + DBG_ERR("Internal RAID request timed out: cmd : 0x%c\n", cmd); + goto err_out; + } + + if (datasize) { + if (buff) { + memcpy(buff, device_mem.virt_addr, datasize); + } + os_dma_mem_free(softs, &device_mem); + } + + ret = rcb->status; + if (ret) { + if(error_info) { + memcpy(error_info, + rcb->error_info, + sizeof(*error_info)); + + if (error_info->data_out_result == + PQI_RAID_DATA_IN_OUT_UNDERFLOW) { + ret = PQI_STATUS_SUCCESS; + } + else{ + DBG_INFO("Error!! Bus=%u Target=%u, Cmd=0x%x," + "Ret=%d\n", BMIC_GET_LEVEL_2_BUS(scsi3addr), + BMIC_GET_LEVEL_TWO_TARGET(scsi3addr), + cmd, ret); + ret = PQI_STATUS_FAILURE; + } + } + } else { + if(error_info) { + ret = PQI_STATUS_SUCCESS; + memset(error_info, 0, sizeof(*error_info)); + } + } + + os_reset_rcb(rcb); + pqisrc_put_tag(&softs->taglist, ((pqisrc_raid_req_t *)request)->request_id); + DBG_FUNC("OUT\n"); + return ret; + +err_out: + DBG_ERR("Error!! Bus=%u Target=%u, Cmd=0x%x, Ret=%d\n", + BMIC_GET_LEVEL_2_BUS(scsi3addr), BMIC_GET_LEVEL_TWO_TARGET(scsi3addr), + cmd, ret); + os_reset_rcb(rcb); + pqisrc_put_tag(&softs->taglist, ((pqisrc_raid_req_t *)request)->request_id); +err_notag: + if (datasize) + os_dma_mem_free(softs, &device_mem); + DBG_FUNC("FAILED \n"); + return ret; +} + +/* common function used to send report physical and logical luns cmnds*/ +static int pqisrc_report_luns(pqisrc_softstate_t *softs, uint8_t cmd, + void *buff, size_t buf_len) +{ + int ret; + pqisrc_raid_req_t request; + + DBG_FUNC("IN\n"); + + memset(&request, 0, sizeof(request)); + ret = pqisrc_build_send_raid_request(softs, &request, buff, + buf_len, cmd, 0, (uint8_t *)RAID_CTLR_LUNID, NULL); + + DBG_FUNC("OUT\n"); + + return ret; +} + +/* subroutine used to get physical and logical luns of the device */ +static int pqisrc_get_physical_logical_luns(pqisrc_softstate_t *softs, uint8_t cmd, + reportlun_data_ext_t **buff, size_t *data_length) +{ + int ret; + size_t list_len; + size_t data_len; + size_t new_lun_list_length; + reportlun_data_ext_t *lun_data; + reportlun_header_t report_lun_header; + + DBG_FUNC("IN\n"); + + ret = pqisrc_report_luns(softs, cmd, &report_lun_header, + sizeof(report_lun_header)); + + if (ret) { + DBG_ERR("failed return code: %d\n", ret); + return ret; + } + list_len = BE_32(report_lun_header.list_length); + +retry: + data_len = sizeof(reportlun_header_t) + list_len; + *data_length = data_len; + + lun_data = os_mem_alloc(softs, data_len); + + if (!lun_data) { + DBG_ERR("failed to allocate memory for lun_data\n"); + return PQI_STATUS_FAILURE; + } + + if (list_len == 0) { + DBG_INFO("list_len is 0\n"); + memcpy(lun_data, &report_lun_header, sizeof(report_lun_header)); + goto out; + } + + ret = pqisrc_report_luns(softs, cmd, lun_data, data_len); + + if (ret) { + DBG_ERR("error\n"); + goto error; + } + + new_lun_list_length = BE_32(lun_data->header.list_length); + + if (new_lun_list_length > list_len) { + list_len = new_lun_list_length; + os_mem_free(softs, (void *)lun_data, data_len); + goto retry; + } + +out: + *buff = lun_data; + DBG_FUNC("OUT\n"); + return 0; + +error: + os_mem_free(softs, (void *)lun_data, data_len); + DBG_ERR("FAILED\n"); + return ret; +} + +/* + * Function used to get physical and logical device list + */ +static int pqisrc_get_phys_log_device_list(pqisrc_softstate_t *softs, + reportlun_data_ext_t **physical_dev_list, + reportlun_data_ext_t **logical_dev_list, + size_t *phys_data_length, + size_t *log_data_length) +{ + int ret = PQI_STATUS_SUCCESS; + size_t logical_list_length; + size_t logdev_data_length; + size_t data_length; + reportlun_data_ext_t *local_logdev_list; + reportlun_data_ext_t *logdev_data; + reportlun_header_t report_lun_header; + + + DBG_FUNC("IN\n"); + + ret = pqisrc_get_physical_logical_luns(softs, SA_REPORT_PHYS, physical_dev_list, phys_data_length); + if (ret) { + DBG_ERR("report physical LUNs failed"); + return ret; + } + + ret = pqisrc_get_physical_logical_luns(softs, SA_REPORT_LOG, logical_dev_list, log_data_length); + if (ret) { + DBG_ERR("report logical LUNs failed"); + return ret; + } + + + logdev_data = *logical_dev_list; + + if (logdev_data) { + logical_list_length = + BE_32(logdev_data->header.list_length); + } else { + memset(&report_lun_header, 0, sizeof(report_lun_header)); + logdev_data = + (reportlun_data_ext_t *)&report_lun_header; + logical_list_length = 0; + } + + logdev_data_length = sizeof(reportlun_header_t) + + logical_list_length; + + /* Adding LOGICAL device entry for controller */ + local_logdev_list = os_mem_alloc(softs, + logdev_data_length + sizeof(reportlun_ext_entry_t)); + if (!local_logdev_list) { + data_length = *log_data_length; + os_mem_free(softs, (char *)*logical_dev_list, data_length); + *logical_dev_list = NULL; + return PQI_STATUS_FAILURE; + } + + memcpy(local_logdev_list, logdev_data, logdev_data_length); + memset((uint8_t *)local_logdev_list + logdev_data_length, 0, + sizeof(reportlun_ext_entry_t)); + local_logdev_list->header.list_length = BE_32(logical_list_length + + sizeof(reportlun_ext_entry_t)); + data_length = *log_data_length; + os_mem_free(softs, (char *)*logical_dev_list, data_length); + *log_data_length = logdev_data_length + sizeof(reportlun_ext_entry_t); + *logical_dev_list = local_logdev_list; + + DBG_FUNC("OUT\n"); + + return ret; +} + +/* Subroutine used to set Bus-Target-Lun for the requested device */ +static inline void pqisrc_set_btl(pqi_scsi_dev_t *device, + int bus, int target, int lun) +{ + DBG_FUNC("IN\n"); + + device->bus = bus; + device->target = target; + device->lun = lun; + + DBG_FUNC("OUT\n"); +} + +inline boolean_t pqisrc_is_external_raid_device(pqi_scsi_dev_t *device) +{ + return device->is_external_raid_device; +} + +static inline boolean_t pqisrc_is_external_raid_addr(uint8_t *scsi3addr) +{ + return scsi3addr[2] != 0; +} + +/* Function used to assign Bus-Target-Lun for the requested device */ +static void pqisrc_assign_btl(pqi_scsi_dev_t *device) +{ + uint8_t *scsi3addr; + uint32_t lunid; + uint32_t bus; + uint32_t target; + uint32_t lun; + DBG_FUNC("IN\n"); + + scsi3addr = device->scsi3addr; + lunid = GET_LE32(scsi3addr); + + if (pqisrc_is_hba_lunid(scsi3addr)) { + /* The specified device is the controller. */ + pqisrc_set_btl(device, PQI_HBA_BUS, PQI_CTLR_INDEX, lunid & 0x3fff); + device->target_lun_valid = true; + return; + } + + if (pqisrc_is_logical_device(device)) { + if (pqisrc_is_external_raid_device(device)) { + DBG_INFO("External Raid Device!!!"); + bus = PQI_EXTERNAL_RAID_VOLUME_BUS; + target = (lunid >> 16) & 0x3fff; + lun = lunid & 0xff; + } else { + bus = PQI_RAID_VOLUME_BUS; + lun = 0; + target = lunid & 0x3fff; + } + pqisrc_set_btl(device, bus, target, lun); + device->target_lun_valid = true; + return; + } + + /* physical device */ + pqisrc_set_btl(device, PQI_PHYSICAL_DEVICE_BUS, PQI_PD_INDEX(scsi3addr[6]), 0); + + DBG_FUNC("OUT\n"); +} + +/* Build and send the internal INQUIRY command to particular device */ +static int pqisrc_send_scsi_inquiry(pqisrc_softstate_t *softs, + uint8_t *scsi3addr, uint16_t vpd_page, uint8_t *buff, int buf_len) +{ + int ret = PQI_STATUS_SUCCESS; + pqisrc_raid_req_t request; + raid_path_error_info_elem_t error_info; + + DBG_FUNC("IN\n"); + + memset(&request, 0, sizeof(request)); + ret = pqisrc_build_send_raid_request(softs, &request, buff, buf_len, + SA_INQUIRY, vpd_page, scsi3addr, &error_info); + + DBG_FUNC("OUT\n"); + return ret; +} + +/* Function used to parse the sense information from response */ +static void pqisrc_fetch_sense_info(const uint8_t *sense_data, + unsigned sense_data_length, uint8_t *sense_key, uint8_t *asc, uint8_t *ascq) +{ + struct sense_header_scsi header; + + DBG_FUNC("IN\n"); + + *sense_key = 0; + *ascq = 0; + *asc = 0; + + if (pqisrc_update_scsi_sense(sense_data, sense_data_length, &header)) { + *sense_key = header.sense_key; + *asc = header.asc; + *ascq = header.ascq; + } + + DBG_INFO("sense_key: %x asc: %x ascq: %x\n", *sense_key, *asc, *ascq); + + DBG_FUNC("OUT\n"); +} + +/* Function used to validate volume offline status */ +static uint8_t pqisrc_get_volume_offline_status(pqisrc_softstate_t *softs, + uint8_t *scsi3addr) +{ + int ret = PQI_STATUS_SUCCESS; + uint8_t status = SA_LV_STATUS_VPD_UNSUPPORTED; + uint8_t size; + uint8_t *buff = NULL; + + DBG_FUNC("IN\n"); + + buff = os_mem_alloc(softs, 64); + if (!buff) + return PQI_STATUS_FAILURE; + + /* Get the size of the VPD return buff. */ + ret = pqisrc_send_scsi_inquiry(softs, scsi3addr, VPD_PAGE | SA_VPD_LV_STATUS, + buff, SCSI_VPD_HEADER_LENGTH); + + if (ret) + goto out; + + size = buff[3]; + + /* Now get the whole VPD buff. */ + ret = pqisrc_send_scsi_inquiry(softs, scsi3addr, VPD_PAGE | SA_VPD_LV_STATUS, + buff, size + SCSI_VPD_HEADER_LENGTH); + if (ret) + goto out; + + status = buff[4]; + +out: + os_mem_free(softs, (char *)buff, 64); + DBG_FUNC("OUT\n"); + + return status; +} + + +/* Determine offline status of a volume. Returns appropriate SA_LV_* status.*/ +static uint8_t pqisrc_get_dev_vol_status(pqisrc_softstate_t *softs, + uint8_t *scsi3addr) +{ + int ret = PQI_STATUS_SUCCESS; + uint8_t *sense_data; + unsigned sense_data_len; + uint8_t sense_key; + uint8_t asc; + uint8_t ascq; + uint8_t off_status; + uint8_t scsi_status; + pqisrc_raid_req_t request; + raid_path_error_info_elem_t error_info; + + DBG_FUNC("IN\n"); + + memset(&request, 0, sizeof(request)); + ret = pqisrc_build_send_raid_request(softs, &request, NULL, 0, + TEST_UNIT_READY, 0, scsi3addr, &error_info); + + if (ret) + goto error; + sense_data = error_info.data; + sense_data_len = LE_16(error_info.sense_data_len); + + if (sense_data_len > sizeof(error_info.data)) + sense_data_len = sizeof(error_info.data); + + pqisrc_fetch_sense_info(sense_data, sense_data_len, &sense_key, &asc, + &ascq); + + scsi_status = error_info.status; + + /* scsi status: "CHECK CONDN" / SK: "not ready" ? */ + if (scsi_status != 2 || + sense_key != 2 || + asc != ASC_LUN_NOT_READY) { + return SA_LV_OK; + } + + /* Determine the reason for not ready state. */ + off_status = pqisrc_get_volume_offline_status(softs, scsi3addr); + + DBG_INFO("offline_status 0x%x\n", off_status); + + /* Keep volume offline in certain cases. */ + switch (off_status) { + case SA_LV_UNDERGOING_ERASE: + case SA_LV_NOT_AVAILABLE: + case SA_LV_UNDERGOING_RPI: + case SA_LV_PENDING_RPI: + case SA_LV_ENCRYPTED_NO_KEY: + case SA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER: + case SA_LV_UNDERGOING_ENCRYPTION: + case SA_LV_UNDERGOING_ENCRYPTION_REKEYING: + case SA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER: + return off_status; + case SA_LV_STATUS_VPD_UNSUPPORTED: + /* + * If the VPD status page isn't available, + * use ASC/ASCQ to determine state. + */ + if (ascq == ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS || + ascq == ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ) + return off_status; + break; + } + + DBG_FUNC("OUT\n"); + + return SA_LV_OK; + +error: + return SA_LV_STATUS_VPD_UNSUPPORTED; +} + +/* Validate the RAID map parameters */ +static int pqisrc_raid_map_validation(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device, pqisrc_raid_map_t *raid_map) +{ + char *error_msg; + uint32_t raidmap_size; + uint32_t r5or6_blocks_per_row; + unsigned phys_dev_num; + unsigned num_raidmap_entries; + + DBG_FUNC("IN\n"); + + raidmap_size = LE_32(raid_map->structure_size); + if (raidmap_size < offsetof(pqisrc_raid_map_t, dev_data)) { + error_msg = "RAID map too small\n"; + goto error; + } + + if (raidmap_size > sizeof(*raid_map)) { + error_msg = "RAID map too large\n"; + goto error; + } + + phys_dev_num = LE_16(raid_map->layout_map_count) * + (LE_16(raid_map->data_disks_per_row) + + LE_16(raid_map->metadata_disks_per_row)); + num_raidmap_entries = phys_dev_num * + LE_16(raid_map->row_cnt); + + if (num_raidmap_entries > RAID_MAP_MAX_ENTRIES) { + error_msg = "invalid number of map entries in RAID map\n"; + goto error; + } + + if (device->raid_level == SA_RAID_1) { + if (LE_16(raid_map->layout_map_count) != 2) { + error_msg = "invalid RAID-1 map\n"; + goto error; + } + } else if (device->raid_level == SA_RAID_ADM) { + if (LE_16(raid_map->layout_map_count) != 3) { + error_msg = "invalid RAID-1(ADM) map\n"; + goto error; + } + } else if ((device->raid_level == SA_RAID_5 || + device->raid_level == SA_RAID_6) && + LE_16(raid_map->layout_map_count) > 1) { + /* RAID 50/60 */ + r5or6_blocks_per_row = + LE_16(raid_map->strip_size) * + LE_16(raid_map->data_disks_per_row); + if (r5or6_blocks_per_row == 0) { + error_msg = "invalid RAID-5 or RAID-6 map\n"; + goto error; + } + } + + DBG_FUNC("OUT\n"); + + return 0; + +error: + DBG_ERR("%s\n", error_msg); + return PQI_STATUS_FAILURE; +} + +/* Get device raidmap for the requested device */ +static int pqisrc_get_device_raidmap(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + int ret = PQI_STATUS_SUCCESS; + pqisrc_raid_req_t request; + pqisrc_raid_map_t *raid_map; + + DBG_FUNC("IN\n"); + + raid_map = os_mem_alloc(softs, sizeof(*raid_map)); + if (!raid_map) + return PQI_STATUS_FAILURE; + + memset(&request, 0, sizeof(request)); + ret = pqisrc_build_send_raid_request(softs, &request, raid_map, sizeof(*raid_map), + SA_GET_RAID_MAP, 0, device->scsi3addr, NULL); + + if (ret) { + DBG_ERR("error in build send raid req ret=%d\n", ret); + goto err_out; + } + + ret = pqisrc_raid_map_validation(softs, device, raid_map); + if (ret) { + DBG_ERR("error in raid map validation ret=%d\n", ret); + goto err_out; + } + + device->raid_map = raid_map; + DBG_FUNC("OUT\n"); + return 0; + +err_out: + os_mem_free(softs, (char*)raid_map, sizeof(*raid_map)); + DBG_FUNC("FAILED \n"); + return ret; +} + +/* Get device ioaccel_status to validate the type of device */ +static void pqisrc_get_dev_ioaccel_status(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + int ret = PQI_STATUS_SUCCESS; + uint8_t *buff; + uint8_t ioaccel_status; + + DBG_FUNC("IN\n"); + + buff = os_mem_alloc(softs, 64); + if (!buff) + return; + + ret = pqisrc_send_scsi_inquiry(softs, device->scsi3addr, + VPD_PAGE | SA_VPD_LV_IOACCEL_STATUS, buff, 64); + if (ret) { + DBG_ERR("error in send scsi inquiry ret=%d\n", ret); + goto err_out; + } + + ioaccel_status = buff[IOACCEL_STATUS_BYTE]; + device->offload_config = + !!(ioaccel_status & OFFLOAD_CONFIGURED_BIT); + + if (device->offload_config) { + device->offload_enabled_pending = + !!(ioaccel_status & OFFLOAD_ENABLED_BIT); + if (pqisrc_get_device_raidmap(softs, device)) + device->offload_enabled_pending = false; + } + + DBG_INFO("offload_config: 0x%x offload_enabled_pending: 0x%x \n", + device->offload_config, device->offload_enabled_pending); + +err_out: + os_mem_free(softs, (char*)buff, 64); + DBG_FUNC("OUT\n"); +} + +/* Get RAID level of requested device */ +static void pqisrc_get_dev_raid_level(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + uint8_t raid_level; + uint8_t *buff; + + DBG_FUNC("IN\n"); + + raid_level = SA_RAID_UNKNOWN; + + buff = os_mem_alloc(softs, 64); + if (buff) { + int ret; + ret = pqisrc_send_scsi_inquiry(softs, device->scsi3addr, + VPD_PAGE | SA_VPD_LV_DEVICE_GEOMETRY, buff, 64); + if (ret == 0) { + raid_level = buff[8]; + if (raid_level > SA_RAID_MAX) + raid_level = SA_RAID_UNKNOWN; + } + os_mem_free(softs, (char*)buff, 64); + } + + device->raid_level = raid_level; + DBG_INFO("RAID LEVEL: %x \n", raid_level); + DBG_FUNC("OUT\n"); +} + +/* Parse the inquiry response and determine the type of device */ +static int pqisrc_get_dev_data(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + int ret = PQI_STATUS_SUCCESS; + uint8_t *inq_buff; + + DBG_FUNC("IN\n"); + + inq_buff = os_mem_alloc(softs, OBDR_TAPE_INQ_SIZE); + if (!inq_buff) + return PQI_STATUS_FAILURE; + + /* Send an inquiry to the device to see what it is. */ + ret = pqisrc_send_scsi_inquiry(softs, device->scsi3addr, 0, inq_buff, + OBDR_TAPE_INQ_SIZE); + if (ret) + goto err_out; + pqisrc_sanitize_inquiry_string(&inq_buff[8], 8); + pqisrc_sanitize_inquiry_string(&inq_buff[16], 16); + + device->devtype = inq_buff[0] & 0x1f; + memcpy(device->vendor, &inq_buff[8], + sizeof(device->vendor)); + memcpy(device->model, &inq_buff[16], + sizeof(device->model)); + DBG_INFO("DEV_TYPE: %x VENDOR: %s MODEL: %s\n", device->devtype, device->vendor, device->model); + + if (pqisrc_is_logical_device(device) && device->devtype == DISK_DEVICE) { + if (pqisrc_is_external_raid_device(device)) { + device->raid_level = SA_RAID_UNKNOWN; + device->volume_status = SA_LV_OK; + device->volume_offline = false; + } + else { + pqisrc_get_dev_raid_level(softs, device); + pqisrc_get_dev_ioaccel_status(softs, device); + device->volume_status = pqisrc_get_dev_vol_status(softs, + device->scsi3addr); + device->volume_offline = device->volume_status != SA_LV_OK; + } + } + + /* + * Check if this is a One-Button-Disaster-Recovery device + * by looking for "$DR-10" at offset 43 in the inquiry data. + */ + device->is_obdr_device = (device->devtype == ROM_DEVICE && + memcmp(&inq_buff[OBDR_SIG_OFFSET], OBDR_TAPE_SIG, + OBDR_SIG_LEN) == 0); +err_out: + os_mem_free(softs, (char*)inq_buff, OBDR_TAPE_INQ_SIZE); + + DBG_FUNC("OUT\n"); + return ret; +} + +/* + * BMIC (Basic Management And Interface Commands) command + * to get the controller identify params + */ +static int pqisrc_identify_ctrl(pqisrc_softstate_t *softs, + bmic_ident_ctrl_t *buff) +{ + int ret = PQI_STATUS_SUCCESS; + pqisrc_raid_req_t request; + + DBG_FUNC("IN\n"); + + memset(&request, 0, sizeof(request)); + ret = pqisrc_build_send_raid_request(softs, &request, buff, sizeof(*buff), + BMIC_IDENTIFY_CONTROLLER, 0, (uint8_t *)RAID_CTLR_LUNID, NULL); + DBG_FUNC("OUT\n"); + + return ret; +} + +/* Get the adapter FW version using BMIC_IDENTIFY_CONTROLLER */ +int pqisrc_get_ctrl_fw_version(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + bmic_ident_ctrl_t *identify_ctrl; + + DBG_FUNC("IN\n"); + + identify_ctrl = os_mem_alloc(softs, sizeof(*identify_ctrl)); + if (!identify_ctrl) { + DBG_ERR("failed to allocate memory for identify_ctrl\n"); + return PQI_STATUS_FAILURE; + } + + memset(identify_ctrl, 0, sizeof(*identify_ctrl)); + + ret = pqisrc_identify_ctrl(softs, identify_ctrl); + if (ret) + goto out; + + softs->fw_build_number = identify_ctrl->fw_build_number; + memcpy(softs->fw_version, identify_ctrl->fw_version, + sizeof(identify_ctrl->fw_version)); + softs->fw_version[sizeof(identify_ctrl->fw_version)] = '\0'; + snprintf(softs->fw_version + + strlen(softs->fw_version), + sizeof(softs->fw_version), + "-%u", identify_ctrl->fw_build_number); +out: + os_mem_free(softs, (char *)identify_ctrl, sizeof(*identify_ctrl)); + DBG_INFO("Firmware version: %s Firmware build number: %d\n", softs->fw_version, softs->fw_build_number); + DBG_FUNC("OUT\n"); + return ret; +} + +/* BMIC command to determine scsi device identify params */ +static int pqisrc_identify_physical_disk(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device, + bmic_ident_physdev_t *buff, + int buf_len) +{ + int ret = PQI_STATUS_SUCCESS; + uint16_t bmic_device_index; + pqisrc_raid_req_t request; + + + DBG_FUNC("IN\n"); + + memset(&request, 0, sizeof(request)); + bmic_device_index = BMIC_GET_DRIVE_NUMBER(device->scsi3addr); + request.cdb[2] = (uint8_t)bmic_device_index; + request.cdb[9] = (uint8_t)(bmic_device_index >> 8); + + ret = pqisrc_build_send_raid_request(softs, &request, buff, buf_len, + BMIC_IDENTIFY_PHYSICAL_DEVICE, 0, (uint8_t *)RAID_CTLR_LUNID, NULL); + DBG_FUNC("OUT\n"); + return ret; +} + +/* + * Function used to get the scsi device information using one of BMIC + * BMIC_IDENTIFY_PHYSICAL_DEVICE + */ +static void pqisrc_get_physical_device_info(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device, + bmic_ident_physdev_t *id_phys) +{ + int ret = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); + memset(id_phys, 0, sizeof(*id_phys)); + + ret= pqisrc_identify_physical_disk(softs, device, + id_phys, sizeof(*id_phys)); + if (ret) { + device->queue_depth = PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH; + return; + } + + device->queue_depth = + LE_16(id_phys->current_queue_depth_limit); + device->device_type = id_phys->device_type; + device->active_path_index = id_phys->active_path_number; + device->path_map = id_phys->redundant_path_present_map; + memcpy(&device->box, + &id_phys->alternate_paths_phys_box_on_port, + sizeof(device->box)); + memcpy(&device->phys_connector, + &id_phys->alternate_paths_phys_connector, + sizeof(device->phys_connector)); + device->bay = id_phys->phys_bay_in_box; + + DBG_INFO("BMIC DEV_TYPE: %x QUEUE DEPTH: 0x%x \n", device->device_type, device->queue_depth); + DBG_FUNC("OUT\n"); +} + + +/* Function used to find the entry of the device in a list */ +static device_status_t pqisrc_scsi_find_entry(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device_to_find, + pqi_scsi_dev_t **same_device) +{ + pqi_scsi_dev_t *device; + int i,j; + DBG_FUNC("IN\n"); + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + if (pqisrc_scsi3addr_equal(device_to_find->scsi3addr, + device->scsi3addr)) { + *same_device = device; + if (pqisrc_device_equal(device_to_find, device)) { + if (device_to_find->volume_offline) + return DEVICE_CHANGED; + return DEVICE_UNCHANGED; + } + return DEVICE_CHANGED; + } + } + } + DBG_FUNC("OUT\n"); + + return DEVICE_NOT_FOUND; +} + + +/* Update the newly added devices as existed device */ +static void pqisrc_exist_device_update(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device_exist, + pqi_scsi_dev_t *new_device) +{ + DBG_FUNC("IN\n"); + device_exist->expose_device = new_device->expose_device; + memcpy(device_exist->vendor, new_device->vendor, + sizeof(device_exist->vendor)); + memcpy(device_exist->model, new_device->model, + sizeof(device_exist->model)); + device_exist->is_physical_device = new_device->is_physical_device; + device_exist->is_external_raid_device = + new_device->is_external_raid_device; + device_exist->sas_address = new_device->sas_address; + device_exist->raid_level = new_device->raid_level; + device_exist->queue_depth = new_device->queue_depth; + device_exist->ioaccel_handle = new_device->ioaccel_handle; + device_exist->volume_status = new_device->volume_status; + device_exist->active_path_index = new_device->active_path_index; + device_exist->path_map = new_device->path_map; + device_exist->bay = new_device->bay; + memcpy(device_exist->box, new_device->box, + sizeof(device_exist->box)); + memcpy(device_exist->phys_connector, new_device->phys_connector, + sizeof(device_exist->phys_connector)); + device_exist->offload_config = new_device->offload_config; + device_exist->offload_enabled = false; + device_exist->offload_enabled_pending = + new_device->offload_enabled_pending; + device_exist->offload_to_mirror = 0; + if (device_exist->raid_map) + os_mem_free(softs, + (char *)device_exist->raid_map, + sizeof(*device_exist->raid_map)); + device_exist->raid_map = new_device->raid_map; + /* To prevent this from being freed later. */ + new_device->raid_map = NULL; + DBG_FUNC("OUT\n"); +} + +/* Validate the ioaccel_handle for a newly added device */ +static pqi_scsi_dev_t *pqisrc_identify_device_via_ioaccel( + pqisrc_softstate_t *softs, uint32_t ioaccel_handle) +{ + pqi_scsi_dev_t *device; + int i,j; + DBG_FUNC("IN\n"); + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + if (device->devtype != DISK_DEVICE) + continue; + if (pqisrc_is_logical_device(device)) + continue; + if (device->ioaccel_handle == ioaccel_handle) + return device; + } + } + DBG_FUNC("OUT\n"); + + return NULL; +} + +/* Get the scsi device queue depth */ +static void pqisrc_update_log_dev_qdepth(pqisrc_softstate_t *softs) +{ + unsigned i; + unsigned phys_dev_num; + unsigned num_raidmap_entries; + unsigned queue_depth; + pqisrc_raid_map_t *raid_map; + pqi_scsi_dev_t *device; + raidmap_data_t *dev_data; + pqi_scsi_dev_t *phys_disk; + unsigned j; + + DBG_FUNC("IN\n"); + + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + if (device->devtype != DISK_DEVICE) + continue; + if (!pqisrc_is_logical_device(device)) + continue; + if (pqisrc_is_external_raid_device(device)) + continue; + device->queue_depth = PQI_LOGICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH; + raid_map = device->raid_map; + if (!raid_map) + return; + dev_data = raid_map->dev_data; + phys_dev_num = LE_16(raid_map->layout_map_count) * + (LE_16(raid_map->data_disks_per_row) + + LE_16(raid_map->metadata_disks_per_row)); + num_raidmap_entries = phys_dev_num * + LE_16(raid_map->row_cnt); + + queue_depth = 0; + for (i = 0; i < num_raidmap_entries; i++) { + phys_disk = pqisrc_identify_device_via_ioaccel(softs, + dev_data[i].ioaccel_handle); + + if (!phys_disk) { + DBG_WARN( + "Failed to find physical disk handle for logical drive %016llx\n", + (unsigned long long)BE_64(device->scsi3addr[0])); + device->offload_enabled = false; + device->offload_enabled_pending = false; + if (raid_map) + os_mem_free(softs, (char *)raid_map, sizeof(*raid_map)); + device->raid_map = NULL; + return; + } + + queue_depth += phys_disk->queue_depth; + } + + device->queue_depth = queue_depth; + } /* end inner loop */ + }/* end outer loop */ + DBG_FUNC("OUT\n"); +} + +/* Function used to add a scsi device to OS scsi subsystem */ +static int pqisrc_add_device(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + DBG_FUNC("IN\n"); + DBG_INFO("vendor: %s model: %s bus:%d target:%d lun:%d is_physical_device:0x%x expose_device:0x%x volume_offline 0x%x volume_status 0x%x \n", + device->vendor, device->model, device->bus, device->target, device->lun, device->is_physical_device, device->expose_device, device->volume_offline, device->volume_status); + + device->invalid = false; + + if(device->expose_device) { + /* TBD: Call OS upper layer function to add the device entry */ + os_add_device(softs,device); + } + DBG_FUNC("OUT\n"); + return PQI_STATUS_SUCCESS; + +} + +/* Function used to remove a scsi device from OS scsi subsystem */ +void pqisrc_remove_device(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + DBG_FUNC("IN\n"); + DBG_INFO("vendor: %s model: %s bus:%d target:%d lun:%d is_physical_device:0x%x expose_device:0x%x volume_offline 0x%x volume_status 0x%x \n", + device->vendor, device->model, device->bus, device->target, device->lun, device->is_physical_device, device->expose_device, device->volume_offline, device->volume_status); + + /* TBD: Call OS upper layer function to remove the device entry */ + device->invalid = true; + os_remove_device(softs,device); + DBG_FUNC("OUT\n"); +} + + +/* + * When exposing new device to OS fails then adjst list according to the + * mid scsi list + */ +static void pqisrc_adjust_list(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + DBG_FUNC("IN\n"); + + if (!device) { + DBG_ERR("softs = %p: device is NULL !!!\n", softs); + return; + } + + OS_ACQUIRE_SPINLOCK(&softs->devlist_lock); + softs->device_list[device->target][device->lun] = NULL; + OS_RELEASE_SPINLOCK(&softs->devlist_lock); + pqisrc_device_mem_free(softs, device); + + DBG_FUNC("OUT\n"); +} + +/* Debug routine used to display the RAID volume status of the device */ +static void pqisrc_display_volume_status(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device) +{ + char *status; + + DBG_FUNC("IN\n"); + switch (device->volume_status) { + case SA_LV_OK: + status = "Volume is online."; + break; + case SA_LV_UNDERGOING_ERASE: + status = "Volume is undergoing background erase process."; + break; + case SA_LV_NOT_AVAILABLE: + status = "Volume is waiting for transforming volume."; + break; + case SA_LV_UNDERGOING_RPI: + status = "Volume is undergoing rapid parity initialization process."; + break; + case SA_LV_PENDING_RPI: + status = "Volume is queued for rapid parity initialization process."; + break; + case SA_LV_ENCRYPTED_NO_KEY: + status = "Volume is encrypted and cannot be accessed because key is not present."; + break; + case SA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER: + status = "Volume is not encrypted and cannot be accessed because controller is in encryption-only mode."; + break; + case SA_LV_UNDERGOING_ENCRYPTION: + status = "Volume is undergoing encryption process."; + break; + case SA_LV_UNDERGOING_ENCRYPTION_REKEYING: + status = "Volume is undergoing encryption re-keying process."; + break; + case SA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER: + status = "Volume is encrypted and cannot be accessed because controller does not have encryption enabled."; + break; + case SA_LV_PENDING_ENCRYPTION: + status = "Volume is pending migration to encrypted state, but process has not started."; + break; + case SA_LV_PENDING_ENCRYPTION_REKEYING: + status = "Volume is encrypted and is pending encryption rekeying."; + break; + case SA_LV_STATUS_VPD_UNSUPPORTED: + status = "Volume status is not available through vital product data pages."; + break; + default: + status = "Volume is in an unknown state."; + break; + } + + DBG_INFO("scsi BTL %d:%d:%d %s\n", + device->bus, device->target, device->lun, status); + DBG_FUNC("OUT\n"); +} + +void pqisrc_device_mem_free(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device) +{ + DBG_INFO("IN\n"); + if (!device) + return; + if (device->raid_map) { + os_mem_free(softs, (char *)device->raid_map, sizeof(pqisrc_raid_map_t)); + } + os_mem_free(softs, (char *)device,sizeof(*device)); + DBG_INFO("OUT\n"); + +} + +/* OS should call this function to free the scsi device */ +void pqisrc_free_device(pqisrc_softstate_t * softs,pqi_scsi_dev_t *device) +{ + + OS_ACQUIRE_SPINLOCK(&softs->devlist_lock); + pqisrc_device_mem_free(softs, device); + OS_RELEASE_SPINLOCK(&softs->devlist_lock); + +} + + +/* Update the newly added devices to the device list */ +static void pqisrc_update_device_list(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *new_device_list[], int num_new_devices) +{ + int ret; + int i; + device_status_t dev_status; + pqi_scsi_dev_t *device; + pqi_scsi_dev_t *same_device; + pqi_scsi_dev_t **added = NULL; + pqi_scsi_dev_t **removed = NULL; + int nadded = 0, nremoved = 0; + int j; + DBG_INFO("IN\n"); + + added = os_mem_alloc(softs, sizeof(*added) * PQI_MAX_DEVICES); + removed = os_mem_alloc(softs, sizeof(*removed) * PQI_MAX_DEVICES); + + if (!added || !removed) { + DBG_WARN("Out of memory \n"); + goto free_and_out; + } + + OS_ACQUIRE_SPINLOCK(&softs->devlist_lock); + + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + device->device_gone = true; + } + } + DBG_IO("Device list used an array\n"); + for (i = 0; i < num_new_devices; i++) { + device = new_device_list[i]; + + dev_status = pqisrc_scsi_find_entry(softs, device, + &same_device); + + switch (dev_status) { + case DEVICE_UNCHANGED: + /* New Device present in existing device list */ + device->new_device = false; + same_device->device_gone = false; + pqisrc_exist_device_update(softs, same_device, device); + break; + case DEVICE_NOT_FOUND: + /* Device not found in existing list */ + device->new_device = true; + break; + case DEVICE_CHANGED: + /* Actual device gone need to add device to list*/ + device->new_device = true; + break; + default: + break; + } + } + /* Process all devices that have gone away. */ + for(i = 0, nremoved = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + if (device->device_gone) { + softs->device_list[device->target][device->lun] = NULL; + removed[nremoved] = device; + nremoved++; + } + } + } + + /* Process all new devices. */ + for (i = 0, nadded = 0; i < num_new_devices; i++) { + device = new_device_list[i]; + if (!device->new_device) + continue; + if (device->volume_offline) + continue; + + softs->device_list[device->target][device->lun] = device; + DBG_INFO("Added device %p at B : %d T : %d L : %d\n",device, + device->bus,device->target,device->lun); + /* To prevent this entry from being freed later. */ + new_device_list[i] = NULL; + added[nadded] = device; + nadded++; + } + + pqisrc_update_log_dev_qdepth(softs); + + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + device->offload_enabled = device->offload_enabled_pending; + } + } + + OS_RELEASE_SPINLOCK(&softs->devlist_lock); + + for(i = 0; i < nremoved; i++) { + device = removed[i]; + if (device == NULL) + continue; + pqisrc_remove_device(softs, device); + pqisrc_display_device_info(softs, "removed", device); + + } + + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + /* + * Notify the OS upper layer if the queue depth of any existing device has + * changed. + */ + if (device->queue_depth != + device->advertised_queue_depth) { + device->advertised_queue_depth = device->queue_depth; + /* TBD: Call OS upper layer function to change device Q depth */ + } + } + } + for(i = 0; i < nadded; i++) { + device = added[i]; + if (device->expose_device) { + ret = pqisrc_add_device(softs, device); + if (ret) { + DBG_WARN("scsi %d:%d:%d addition failed, device not added\n", + device->bus, device->target, + device->lun); + pqisrc_adjust_list(softs, device); + continue; + } + } + + pqisrc_display_device_info(softs, "added", device); + } + + /* Process all volumes that are offline. */ + for (i = 0; i < num_new_devices; i++) { + device = new_device_list[i]; + if (!device) + continue; + if (!device->new_device) + continue; + if (device->volume_offline) { + pqisrc_display_volume_status(softs, device); + pqisrc_display_device_info(softs, "offline", device); + } + } + +free_and_out: + if (added) + os_mem_free(softs, (char *)added, + sizeof(*added) * PQI_MAX_DEVICES); + if (removed) + os_mem_free(softs, (char *)removed, + sizeof(*removed) * PQI_MAX_DEVICES); + + DBG_INFO("OUT\n"); +} + +/* + * Let the Adapter know about driver version using one of BMIC + * BMIC_WRITE_HOST_WELLNESS + */ +int pqisrc_write_driver_version_to_host_wellness(pqisrc_softstate_t *softs) +{ + int rval = PQI_STATUS_SUCCESS; + struct bmic_host_wellness_driver_version *host_wellness_driver_ver; + size_t data_length; + pqisrc_raid_req_t request; + + DBG_FUNC("IN\n"); + + memset(&request, 0, sizeof(request)); + data_length = sizeof(*host_wellness_driver_ver); + + host_wellness_driver_ver = os_mem_alloc(softs, data_length); + if (!host_wellness_driver_ver) { + DBG_ERR("failed to allocate memory for host wellness driver_version\n"); + return PQI_STATUS_FAILURE; + } + + host_wellness_driver_ver->start_tag[0] = '<'; + host_wellness_driver_ver->start_tag[1] = 'H'; + host_wellness_driver_ver->start_tag[2] = 'W'; + host_wellness_driver_ver->start_tag[3] = '>'; + host_wellness_driver_ver->driver_version_tag[0] = 'D'; + host_wellness_driver_ver->driver_version_tag[1] = 'V'; + host_wellness_driver_ver->driver_version_length = LE_16(sizeof(host_wellness_driver_ver->driver_version)); + strncpy(host_wellness_driver_ver->driver_version, softs->os_name, + sizeof(host_wellness_driver_ver->driver_version)); + if (strlen(softs->os_name) < sizeof(host_wellness_driver_ver->driver_version) ) { + strncpy(host_wellness_driver_ver->driver_version + strlen(softs->os_name), PQISRC_DRIVER_VERSION, + sizeof(host_wellness_driver_ver->driver_version) - strlen(softs->os_name)); + } else { + DBG_INFO("OS name length(%lu) is longer than buffer of driver_version\n", + strlen(softs->os_name)); + } + host_wellness_driver_ver->driver_version[sizeof(host_wellness_driver_ver->driver_version) - 1] = '\0'; + host_wellness_driver_ver->end_tag[0] = 'Z'; + host_wellness_driver_ver->end_tag[1] = 'Z'; + + rval = pqisrc_build_send_raid_request(softs, &request, host_wellness_driver_ver,data_length, + BMIC_WRITE_HOST_WELLNESS, 0, (uint8_t *)RAID_CTLR_LUNID, NULL); + + os_mem_free(softs, (char *)host_wellness_driver_ver, data_length); + + DBG_FUNC("OUT"); + return rval; +} + +/* + * Write current RTC time from host to the adapter using + * BMIC_WRITE_HOST_WELLNESS + */ +int pqisrc_write_current_time_to_host_wellness(pqisrc_softstate_t *softs) +{ + int rval = PQI_STATUS_SUCCESS; + struct bmic_host_wellness_time *host_wellness_time; + size_t data_length; + pqisrc_raid_req_t request; + + DBG_FUNC("IN\n"); + + memset(&request, 0, sizeof(request)); + data_length = sizeof(*host_wellness_time); + + host_wellness_time = os_mem_alloc(softs, data_length); + if (!host_wellness_time) { + DBG_ERR("failed to allocate memory for host wellness time structure\n"); + return PQI_STATUS_FAILURE; + } + + host_wellness_time->start_tag[0] = '<'; + host_wellness_time->start_tag[1] = 'H'; + host_wellness_time->start_tag[2] = 'W'; + host_wellness_time->start_tag[3] = '>'; + host_wellness_time->time_tag[0] = 'T'; + host_wellness_time->time_tag[1] = 'D'; + host_wellness_time->time_length = LE_16(offsetof(struct bmic_host_wellness_time, time_length) - + offsetof(struct bmic_host_wellness_time, century)); + + os_get_time(host_wellness_time); + + host_wellness_time->dont_write_tag[0] = 'D'; + host_wellness_time->dont_write_tag[1] = 'W'; + host_wellness_time->end_tag[0] = 'Z'; + host_wellness_time->end_tag[1] = 'Z'; + + rval = pqisrc_build_send_raid_request(softs, &request, host_wellness_time,data_length, + BMIC_WRITE_HOST_WELLNESS, 0, (uint8_t *)RAID_CTLR_LUNID, NULL); + + os_mem_free(softs, (char *)host_wellness_time, data_length); + + DBG_FUNC("OUT"); + return rval; +} + +/* + * Function used to perform a rescan of scsi devices + * for any config change events + */ +int pqisrc_scan_devices(pqisrc_softstate_t *softs) +{ + boolean_t is_physical_device; + int ret = PQI_STATUS_FAILURE; + int i; + int new_dev_cnt; + int phy_log_dev_cnt; + uint8_t *scsi3addr; + uint32_t physical_cnt; + uint32_t logical_cnt; + uint32_t ndev_allocated = 0; + size_t phys_data_length, log_data_length; + reportlun_data_ext_t *physical_dev_list = NULL; + reportlun_data_ext_t *logical_dev_list = NULL; + reportlun_ext_entry_t *lun_ext_entry = NULL; + bmic_ident_physdev_t *bmic_phy_info = NULL; + pqi_scsi_dev_t **new_device_list = NULL; + pqi_scsi_dev_t *device = NULL; + + + DBG_FUNC("IN\n"); + + ret = pqisrc_get_phys_log_device_list(softs, &physical_dev_list, &logical_dev_list, + &phys_data_length, &log_data_length); + + if (ret) + goto err_out; + + physical_cnt = BE_32(physical_dev_list->header.list_length) + / sizeof(physical_dev_list->lun_entries[0]); + + logical_cnt = BE_32(logical_dev_list->header.list_length) + / sizeof(logical_dev_list->lun_entries[0]); + + DBG_INFO("physical_cnt %d logical_cnt %d\n", physical_cnt, logical_cnt); + + if (physical_cnt) { + bmic_phy_info = os_mem_alloc(softs, sizeof(*bmic_phy_info)); + if (bmic_phy_info == NULL) { + ret = PQI_STATUS_FAILURE; + DBG_ERR("failed to allocate memory for BMIC ID PHYS Device : %d\n", ret); + goto err_out; + } + } + phy_log_dev_cnt = physical_cnt + logical_cnt; + new_device_list = os_mem_alloc(softs, + sizeof(*new_device_list) * phy_log_dev_cnt); + + if (new_device_list == NULL) { + ret = PQI_STATUS_FAILURE; + DBG_ERR("failed to allocate memory for device list : %d\n", ret); + goto err_out; + } + + for (i = 0; i < phy_log_dev_cnt; i++) { + new_device_list[i] = os_mem_alloc(softs, + sizeof(*new_device_list[i])); + if (new_device_list[i] == NULL) { + ret = PQI_STATUS_FAILURE; + DBG_ERR("failed to allocate memory for device list : %d\n", ret); + ndev_allocated = i; + goto err_out; + } + } + + ndev_allocated = phy_log_dev_cnt; + new_dev_cnt = 0; + for (i = 0; i < phy_log_dev_cnt; i++) { + + if (i < physical_cnt) { + is_physical_device = true; + lun_ext_entry = &physical_dev_list->lun_entries[i]; + } else { + is_physical_device = false; + lun_ext_entry = + &logical_dev_list->lun_entries[i - physical_cnt]; + } + + scsi3addr = lun_ext_entry->lunid; + + /* Skip masked physical non-disk devices. */ + if (MASKED_DEVICE(scsi3addr) && is_physical_device) + continue; + + device = new_device_list[new_dev_cnt]; + memset(device, 0, sizeof(*device)); + memcpy(device->scsi3addr, scsi3addr, sizeof(device->scsi3addr)); + device->wwid = lun_ext_entry->wwid; + device->is_physical_device = is_physical_device; + if (!is_physical_device) + device->is_external_raid_device = + pqisrc_is_external_raid_addr(scsi3addr); + + + /* Get device type, vendor, model, device ID. */ + ret = pqisrc_get_dev_data(softs, device); + if (ret) { + DBG_WARN("Inquiry failed, skipping device %016llx\n", + (unsigned long long)BE_64(device->scsi3addr[0])); + DBG_INFO("INQUIRY FAILED \n"); + continue; + } + pqisrc_assign_btl(device); + + /* + * Expose all devices except for physical devices that + * are masked. + */ + if (device->is_physical_device && + MASKED_DEVICE(scsi3addr)) + device->expose_device = false; + else + device->expose_device = true; + + if (device->is_physical_device && + (lun_ext_entry->device_flags & + REPORT_LUN_DEV_FLAG_AIO_ENABLED) && + lun_ext_entry->ioaccel_handle) { + device->aio_enabled = true; + } + switch (device->devtype) { + case ROM_DEVICE: + /* + * We don't *really* support actual CD-ROM devices, + * but we do support the HP "One Button Disaster + * Recovery" tape drive which temporarily pretends to + * be a CD-ROM drive. + */ + if (device->is_obdr_device) + new_dev_cnt++; + break; + case DISK_DEVICE: + case ZBC_DEVICE: + if (device->is_physical_device) { + device->ioaccel_handle = + lun_ext_entry->ioaccel_handle; + device->sas_address = BE_64(lun_ext_entry->wwid); + pqisrc_get_physical_device_info(softs, device, + bmic_phy_info); + } + /* Logical device doesn't have SAS address + * so requires target SAS address for MSA. + */ + if(device->is_external_raid_device) + device->sas_address = BE_64((uint64_t)lun_ext_entry->lunid); + new_dev_cnt++; + break; + case ENCLOSURE_DEVICE: + if (device->is_physical_device) { + device->sas_address = BE_64(lun_ext_entry->wwid); + } + new_dev_cnt++; + break; + case TAPE_DEVICE: + case MEDIUM_CHANGER_DEVICE: + new_dev_cnt++; + break; + case RAID_DEVICE: + /* + * Only present the HBA controller itself as a RAID + * controller. If it's a RAID controller other than + * the HBA itself (an external RAID controller, MSA500 + * or similar), don't present it. + */ + if (pqisrc_is_hba_lunid(scsi3addr)) + new_dev_cnt++; + break; + } + } + DBG_INFO("new_dev_cnt %d\n", new_dev_cnt); + + pqisrc_update_device_list(softs, new_device_list, new_dev_cnt); + +err_out: + if (new_device_list) { + for (i = 0; i < ndev_allocated; i++) { + if (new_device_list[i]) { + if(new_device_list[i]->raid_map) + os_mem_free(softs, (char *)new_device_list[i]->raid_map, + sizeof(pqisrc_raid_map_t)); + os_mem_free(softs, (char*)new_device_list[i], + sizeof(*new_device_list[i])); + } + } + os_mem_free(softs, (char *)new_device_list, + sizeof(*new_device_list) * ndev_allocated); + } + if(physical_dev_list) + os_mem_free(softs, (char *)physical_dev_list, phys_data_length); + if(logical_dev_list) + os_mem_free(softs, (char *)logical_dev_list, log_data_length); + if (bmic_phy_info) + os_mem_free(softs, (char *)bmic_phy_info, sizeof(*bmic_phy_info)); + + DBG_FUNC("OUT \n"); + + return ret; +} + +/* + * Clean up memory allocated for devices. + */ +void pqisrc_cleanup_devices(pqisrc_softstate_t *softs) +{ + + int i = 0,j = 0; + pqi_scsi_dev_t *dvp = NULL; + DBG_FUNC("IN\n"); + + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if (softs->device_list[i][j] == NULL) + continue; + dvp = softs->device_list[i][j]; + pqisrc_device_mem_free(softs, dvp); + } + } + DBG_FUNC("OUT\n"); +} + Property changes on: head/sys/dev/smartpqi/smartpqi_discovery.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_event.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_event.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_event.c (revision 333019) @@ -0,0 +1,439 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include"smartpqi_includes.h" + +/* + * Function to rescan the devices connected to adapter. + */ +int +pqisrc_rescan_devices(pqisrc_softstate_t *softs) +{ + int ret; + + DBG_FUNC("IN\n"); + + os_sema_lock(&softs->scan_lock); + + ret = pqisrc_scan_devices(softs); + + os_sema_unlock(&softs->scan_lock); + + DBG_FUNC("OUT\n"); + + return ret; +} + +/* + * Subroutine to acknowledge the events processed by the driver to the adapter. + */ +static void +pqisrc_acknowledge_event(pqisrc_softstate_t *softs, + struct pqi_event *event) +{ + + pqi_event_acknowledge_request_t request; + ib_queue_t *ib_q = &softs->op_raid_ib_q[0]; + int tmo = PQISRC_EVENT_ACK_RESP_TIMEOUT; + memset(&request,0,sizeof(request)); + + DBG_FUNC("IN\n"); + + request.header.iu_type = PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT; + request.header.iu_length = (sizeof(pqi_event_acknowledge_request_t) - + PQI_REQUEST_HEADER_LENGTH); + request.event_type = event->event_type; + request.event_id = event->event_id; + request.additional_event_id = event->additional_event_id; + + /* Submit Event Acknowledge */ + + pqisrc_submit_cmnd(softs, ib_q, &request); + + /* + * We have to special-case this type of request because the firmware + * does not generate an interrupt when this type of request completes. + * Therefore, we have to poll until we see that the firmware has + * consumed the request before we move on. + */ + + COND_WAIT(((ib_q->pi_local) == *(ib_q->ci_virt_addr)), tmo); + if (tmo <= 0) { + DBG_ERR("wait for event acknowledge timed out\n"); + DBG_ERR("tmo : %d\n",tmo); + } + + DBG_FUNC(" OUT\n"); +} + +/* + * Acknowledge processed events to the adapter. + */ +void +pqisrc_ack_all_events(void *arg1) +{ + int i; + struct pqi_event *pending_event; + pqisrc_softstate_t *softs = (pqisrc_softstate_t*)arg1; + + DBG_FUNC(" IN\n"); + + + pending_event = &softs->pending_events[0]; + for (i=0; i < PQI_NUM_SUPPORTED_EVENTS; i++) { + if (pending_event->pending == true) { + pending_event->pending = false; + pqisrc_acknowledge_event(softs, pending_event); + } + pending_event++; + } + + /* Rescan devices except for heartbeat event */ + if ((pqisrc_rescan_devices(softs)) != PQI_STATUS_SUCCESS) { + DBG_ERR(" Failed to Re-Scan devices\n "); + } + DBG_FUNC(" OUT\n"); + +} + +/* + * Get event index from event type to validate the type of event. + */ +static int +pqisrc_event_type_to_event_index(unsigned event_type) +{ + int index; + + switch (event_type) { + case PQI_EVENT_TYPE_HOTPLUG: + index = PQI_EVENT_HOTPLUG; + break; + case PQI_EVENT_TYPE_HARDWARE: + index = PQI_EVENT_HARDWARE; + break; + case PQI_EVENT_TYPE_PHYSICAL_DEVICE: + index = PQI_EVENT_PHYSICAL_DEVICE; + break; + case PQI_EVENT_TYPE_LOGICAL_DEVICE: + index = PQI_EVENT_LOGICAL_DEVICE; + break; + case PQI_EVENT_TYPE_AIO_STATE_CHANGE: + index = PQI_EVENT_AIO_STATE_CHANGE; + break; + case PQI_EVENT_TYPE_AIO_CONFIG_CHANGE: + index = PQI_EVENT_AIO_CONFIG_CHANGE; + break; + default: + index = -1; + break; + } + + return index; +} + +/* + * Function used to process the events supported by the adapter. + */ +int +pqisrc_process_event_intr_src(pqisrc_softstate_t *softs,int obq_id) +{ + uint32_t obq_pi,obq_ci; + pqi_event_response_t response; + ob_queue_t *event_q; + struct pqi_event *pending_event; + boolean_t need_delayed_work = false; + + DBG_FUNC(" IN\n"); + + OS_ATOMIC64_INC(softs, num_intrs); + + event_q = &softs->event_q; + obq_ci = event_q->ci_local; + obq_pi = *(event_q->pi_virt_addr); + DBG_INFO("Initial Event_q ci : %d Event_q pi : %d\n", obq_ci, obq_pi); + + while(1) { + int event_index; + DBG_INFO("queue_id : %d ci : %d pi : %d\n",obq_id, obq_ci, obq_pi); + if (obq_pi == obq_ci) + break; + + need_delayed_work = true; + + /* Copy the response */ + memcpy(&response, event_q->array_virt_addr + (obq_ci * event_q->elem_size), + sizeof(pqi_event_response_t)); + DBG_INFO("response.header.iu_type : 0x%x \n", response.header.iu_type); + DBG_INFO("response.event_type : 0x%x \n", response.event_type); + + event_index = pqisrc_event_type_to_event_index(response.event_type); + + if (event_index >= 0) { + if(response.request_acknowledge) { + pending_event = &softs->pending_events[event_index]; + pending_event->pending = true; + pending_event->event_type = response.event_type; + pending_event->event_id = response.event_id; + pending_event->additional_event_id = response.additional_event_id; + } + } + + obq_ci = (obq_ci + 1) % event_q->num_elem; + } + /* Update CI */ + event_q->ci_local = obq_ci; + PCI_MEM_PUT32(softs, event_q->ci_register_abs, + event_q->ci_register_offset, event_q->ci_local); + + /*Adding events to the task queue for acknowledging*/ + if (need_delayed_work == true) { + os_eventtaskqueue_enqueue(softs); + } + + DBG_FUNC("OUT"); + return PQI_STATUS_SUCCESS; + + +} + +/* + * Function used to send a general management request to adapter. + */ +int pqisrc_submit_management_req(pqisrc_softstate_t *softs, + pqi_event_config_request_t *request) +{ + int ret = PQI_STATUS_SUCCESS; + ib_queue_t *op_ib_q = &softs->op_raid_ib_q[0]; + rcb_t *rcb = NULL; + + DBG_FUNC(" IN\n"); + + /* Get the tag */ + request->request_id = pqisrc_get_tag(&softs->taglist); + if (INVALID_ELEM == request->request_id) { + DBG_ERR("Tag not available\n"); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + + rcb = &softs->rcb[request->request_id]; + rcb->req_pending = true; + rcb->tag = request->request_id; + /* Submit command on operational raid ib queue */ + ret = pqisrc_submit_cmnd(softs, op_ib_q, request); + if (ret != PQI_STATUS_SUCCESS) { + DBG_ERR(" Unable to submit command\n"); + goto err_cmd; + } + + ret = pqisrc_wait_on_condition(softs, rcb); + if (ret != PQI_STATUS_SUCCESS) { + DBG_ERR("Management request timed out !!\n"); + goto err_cmd; + } + + os_reset_rcb(rcb); + pqisrc_put_tag(&softs->taglist,request->request_id); + DBG_FUNC("OUT\n"); + return ret; + +err_cmd: + os_reset_rcb(rcb); + pqisrc_put_tag(&softs->taglist,request->request_id); +err_out: + DBG_FUNC(" failed OUT : %d\n", ret); + return ret; +} + +/* + * Build and send the general management request. + */ +static int +pqi_event_configure(pqisrc_softstate_t *softs , + pqi_event_config_request_t *request, + dma_mem_t *buff) +{ + int ret = PQI_STATUS_SUCCESS; + + DBG_FUNC(" IN\n"); + + request->header.comp_feature = 0x00; + request->header.iu_length = sizeof(pqi_event_config_request_t) - + PQI_REQUEST_HEADER_LENGTH; /* excluding IU header length */ + + /*Op OQ id where response to be delivered */ + request->response_queue_id = softs->op_ob_q[0].q_id; + request->buffer_length = buff->size; + request->sg_desc.addr = buff->dma_addr; + request->sg_desc.length = buff->size; + request->sg_desc.zero = 0; + request->sg_desc.type = SGL_DESCRIPTOR_CODE_LAST_ALTERNATIVE_SGL_SEGMENT; + + /* submit management req IU*/ + ret = pqisrc_submit_management_req(softs,request); + if(ret) + goto err_out; + + + DBG_FUNC(" OUT\n"); + return ret; + +err_out: + DBG_FUNC("Failed OUT\n"); + return ret; +} + +/* + * Prepare REPORT EVENT CONFIGURATION IU to request that + * event configuration information be reported. + */ +int pqisrc_report_event_config(pqisrc_softstate_t *softs) +{ + + int ret,i ; + pqi_event_config_request_t request; + pqi_event_config_t *event_config_p ; + dma_mem_t buf_report_event ; + /*bytes to be allocaed for report event config data-in buffer */ + uint32_t alloc_size = sizeof(pqi_event_config_t) ; + memset(&request, 0 , sizeof(request)); + + DBG_FUNC(" IN\n"); + + memset(&buf_report_event, 0, sizeof(struct dma_mem)); + buf_report_event.tag = "pqi_report_event_buf" ; + buf_report_event.size = alloc_size; + buf_report_event.align = PQISRC_DEFAULT_DMA_ALIGN; + + /* allocate memory */ + ret = os_dma_mem_alloc(softs, &buf_report_event); + if (ret) { + DBG_ERR("Failed to Allocate report event config buffer : %d\n", ret); + goto err_out; + } + DBG_INFO("buf_report_event.dma_addr = %p \n",(void*)buf_report_event.dma_addr); + DBG_INFO("buf_report_event.virt_addr = %p \n",(void*)buf_report_event.virt_addr); + + request.header.iu_type = PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG; + + /* Event configuration */ + ret=pqi_event_configure(softs,&request,&buf_report_event); + if(ret) + goto free_mem; + + + event_config_p = (pqi_event_config_t*)buf_report_event.virt_addr; + softs->event_config.num_event_descriptors = MIN(event_config_p->num_event_descriptors, + PQI_MAX_EVENT_DESCRIPTORS) ; + + for (i=0; i < softs->event_config.num_event_descriptors ;i++){ + softs->event_config.descriptors[i].event_type = + event_config_p->descriptors[i].event_type; + } + /* free the allocated memory*/ + os_dma_mem_free(softs, &buf_report_event); + + DBG_FUNC(" OUT\n"); + return ret; + +free_mem: + os_dma_mem_free(softs, &buf_report_event); +err_out: + DBG_FUNC("Failed OUT\n"); + return PQI_STATUS_FAILURE; +} + +/* + * Prepare SET EVENT CONFIGURATION IU to request that + * event configuration parameters be set. + */ +int pqisrc_set_event_config(pqisrc_softstate_t *softs) +{ + + int ret,i; + pqi_event_config_request_t request; + pqi_event_config_t *event_config_p; + dma_mem_t buf_set_event; + /*bytes to be allocaed for set event config data-out buffer */ + uint32_t alloc_size = sizeof(pqi_event_config_t); + memset(&request, 0 , sizeof(request)); + + DBG_FUNC(" IN\n"); + + memset(&buf_set_event, 0, sizeof(struct dma_mem)); + buf_set_event.tag = "pqi_set_event_buf"; + buf_set_event.size = alloc_size; + buf_set_event.align = PQISRC_DEFAULT_DMA_ALIGN; + + /* allocate memory */ + ret = os_dma_mem_alloc(softs, &buf_set_event); + if (ret) { + DBG_ERR("Failed to Allocate set event config buffer : %d\n", ret); + goto err_out; + } + + DBG_INFO("buf_set_event.dma_addr = %p\n",(void*)buf_set_event.dma_addr); + DBG_INFO("buf_set_event.virt_addr = %p\n",(void*)buf_set_event.virt_addr); + + request.header.iu_type = PQI_REQUEST_IU_SET_EVENT_CONFIG; + request.iu_specific.global_event_oq_id = softs->event_q.q_id; + + /*pointer to data-out buffer*/ + + event_config_p = (pqi_event_config_t *)buf_set_event.virt_addr; + + event_config_p->num_event_descriptors = softs->event_config.num_event_descriptors; + + + for (i=0; i < softs->event_config.num_event_descriptors ; i++){ + event_config_p->descriptors[i].event_type = + softs->event_config.descriptors[i].event_type; + if( pqisrc_event_type_to_event_index(event_config_p->descriptors[i].event_type) != -1) + event_config_p->descriptors[i].oq_id = softs->event_q.q_id; + else + event_config_p->descriptors[i].oq_id = 0; /* Not supported this event. */ + + + } + /* Event configuration */ + ret = pqi_event_configure(softs,&request,&buf_set_event); + if(ret) + goto free_mem; + + os_dma_mem_free(softs, &buf_set_event); + + DBG_FUNC(" OUT\n"); + return ret; + +free_mem: + os_dma_mem_free(softs, &buf_set_event); +err_out: + DBG_FUNC("Failed OUT\n"); + return PQI_STATUS_FAILURE; + +} Property changes on: head/sys/dev/smartpqi/smartpqi_event.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_helper.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_helper.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_helper.c (revision 333019) @@ -0,0 +1,291 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* + * Function used to validate the adapter health. + */ +boolean_t pqisrc_ctrl_offline(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + + DBG_FUNC("OUT\n"); + + return !softs->ctrl_online; +} + +/* + * Function used to take exposed devices to OS as offline. + */ +void pqisrc_take_devices_offline(pqisrc_softstate_t *softs) +{ + pqi_scsi_dev_t *device = NULL; + int i,j; + + DBG_FUNC("IN\n"); + for(i = 0; i < PQI_MAX_DEVICES; i++) { + for(j = 0; j < PQI_MAX_MULTILUN; j++) { + if(softs->device_list[i][j] == NULL) + continue; + device = softs->device_list[i][j]; + pqisrc_remove_device(softs, device); + } + } + + DBG_FUNC("OUT\n"); +} + +/* + * Function used to take adapter offline. + */ +void pqisrc_take_ctrl_offline(pqisrc_softstate_t *softs) +{ + + DBG_FUNC("IN\n"); + + softs->ctrl_online = false; + pqisrc_trigger_nmi_sis(softs); + os_complete_outstanding_cmds_nodevice(softs); + pqisrc_take_devices_offline(softs); + + DBG_FUNC("OUT\n"); +} + +/* + * Timer handler for the adapter heart-beat. + */ +void pqisrc_heartbeat_timer_handler(pqisrc_softstate_t *softs) +{ + uint64_t num_intrs; + uint8_t take_offline = false; + + DBG_FUNC("IN\n"); + + num_intrs = OS_ATOMIC64_READ(softs, num_intrs); + + if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) { + if (CTRLR_HEARTBEAT_CNT(softs) == softs->prev_heartbeat_count) { + take_offline = true; + goto take_ctrl_offline; + } + softs->prev_heartbeat_count = CTRLR_HEARTBEAT_CNT(softs); + DBG_INFO("CTRLR_HEARTBEAT_CNT(softs) = %lx \ + softs->prev_heartbeat_count = %lx\n", + CTRLR_HEARTBEAT_CNT(softs), softs->prev_heartbeat_count); + } else { + if (num_intrs == softs->prev_num_intrs) { + softs->num_heartbeats_requested++; + if (softs->num_heartbeats_requested > PQI_MAX_HEARTBEAT_REQUESTS) { + take_offline = true; + goto take_ctrl_offline; + } + softs->pending_events[PQI_EVENT_HEARTBEAT].pending = true; + + pqisrc_ack_all_events((void*)softs); + + } else { + softs->num_heartbeats_requested = 0; + } + softs->prev_num_intrs = num_intrs; + } + +take_ctrl_offline: + if (take_offline){ + DBG_ERR("controller is offline\n"); + pqisrc_take_ctrl_offline(softs); + os_stop_heartbeat_timer(softs); + } + DBG_FUNC("OUT\n"); +} + +/* + * Conditional variable management routine for internal commands. + */ +int pqisrc_wait_on_condition(pqisrc_softstate_t *softs, rcb_t *rcb){ + + DBG_FUNC("IN\n"); + + int ret = PQI_STATUS_SUCCESS; + uint32_t loop_cnt = 0; + + while (rcb->req_pending == true) { + OS_SLEEP(500); /* Micro sec */ + + /*Polling needed for FreeBSD : since ithread routine is not scheduled + during bootup, we could use polling until interrupts are + enabled (using 'if (cold)'to check for the boot time before + interrupts are enabled). */ + IS_POLLING_REQUIRED(softs); + + if (loop_cnt++ == PQISRC_CMD_TIMEOUT_CNT) { + DBG_ERR("ERR: Requested cmd timed out !!!\n"); + ret = PQI_STATUS_TIMEOUT; + break; + } + + if (pqisrc_ctrl_offline(softs)) { + DBG_ERR("Controller is Offline"); + ret = PQI_STATUS_FAILURE; + break; + } + + } + rcb->req_pending = true; + + DBG_FUNC("OUT\n"); + + return ret; +} + +/* Function used to validate the device wwid. */ +boolean_t pqisrc_device_equal(pqi_scsi_dev_t *dev1, + pqi_scsi_dev_t *dev2) +{ + return dev1->wwid == dev2->wwid; +} + +/* Function used to validate the device scsi3addr. */ +boolean_t pqisrc_scsi3addr_equal(uint8_t *scsi3addr1, uint8_t *scsi3addr2) +{ + return memcmp(scsi3addr1, scsi3addr2, 8) == 0; +} + +/* Function used to validate hba_lunid */ +boolean_t pqisrc_is_hba_lunid(uint8_t *scsi3addr) +{ + return pqisrc_scsi3addr_equal(scsi3addr, (uint8_t*)RAID_CTLR_LUNID); +} + +/* Function used to validate type of device */ +boolean_t pqisrc_is_logical_device(pqi_scsi_dev_t *device) +{ + return !device->is_physical_device; +} + +/* Function used to sanitize inquiry string */ +void pqisrc_sanitize_inquiry_string(unsigned char *s, int len) +{ + boolean_t terminated = false; + + DBG_FUNC("IN\n"); + + for (; len > 0; (--len, ++s)) { + if (*s == 0) + terminated = true; + if (terminated || *s < 0x20 || *s > 0x7e) + *s = ' '; + } + + DBG_FUNC("OUT\n"); +} + +static char *raid_levels[] = { + "RAID 0", + "RAID 4", + "RAID 1(1+0)", + "RAID 5", + "RAID 5+1", + "RAID ADG", + "RAID 1(ADM)", + "RAID 6", +}; + +/* Get the RAID level from the index */ +char *pqisrc_raidlevel_to_string(uint8_t raid_level) +{ + DBG_FUNC("IN\n"); + if (raid_level < ARRAY_SIZE(raid_levels)) + return raid_levels[raid_level]; + DBG_FUNC("OUT\n"); + + return " "; +} + +/* Debug routine for displaying device info */ +void pqisrc_display_device_info(pqisrc_softstate_t *softs, + char *action, pqi_scsi_dev_t *device) +{ + DBG_INFO( "%s scsi BTL %d:%d:%d: %.8s %.16s %-12s SSDSmartPathCap%c En%c Exp%c qd=%d\n", + action, + device->bus, + device->target, + device->lun, + device->vendor, + device->model, + pqisrc_raidlevel_to_string(device->raid_level), + device->offload_config ? '+' : '-', + device->offload_enabled_pending ? '+' : '-', + device->expose_device ? '+' : '-', + device->queue_depth); + pqisrc_raidlevel_to_string(device->raid_level); /* To use this function */ +} + +/* validate the structure sizes */ +void check_struct_sizes() +{ + + ASSERT(sizeof(SCSI3Addr_struct)== 2); + ASSERT(sizeof(PhysDevAddr_struct) == 8); + ASSERT(sizeof(LogDevAddr_struct)== 8); + ASSERT(sizeof(LUNAddr_struct)==8); + ASSERT(sizeof(RequestBlock_struct) == 20); + ASSERT(sizeof(MoreErrInfo_struct)== 8); + ASSERT(sizeof(ErrorInfo_struct)== 48); + ASSERT(sizeof(IOCTL_Command_struct)== 86); + ASSERT(sizeof(struct bmic_host_wellness_driver_version)== 42); + ASSERT(sizeof(struct bmic_host_wellness_time)== 20); + ASSERT(sizeof(struct pqi_dev_adminq_cap)== 8); + ASSERT(sizeof(struct admin_q_param)== 4); + ASSERT(sizeof(struct pqi_registers)== 256); + ASSERT(sizeof(struct ioa_registers)== 4128); + ASSERT(sizeof(struct pqi_pref_settings)==4); + ASSERT(sizeof(struct pqi_cap)== 20); + ASSERT(sizeof(iu_header_t)== 4); + ASSERT(sizeof(gen_adm_req_iu_t)== 64); + ASSERT(sizeof(gen_adm_resp_iu_t)== 64); + ASSERT(sizeof(op_q_params) == 9); + ASSERT(sizeof(raid_path_error_info_elem_t)== 276); + ASSERT(sizeof(aio_path_error_info_elem_t)== 276); + ASSERT(sizeof(struct init_base_struct)== 24); + ASSERT(sizeof(pqi_iu_layer_desc_t)== 16); + ASSERT(sizeof(pqi_dev_cap_t)== 576); + ASSERT(sizeof(pqi_aio_req_t)== 128); + ASSERT(sizeof(pqisrc_raid_req_t)== 128); + ASSERT(sizeof(pqi_tmf_req_t)== 32); + ASSERT(sizeof(struct pqi_io_response)== 16); + ASSERT(sizeof(struct sense_header_scsi)== 8); + ASSERT(sizeof(reportlun_header_t)==8); + ASSERT(sizeof(reportlun_ext_entry_t)== 24); + ASSERT(sizeof(reportlun_data_ext_t)== 32); + ASSERT(sizeof(raidmap_data_t)==8); + ASSERT(sizeof(pqisrc_raid_map_t)== 8256); + ASSERT(sizeof(bmic_ident_ctrl_t)== 325); + ASSERT(sizeof(bmic_ident_physdev_t)==2048); + +} Property changes on: head/sys/dev/smartpqi/smartpqi_helper.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_includes.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_includes.h (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_includes.h (revision 333019) @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#ifndef _PQI_INCLUDES_H +#define _PQI_INCLUDES_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + + + +#include "smartpqi_defines.h" +#include "smartpqi_structures.h" +#include "smartpqi_prototypes.h" +#include "smartpqi_ioctl.h" + + +#endif // _PQI_INCLUDES_H Property changes on: head/sys/dev/smartpqi/smartpqi_includes.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_init.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_init.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_init.c (revision 333019) @@ -0,0 +1,913 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* + * Request the adapter to get PQI capabilities supported. + */ +static int pqisrc_report_pqi_capability(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); + + gen_adm_req_iu_t admin_req; + gen_adm_resp_iu_t admin_resp; + dma_mem_t pqi_cap_dma_buf; + pqi_dev_cap_t *capability = NULL; + pqi_iu_layer_desc_t *iu_layer_desc = NULL; + + /* Allocate Non DMA memory */ + capability = os_mem_alloc(softs, sizeof(*capability)); + if (!capability) { + DBG_ERR("Failed to allocate memory for capability\n"); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + + memset(&admin_req, 0, sizeof(admin_req)); + memset(&admin_resp, 0, sizeof(admin_resp)); + + memset(&pqi_cap_dma_buf, 0, sizeof(struct dma_mem)); + pqi_cap_dma_buf.tag = "pqi_cap_buf"; + pqi_cap_dma_buf.size = REPORT_PQI_DEV_CAP_DATA_BUF_SIZE; + pqi_cap_dma_buf.align = PQISRC_DEFAULT_DMA_ALIGN; + + ret = os_dma_mem_alloc(softs, &pqi_cap_dma_buf); + if (ret) { + DBG_ERR("Failed to allocate capability DMA buffer : %d\n", ret); + goto err_dma_alloc; + } + + admin_req.fn_code = PQI_FUNCTION_REPORT_DEV_CAP; + admin_req.req_type.general_func.buf_size = pqi_cap_dma_buf.size; + admin_req.req_type.general_func.sg_desc.length = pqi_cap_dma_buf.size; + admin_req.req_type.general_func.sg_desc.addr = pqi_cap_dma_buf.dma_addr; + admin_req.req_type.general_func.sg_desc.type = SGL_DESCRIPTOR_CODE_DATA_BLOCK; + + ret = pqisrc_submit_admin_req(softs, &admin_req, &admin_resp); + if( PQI_STATUS_SUCCESS == ret) { + memcpy(capability, + pqi_cap_dma_buf.virt_addr, + pqi_cap_dma_buf.size); + } else { + DBG_ERR("Failed to send admin req report pqi device capability\n"); + goto err_admin_req; + + } + + softs->pqi_dev_cap.max_iqs = capability->max_iqs; + softs->pqi_dev_cap.max_iq_elements = capability->max_iq_elements; + softs->pqi_dev_cap.max_iq_elem_len = capability->max_iq_elem_len; + softs->pqi_dev_cap.min_iq_elem_len = capability->min_iq_elem_len; + softs->pqi_dev_cap.max_oqs = capability->max_oqs; + softs->pqi_dev_cap.max_oq_elements = capability->max_oq_elements; + softs->pqi_dev_cap.max_oq_elem_len = capability->max_oq_elem_len; + softs->pqi_dev_cap.intr_coales_time_granularity = capability->intr_coales_time_granularity; + + iu_layer_desc = &capability->iu_layer_desc[PQI_PROTOCOL_SOP]; + softs->max_ib_iu_length_per_fw = iu_layer_desc->max_ib_iu_len; + softs->ib_spanning_supported = iu_layer_desc->ib_spanning_supported; + softs->ob_spanning_supported = iu_layer_desc->ob_spanning_supported; + + DBG_INFO("softs->pqi_dev_cap.max_iqs: %d\n", softs->pqi_dev_cap.max_iqs); + DBG_INFO("softs->pqi_dev_cap.max_iq_elements: %d\n", softs->pqi_dev_cap.max_iq_elements); + DBG_INFO("softs->pqi_dev_cap.max_iq_elem_len: %d\n", softs->pqi_dev_cap.max_iq_elem_len); + DBG_INFO("softs->pqi_dev_cap.min_iq_elem_len: %d\n", softs->pqi_dev_cap.min_iq_elem_len); + DBG_INFO("softs->pqi_dev_cap.max_oqs: %d\n", softs->pqi_dev_cap.max_oqs); + DBG_INFO("softs->pqi_dev_cap.max_oq_elements: %d\n", softs->pqi_dev_cap.max_oq_elements); + DBG_INFO("softs->pqi_dev_cap.max_oq_elem_len: %d\n", softs->pqi_dev_cap.max_oq_elem_len); + DBG_INFO("softs->pqi_dev_cap.intr_coales_time_granularity: %d\n", softs->pqi_dev_cap.intr_coales_time_granularity); + DBG_INFO("softs->max_ib_iu_length_per_fw: %d\n", softs->max_ib_iu_length_per_fw); + DBG_INFO("softs->ib_spanning_supported: %d\n", softs->ib_spanning_supported); + DBG_INFO("softs->ob_spanning_supported: %d\n", softs->ob_spanning_supported); + + + os_mem_free(softs, (void *)capability, + REPORT_PQI_DEV_CAP_DATA_BUF_SIZE); + os_dma_mem_free(softs, &pqi_cap_dma_buf); + + DBG_FUNC("OUT\n"); + return ret; + +err_admin_req: + os_dma_mem_free(softs, &pqi_cap_dma_buf); +err_dma_alloc: + if (capability) + os_mem_free(softs, (void *)capability, + REPORT_PQI_DEV_CAP_DATA_BUF_SIZE); +err_out: + DBG_FUNC("failed OUT\n"); + return PQI_STATUS_FAILURE; +} + +/* + * Function used to deallocate the used rcb. + */ +void pqisrc_free_rcb(pqisrc_softstate_t *softs, int req_count) +{ + + uint32_t num_req; + size_t size; + int i; + + DBG_FUNC("IN\n"); + num_req = softs->max_outstanding_io + 1; + size = num_req * sizeof(rcb_t); + for (i = 1; i < req_count; i++) + os_dma_mem_free(softs, &softs->sg_dma_desc[i]); + os_mem_free(softs, (void *)softs->rcb, size); + softs->rcb = NULL; + DBG_FUNC("OUT\n"); +} + + +/* + * Allocate memory for rcb and SG descriptors. + */ +static int pqisrc_allocate_rcb(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + int i = 0; + uint32_t num_req = 0; + uint32_t sg_buf_size = 0; + uint64_t alloc_size = 0; + rcb_t *rcb = NULL; + rcb_t *prcb = NULL; + DBG_FUNC("IN\n"); + + /* Set maximum outstanding requests */ + /* The valid tag values are from 1, 2, ..., softs->max_outstanding_io + * The rcb will be accessed by using the tag as index + * As 0 tag index is not used, we need to allocate one extra. + */ + softs->max_outstanding_io = softs->pqi_cap.max_outstanding_io; + num_req = softs->max_outstanding_io + 1; + DBG_INFO("Max Outstanding IO reset to %d\n", num_req); + + alloc_size = num_req * sizeof(rcb_t); + + /* Allocate Non DMA memory */ + rcb = os_mem_alloc(softs, alloc_size); + if (!rcb) { + DBG_ERR("Failed to allocate memory for rcb\n"); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + softs->rcb = rcb; + + /* Allocate sg dma memory for sg chain */ + sg_buf_size = softs->pqi_cap.max_sg_elem * + sizeof(sgt_t); + + prcb = &softs->rcb[1]; + /* Initialize rcb */ + for(i=1; i < num_req; i++) { + char tag[15]; + sprintf(tag, "sg_dma_buf%d", i); + softs->sg_dma_desc[i].tag = tag; + softs->sg_dma_desc[i].size = sg_buf_size; + softs->sg_dma_desc[i].align = PQISRC_DEFAULT_DMA_ALIGN; + + ret = os_dma_mem_alloc(softs, &softs->sg_dma_desc[i]); + if (ret) { + DBG_ERR("Failed to Allocate sg desc %d\n", ret); + ret = PQI_STATUS_FAILURE; + goto error; + } + prcb->sg_chain_virt = (sgt_t *)(softs->sg_dma_desc[i].virt_addr); + prcb->sg_chain_dma = (dma_addr_t)(softs->sg_dma_desc[i].dma_addr); + prcb ++; + } + + DBG_FUNC("OUT\n"); + return ret; +error: + pqisrc_free_rcb(softs, i); +err_out: + DBG_FUNC("failed OUT\n"); + return ret; +} + +/* + * Function used to decide the operational queue configuration params + * - no of ibq/obq, shared/non-shared interrupt resource, IU spanning support + */ +void pqisrc_decide_opq_config(pqisrc_softstate_t *softs) +{ + uint16_t total_iq_elements; + + DBG_FUNC("IN\n"); + + DBG_INFO("softs->intr_count : %d softs->num_cpus_online : %d", + softs->intr_count, softs->num_cpus_online); + + if (softs->intr_count == 1 || softs->num_cpus_online == 1) { + /* Share the event and Operational queue. */ + softs->num_op_obq = 1; + softs->share_opq_and_eventq = true; + } + else { + /* Note : One OBQ (OBQ0) reserved for event queue */ + softs->num_op_obq = MIN(softs->num_cpus_online, + softs->intr_count) - 1; + softs->num_op_obq = softs->intr_count - 1; + softs->share_opq_and_eventq = false; + } + +#ifdef MULTIPLE_MSIX + /* + * softs->num_cpus_online is set as number of physical CPUs, + * So we can have more queues/interrupts . + */ + if (softs->intr_count > 1) + softs->share_opq_and_eventq = false; +#endif + + DBG_INFO("softs->num_op_obq : %d\n",softs->num_op_obq); + + softs->num_op_raid_ibq = softs->num_op_obq; + softs->num_op_aio_ibq = softs->num_op_raid_ibq; + softs->ibq_elem_size = softs->pqi_dev_cap.max_iq_elem_len * 16; + softs->obq_elem_size = softs->pqi_dev_cap.max_oq_elem_len * 16; + if (softs->max_ib_iu_length_per_fw == 256 && + softs->ob_spanning_supported) { + /* older f/w that doesn't actually support spanning. */ + softs->max_ib_iu_length = softs->ibq_elem_size; + } else { + /* max. inbound IU length is an multiple of our inbound element size. */ + softs->max_ib_iu_length = + (softs->max_ib_iu_length_per_fw / softs->ibq_elem_size) * + softs->ibq_elem_size; + + } + /* If Max. Outstanding IO came with Max. Spanning element count then, + needed elements per IO are multiplication of + Max.Outstanding IO and Max.Spanning element */ + total_iq_elements = (softs->max_outstanding_io * + (softs->max_ib_iu_length / softs->ibq_elem_size)); + + softs->num_elem_per_op_ibq = total_iq_elements / softs->num_op_raid_ibq; + softs->num_elem_per_op_ibq = MIN(softs->num_elem_per_op_ibq, + softs->pqi_dev_cap.max_iq_elements); + + softs->num_elem_per_op_obq = softs->max_outstanding_io / softs->num_op_obq; + softs->num_elem_per_op_obq = MIN(softs->num_elem_per_op_obq, + softs->pqi_dev_cap.max_oq_elements); + + softs->max_sg_per_iu = ((softs->max_ib_iu_length - + softs->ibq_elem_size) / + sizeof(sgt_t)) + + MAX_EMBEDDED_SG_IN_FIRST_IU; + + DBG_INFO("softs->max_ib_iu_length: %d\n", softs->max_ib_iu_length); + DBG_INFO("softs->num_elem_per_op_ibq: %d\n", softs->num_elem_per_op_ibq); + DBG_INFO("softs->num_elem_per_op_obq: %d\n", softs->num_elem_per_op_obq); + DBG_INFO("softs->max_sg_per_iu: %d\n", softs->max_sg_per_iu); + + DBG_FUNC("OUT\n"); +} + +/* + * Configure the operational queue parameters. + */ +int pqisrc_configure_op_queues(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + + /* Get the PQI capability, + REPORT PQI DEVICE CAPABILITY request */ + ret = pqisrc_report_pqi_capability(softs); + if (ret) { + DBG_ERR("Failed to send report pqi dev capability request : %d\n", + ret); + goto err_out; + } + + /* Reserve required no of slots for internal requests */ + softs->max_io_for_scsi_ml = softs->max_outstanding_io - PQI_RESERVED_IO_SLOTS_CNT; + + /* Decide the Op queue configuration */ + pqisrc_decide_opq_config(softs); + + DBG_FUNC("OUT\n"); + return ret; + +err_out: + DBG_FUNC("OUT failed\n"); + return ret; +} + +/* + * Validate the PQI mode of adapter. + */ +int pqisrc_check_pqimode(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_FAILURE; + int tmo = 0; + uint64_t signature = 0; + + DBG_FUNC("IN\n"); + + /* Check the PQI device signature */ + tmo = PQISRC_PQIMODE_READY_TIMEOUT; + do { + signature = LE_64(PCI_MEM_GET64(softs, &softs->pqi_reg->signature, PQI_SIGNATURE)); + + if (memcmp(&signature, PQISRC_PQI_DEVICE_SIGNATURE, + sizeof(uint64_t)) == 0) { + ret = PQI_STATUS_SUCCESS; + break; + } + OS_SLEEP(PQISRC_MODE_READY_POLL_INTERVAL); + } while (tmo--); + + PRINT_PQI_SIGNATURE(signature); + + if (tmo <= 0) { + DBG_ERR("PQI Signature is invalid\n"); + ret = PQI_STATUS_TIMEOUT; + goto err_out; + } + + tmo = PQISRC_PQIMODE_READY_TIMEOUT; + /* Check function and status code for the device */ + COND_WAIT((PCI_MEM_GET64(softs, &softs->pqi_reg->admin_q_config, + PQI_ADMINQ_CONFIG) == PQI_ADMIN_QUEUE_CONF_FUNC_STATUS_IDLE), tmo); + if (!tmo) { + DBG_ERR("PQI device is not in IDLE state\n"); + ret = PQI_STATUS_TIMEOUT; + goto err_out; + } + + + tmo = PQISRC_PQIMODE_READY_TIMEOUT; + /* Check the PQI device status register */ + COND_WAIT(LE_32(PCI_MEM_GET32(softs, &softs->pqi_reg->pqi_dev_status, PQI_DEV_STATUS)) & + PQI_DEV_STATE_AT_INIT, tmo); + if (!tmo) { + DBG_ERR("PQI Registers are not ready\n"); + ret = PQI_STATUS_TIMEOUT; + goto err_out; + } + + DBG_FUNC("OUT\n"); + return ret; +err_out: + DBG_FUNC("OUT failed\n"); + return ret; +} + +/* + * Get the PQI configuration table parameters. + * Currently using for heart-beat counter scratch-pad register. + */ +int pqisrc_process_config_table(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_FAILURE; + uint32_t config_table_size; + uint32_t section_off; + uint8_t *config_table_abs_addr; + struct pqi_conf_table *conf_table; + struct pqi_conf_table_section_header *section_hdr; + + config_table_size = softs->pqi_cap.conf_tab_sz; + + if (config_table_size < sizeof(*conf_table) || + config_table_size > PQI_CONF_TABLE_MAX_LEN) { + DBG_ERR("Invalid PQI conf table length of %u\n", + config_table_size); + return ret; + } + + conf_table = os_mem_alloc(softs, config_table_size); + if (!conf_table) { + DBG_ERR("Failed to allocate memory for PQI conf table\n"); + return ret; + } + + config_table_abs_addr = (uint8_t *)(softs->pci_mem_base_vaddr + + softs->pqi_cap.conf_tab_off); + + PCI_MEM_GET_BUF(softs, config_table_abs_addr, + softs->pqi_cap.conf_tab_off, + (uint8_t*)conf_table, config_table_size); + + + if (memcmp(conf_table->sign, PQI_CONF_TABLE_SIGNATURE, + sizeof(conf_table->sign)) != 0) { + DBG_ERR("Invalid PQI config signature\n"); + goto out; + } + + section_off = LE_32(conf_table->first_section_off); + + while (section_off) { + + if (section_off+ sizeof(*section_hdr) >= config_table_size) { + DBG_ERR("PQI config table section offset (%u) beyond \ + end of config table (config table length: %u)\n", + section_off, config_table_size); + break; + } + + section_hdr = (struct pqi_conf_table_section_header *)((uint8_t *)conf_table + section_off); + + switch (LE_16(section_hdr->section_id)) { + case PQI_CONF_TABLE_SECTION_GENERAL_INFO: + case PQI_CONF_TABLE_SECTION_FIRMWARE_FEATURES: + case PQI_CONF_TABLE_SECTION_FIRMWARE_ERRATA: + case PQI_CONF_TABLE_SECTION_DEBUG: + break; + case PQI_CONF_TABLE_SECTION_HEARTBEAT: + softs->heartbeat_counter_off = softs->pqi_cap.conf_tab_off + + section_off + + offsetof(struct pqi_conf_table_heartbeat, + heartbeat_counter); + softs->heartbeat_counter_abs_addr = (uint64_t *)(softs->pci_mem_base_vaddr + + softs->heartbeat_counter_off); + ret = PQI_STATUS_SUCCESS; + break; + default: + DBG_ERR("unrecognized PQI config table section ID: 0x%x\n", + LE_16(section_hdr->section_id)); + break; + } + section_off = LE_16(section_hdr->next_section_off); + } +out: + os_mem_free(softs, (void *)conf_table,config_table_size); + return ret; +} + +/* Wait for PQI reset completion for the adapter*/ +int pqisrc_wait_for_pqi_reset_completion(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + pqi_reset_reg_t reset_reg; + int pqi_reset_timeout = 0; + uint64_t val = 0; + uint32_t max_timeout = 0; + + val = PCI_MEM_GET64(softs, &softs->pqi_reg->pqi_dev_adminq_cap, PQI_ADMINQ_CAP); + + max_timeout = (val & 0xFFFF00000000) >> 32; + + DBG_INFO("max_timeout for PQI reset completion in 100 msec units = %u\n", max_timeout); + + while(1) { + if (pqi_reset_timeout++ == max_timeout) { + return PQI_STATUS_TIMEOUT; + } + OS_SLEEP(PQI_RESET_POLL_INTERVAL);/* 100 msec */ + reset_reg.all_bits = PCI_MEM_GET32(softs, + &softs->pqi_reg->dev_reset, PQI_DEV_RESET); + if (reset_reg.bits.reset_action == PQI_RESET_ACTION_COMPLETED) + break; + } + + return ret; +} + +/* + * Function used to perform PQI hard reset. + */ +int pqi_reset(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t val = 0; + pqi_reset_reg_t pqi_reset_reg; + + DBG_FUNC("IN\n"); + + if (true == softs->ctrl_in_pqi_mode) { + + if (softs->pqi_reset_quiesce_allowed) { + val = PCI_MEM_GET32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR); + val |= SIS_PQI_RESET_QUIESCE; + PCI_MEM_PUT32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR, LE_32(val)); + ret = pqisrc_sis_wait_for_db_bit_to_clear(softs, SIS_PQI_RESET_QUIESCE); + if (ret) { + DBG_ERR("failed with error %d during quiesce\n", ret); + return ret; + } + } + + pqi_reset_reg.all_bits = 0; + pqi_reset_reg.bits.reset_type = PQI_RESET_TYPE_HARD_RESET; + pqi_reset_reg.bits.reset_action = PQI_RESET_ACTION_RESET; + + PCI_MEM_PUT32(softs, &softs->pqi_reg->dev_reset, PQI_DEV_RESET, + LE_32(pqi_reset_reg.all_bits)); + + ret = pqisrc_wait_for_pqi_reset_completion(softs); + if (ret) { + DBG_ERR("PQI reset timed out: ret = %d!\n", ret); + return ret; + } + } + softs->ctrl_in_pqi_mode = false; + DBG_FUNC("OUT\n"); + return ret; +} + +/* + * Initialize the adapter with supported PQI configuration. + */ +int pqisrc_pqi_init(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); + + /* Check the PQI signature */ + ret = pqisrc_check_pqimode(softs); + if(ret) { + DBG_ERR("failed to switch to pqi\n"); + goto err_out; + } + + PQI_SAVE_CTRL_MODE(softs, CTRL_PQI_MODE); + softs->ctrl_in_pqi_mode = true; + + /* Get the No. of Online CPUs,NUMA/Processor config from OS */ + ret = os_get_processor_config(softs); + if (ret) { + DBG_ERR("Failed to get processor config from OS %d\n", + ret); + goto err_out; + } + + /* Get the interrupt count, type, priority available from OS */ + ret = os_get_intr_config(softs); + if (ret) { + DBG_ERR("Failed to get interrupt config from OS %d\n", + ret); + goto err_out; + } + + /* Create Admin Queue pair*/ + ret = pqisrc_create_admin_queue(softs); + if(ret) { + DBG_ERR("Failed to configure admin queue\n"); + goto err_admin_queue; + } + + /* For creating event and IO operational queues we have to submit + admin IU requests.So Allocate resources for submitting IUs */ + + /* Allocate the request container block (rcb) */ + ret = pqisrc_allocate_rcb(softs); + if (ret == PQI_STATUS_FAILURE) { + DBG_ERR("Failed to allocate rcb \n"); + goto err_rcb; + } + + /* Allocate & initialize request id queue */ + ret = pqisrc_init_taglist(softs,&softs->taglist, + softs->max_outstanding_io); + if (ret) { + DBG_ERR("Failed to allocate memory for request id q : %d\n", + ret); + goto err_taglist; + } + + ret = pqisrc_configure_op_queues(softs); + if (ret) { + DBG_ERR("Failed to configure op queue\n"); + goto err_config_opq; + } + + /* Create Operational queues */ + ret = pqisrc_create_op_queues(softs); + if(ret) { + DBG_ERR("Failed to create op queue\n"); + ret = PQI_STATUS_FAILURE; + goto err_create_opq; + } + + softs->ctrl_online = true; + + DBG_FUNC("OUT\n"); + return ret; + +err_create_opq: +err_config_opq: + pqisrc_destroy_taglist(softs,&softs->taglist); +err_taglist: + pqisrc_free_rcb(softs, softs->max_outstanding_io + 1); +err_rcb: + pqisrc_destroy_admin_queue(softs); +err_admin_queue: + os_free_intr_config(softs); +err_out: + DBG_FUNC("OUT failed\n"); + return PQI_STATUS_FAILURE; +} + +/* */ +int pqisrc_force_sis(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + + if (SIS_IS_KERNEL_PANIC(softs)) { + DBG_INFO("Controller FW is not runnning"); + return PQI_STATUS_FAILURE; + } + + if (PQI_GET_CTRL_MODE(softs) == CTRL_SIS_MODE) { + return ret; + } + + if (SIS_IS_KERNEL_UP(softs)) { + PQI_SAVE_CTRL_MODE(softs, CTRL_SIS_MODE); + return ret; + } + /* Disable interrupts ? */ + sis_disable_msix(softs); + + /* reset pqi, this will delete queues */ + ret = pqi_reset(softs); + if (ret) { + return ret; + } + /* Re enable SIS */ + ret = pqisrc_reenable_sis(softs); + if (ret) { + return ret; + } + + PQI_SAVE_CTRL_MODE(softs, CTRL_SIS_MODE); + + return ret; +} + +/* + * Uninitialize the resources used during PQI initialization. + */ +void pqisrc_pqi_uninit(pqisrc_softstate_t *softs) +{ + int i; + DBG_FUNC("IN\n"); + + if(softs->devlist_lockcreated==true){ + os_uninit_spinlock(&softs->devlist_lock); + softs->devlist_lockcreated = false; + } + + for (i = 0; i < softs->num_op_raid_ibq; i++) { + /* OP RAID IB Q */ + if(softs->op_raid_ib_q[i].lockcreated==true){ + OS_UNINIT_PQILOCK(&softs->op_raid_ib_q[i].lock); + softs->op_raid_ib_q[i].lockcreated = false; + } + + /* OP AIO IB Q */ + if(softs->op_aio_ib_q[i].lockcreated==true){ + OS_UNINIT_PQILOCK(&softs->op_aio_ib_q[i].lock); + softs->op_aio_ib_q[i].lockcreated = false; + } + } + + /* Free Op queues */ + os_dma_mem_free(softs, &softs->op_ibq_dma_mem); + os_dma_mem_free(softs, &softs->op_obq_dma_mem); + os_dma_mem_free(softs, &softs->event_q_dma_mem); + + /* Complete all pending commands. */ + os_complete_outstanding_cmds_nodevice(softs); + + /* Free rcb */ + pqisrc_free_rcb(softs, softs->max_outstanding_io + 1); + + /* Free request id lists */ + pqisrc_destroy_taglist(softs,&softs->taglist); + + if(softs->admin_ib_queue.lockcreated==true){ + OS_UNINIT_PQILOCK(&softs->admin_ib_queue.lock); + softs->admin_ib_queue.lockcreated = false; + } + + /* Free Admin Queue */ + os_dma_mem_free(softs, &softs->admin_queue_dma_mem); + + /* Switch back to SIS mode */ + if (pqisrc_force_sis(softs)) { + DBG_ERR("Failed to switch back the adapter to SIS mode!\n"); + } + + DBG_FUNC("OUT\n"); +} + +/* + * Function to initialize the adapter settings. + */ +int pqisrc_init(pqisrc_softstate_t *softs) +{ + int ret = 0; + int i = 0, j = 0; + + DBG_FUNC("IN\n"); + + check_struct_sizes(); + + /* Init the Sync interface */ + ret = pqisrc_sis_init(softs); + if (ret) { + DBG_ERR("SIS Init failed with error %d\n", ret); + goto err_out; + } + + /* Init the PQI interface */ + ret = pqisrc_pqi_init(softs); + if (ret) { + DBG_ERR("PQI Init failed with error %d\n", ret); + goto err_pqi; + } + + /* Setup interrupt */ + ret = os_setup_intr(softs); + if (ret) { + DBG_ERR("Interrupt setup failed with error %d\n", ret); + goto err_intr; + } + + /* Report event configuration */ + ret = pqisrc_report_event_config(softs); + if(ret){ + DBG_ERR(" Failed to configure Report events\n"); + goto err_event; + } + + /* Set event configuration*/ + ret = pqisrc_set_event_config(softs); + if(ret){ + DBG_ERR(" Failed to configure Set events\n"); + goto err_event; + } + + /* Check for For PQI spanning */ + ret = pqisrc_get_ctrl_fw_version(softs); + if(ret){ + DBG_ERR(" Failed to get ctrl fw version\n"); + goto err_fw_version; + } + + /* update driver version in to FW */ + ret = pqisrc_write_driver_version_to_host_wellness(softs); + if (ret) { + DBG_ERR(" Failed to update driver version in to FW"); + goto err_host_wellness; + } + + + os_strlcpy(softs->devlist_lock_name, "devlist_lock", LOCKNAME_SIZE); + ret = os_init_spinlock(softs, &softs->devlist_lock, softs->devlist_lock_name); + if(ret){ + DBG_ERR(" Failed to initialize devlist_lock\n"); + softs->devlist_lockcreated=false; + goto err_lock; + } + softs->devlist_lockcreated = true; + + ret = os_create_semaphore("scan_lock", 1, &softs->scan_lock); + if(ret != PQI_STATUS_SUCCESS){ + DBG_ERR(" Failed to initialize scan lock\n"); + goto err_scan_lock; + } + + OS_ATOMIC64_SET(softs, num_intrs, 0); + softs->prev_num_intrs = softs->num_intrs; + + + /* Get the PQI configuration table to read heart-beat counter*/ + if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) { + ret = pqisrc_process_config_table(softs); + if (ret) { + DBG_ERR("Failed to process PQI configuration table %d\n", ret); + goto err_config_tab; + } + } + + if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) + softs->prev_heartbeat_count = CTRLR_HEARTBEAT_CNT(softs) - OS_FW_HEARTBEAT_TIMER_INTERVAL; + + /* Init device list */ + for(i = 0; i < PQI_MAX_DEVICES; i++) + for(j = 0; j < PQI_MAX_MULTILUN; j++) + softs->device_list[i][j] = NULL; + + DBG_FUNC("OUT\n"); + return ret; + +err_config_tab: + os_destroy_semaphore(&softs->scan_lock); +err_scan_lock: + if(softs->devlist_lockcreated==true){ + os_uninit_spinlock(&softs->devlist_lock); + softs->devlist_lockcreated = false; + } +err_lock: +err_fw_version: +err_event: +err_host_wellness: + os_destroy_intr(softs); +err_intr: + pqisrc_pqi_uninit(softs); +err_pqi: + pqisrc_sis_uninit(softs); +err_out: + DBG_FUNC("OUT failed\n"); + return ret; +} + +/* + * Write all data in the adapter's battery-backed cache to + * storage. + */ +int pqisrc_flush_cache( pqisrc_softstate_t *softs, + enum pqisrc_flush_cache_event_type event_type) +{ + int rval = PQI_STATUS_SUCCESS; + pqisrc_raid_req_t request; + pqisrc_bmic_flush_cache_t *flush_buff = NULL; + + DBG_FUNC("IN\n"); + + if (pqisrc_ctrl_offline(softs)) + return PQI_STATUS_FAILURE; + + flush_buff = os_mem_alloc(softs, sizeof(pqisrc_bmic_flush_cache_t)); + if (!flush_buff) { + DBG_ERR("Failed to allocate memory for flush cache params\n"); + rval = PQI_STATUS_FAILURE; + return rval; + } + + flush_buff->halt_event = event_type; + + memset(&request, 0, sizeof(request)); + + rval = pqisrc_build_send_raid_request(softs, &request, flush_buff, + sizeof(*flush_buff), SA_CACHE_FLUSH, 0, + (uint8_t *)RAID_CTLR_LUNID, NULL); + if (rval) { + DBG_ERR("error in build send raid req ret=%d\n", rval); + } + + if (flush_buff) + os_mem_free(softs, (void *)flush_buff, + sizeof(pqisrc_bmic_flush_cache_t)); + + DBG_FUNC("OUT\n"); + + return rval; +} + +/* + * Uninitialize the adapter. + */ +void pqisrc_uninit(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + + os_destroy_intr(softs); + + os_destroy_semaphore(&softs->scan_lock); + + pqisrc_pqi_uninit(softs); + + pqisrc_sis_uninit(softs); + + pqisrc_cleanup_devices(softs); + + DBG_FUNC("OUT\n"); +} Property changes on: head/sys/dev/smartpqi/smartpqi_init.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_intr.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_intr.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_intr.c (revision 333019) @@ -0,0 +1,437 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + + +/* + * Function to get processor count + */ +int os_get_processor_config(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + softs->num_cpus_online = mp_ncpus; + DBG_FUNC("OUT\n"); + + return PQI_STATUS_SUCCESS; +} + +/* + * Function to get interrupt count and type supported + */ +int os_get_intr_config(pqisrc_softstate_t *softs) +{ + device_t dev; + int msi_count = 0; + int error = 0; + int ret = PQI_STATUS_SUCCESS; + dev = softs->os_specific.pqi_dev; + + DBG_FUNC("IN\n"); + + msi_count = pci_msix_count(dev); + + if (msi_count > softs->num_cpus_online) + msi_count = softs->num_cpus_online; + if (msi_count > PQI_MAX_MSIX) + msi_count = PQI_MAX_MSIX; + if (msi_count == 0 || (error = pci_alloc_msix(dev, &msi_count)) != 0) { + device_printf(dev, "alloc msix failed - msi_count=%d, err=%d; " + "will try MSI\n", msi_count, error); + pci_release_msi(dev); + } else { + softs->intr_count = msi_count; + softs->intr_type = INTR_TYPE_MSIX; + softs->os_specific.msi_enabled = TRUE; + device_printf(dev, "using MSI-X interrupts (%d vectors)\n", + msi_count); + } + if (!softs->intr_type) { + msi_count = 1; + if ((error = pci_alloc_msi(dev, &msi_count)) != 0) { + device_printf(dev, "alloc msi failed - err=%d; " + "will use INTx\n", error); + pci_release_msi(dev); + } else { + softs->os_specific.msi_enabled = TRUE; + softs->intr_count = msi_count; + softs->intr_type = INTR_TYPE_MSI; + device_printf(dev, "using MSI interrupts\n"); + } + } + + if (!softs->intr_type) { + device_printf(dev, "using legacy interrupts\n"); + softs->intr_type = INTR_TYPE_FIXED; + softs->intr_count = 1; + } + + if(!softs->intr_type) { + DBG_FUNC("OUT failed\n"); + ret = PQI_STATUS_FAILURE; + return ret; + } + DBG_FUNC("OUT\n"); + return ret; +} + +void os_eventtaskqueue_enqueue(pqisrc_softstate_t *sc) +{ + taskqueue_enqueue(taskqueue_swi, &sc->os_specific.event_task); +} + +void pqisrc_event_worker(void *arg1, int arg2) +{ + pqisrc_ack_all_events(arg1); +} + +/* + * ithread routine to handle uniprocessor systems + */ +static void shared_ithread_routine(void *arg) +{ + pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; + pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); + int oq_id = intr_ctx->oq_id; + + DBG_FUNC("IN\n"); + + pqisrc_process_response_queue(softs, oq_id); + pqisrc_process_event_intr_src(softs, oq_id - 1); + + DBG_FUNC("OUT\n"); +} + +/* + * ithread routine to process non event response + */ +static void common_ithread_routine(void *arg) +{ + pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; + pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); + int oq_id = intr_ctx->oq_id; + + DBG_FUNC("IN\n"); + + pqisrc_process_response_queue(softs, oq_id); + + DBG_FUNC("OUT\n"); +} + +static void event_ithread_routine(void *arg) +{ + pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; + pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); + int oq_id = intr_ctx->oq_id; + + DBG_FUNC("IN\n"); + + pqisrc_process_event_intr_src(softs, oq_id); + + DBG_FUNC("OUT\n"); +} + +/* + * Registration of legacy interrupt in case MSI is unsupported + */ +int register_legacy_intr(pqisrc_softstate_t *softs) +{ + int error = 0; + device_t dev; + + DBG_FUNC("IN\n"); + + dev = softs->os_specific.pqi_dev; + + softs->os_specific.pqi_irq_rid[0] = 0; + softs->os_specific.pqi_irq[0] = bus_alloc_resource_any(dev, \ + SYS_RES_IRQ, &softs->os_specific.pqi_irq_rid[0], + RF_ACTIVE | RF_SHAREABLE); + if (NULL == softs->os_specific.pqi_irq[0]) { + DBG_ERR("Failed to allocate resource for interrupt\n"); + return PQI_STATUS_FAILURE; + } + if ((softs->os_specific.msi_ctx = os_mem_alloc(softs,sizeof(pqi_intr_ctx_t))) == NULL) { + DBG_ERR("Failed to allocate memory for msi_ctx\n"); + return PQI_STATUS_FAILURE; + } + softs->os_specific.msi_ctx[0].pqi_dev = dev; + softs->os_specific.msi_ctx[0].oq_id = 0; + + error = bus_setup_intr(dev, softs->os_specific.pqi_irq[0], + INTR_TYPE_CAM | INTR_MPSAFE, \ + NULL, shared_ithread_routine, + &softs->os_specific.msi_ctx[0], + &softs->os_specific.intrcookie[0]); + if (error) { + DBG_ERR("Failed to setup legacy interrupt err = %d\n", error); + return error; + } + softs->os_specific.intr_registered[0] = TRUE; + + DBG_FUNC("OUT error = %d\n", error); + + return error; +} + +/* + * Registration of MSIx + */ +int register_msix_intr(pqisrc_softstate_t *softs) +{ + int error = 0; + int i = 0; + device_t dev; + dev = softs->os_specific.pqi_dev; + int msix_count = softs->intr_count; + + DBG_FUNC("IN\n"); + + softs->os_specific.msi_ctx = os_mem_alloc(softs, sizeof(pqi_intr_ctx_t) * msix_count); + /*Add shared handler */ + if (softs->share_opq_and_eventq) { + softs->os_specific.pqi_irq_rid[i] = i+1; + softs->os_specific.pqi_irq[i] = bus_alloc_resource_any(dev, \ + SYS_RES_IRQ, + &softs->os_specific.pqi_irq_rid[i], + RF_SHAREABLE | RF_ACTIVE); + if (NULL == softs->os_specific.pqi_irq[i]) { + DBG_ERR("Failed to allocate \ + event interrupt resource\n"); + return PQI_STATUS_FAILURE; + } + + softs->os_specific.msi_ctx[i].pqi_dev = dev; + softs->os_specific.msi_ctx[i].oq_id = i; + + error = bus_setup_intr(dev,softs->os_specific.pqi_irq[i], + INTR_TYPE_CAM | INTR_MPSAFE,\ + NULL, + shared_ithread_routine, + &softs->os_specific.msi_ctx[i], + &softs->os_specific.intrcookie[i]); + + if (error) { + DBG_ERR("Failed to setup interrupt for events r=%d\n", + error); + return error; + } + softs->os_specific.intr_registered[i] = TRUE; + } + else { + /* Add event handler */ + softs->os_specific.pqi_irq_rid[i] = i+1; + softs->os_specific.pqi_irq[i] = bus_alloc_resource_any(dev, \ + SYS_RES_IRQ, + &softs->os_specific.pqi_irq_rid[i], + RF_SHAREABLE | RF_ACTIVE); + if (NULL == softs->os_specific.pqi_irq[i]) { + DBG_ERR("ERR : Failed to allocate \ + event interrupt resource\n"); + return PQI_STATUS_FAILURE; + } + + + softs->os_specific.msi_ctx[i].pqi_dev = dev; + softs->os_specific.msi_ctx[i].oq_id = i; + + + error = bus_setup_intr(dev,softs->os_specific.pqi_irq[i], + INTR_TYPE_CAM | INTR_MPSAFE,\ + NULL, + event_ithread_routine, + &softs->os_specific.msi_ctx[i], + &softs->os_specific.intrcookie[i]); + if (error) { + DBG_ERR("Failed to setup interrupt for events err=%d\n", + error); + return error; + } + softs->os_specific.intr_registered[i] = TRUE; + /* Add interrupt handlers*/ + for (i = 1; i < msix_count; ++i) { + softs->os_specific.pqi_irq_rid[i] = i+1; + softs->os_specific.pqi_irq[i] = \ + bus_alloc_resource_any(dev, + SYS_RES_IRQ, + &softs->os_specific.pqi_irq_rid[i], + RF_SHAREABLE | RF_ACTIVE); + if (NULL == softs->os_specific.pqi_irq[i]) { + DBG_ERR("Failed to allocate \ + msi/x interrupt resource\n"); + return PQI_STATUS_FAILURE; + } + softs->os_specific.msi_ctx[i].pqi_dev = dev; + softs->os_specific.msi_ctx[i].oq_id = i; + error = bus_setup_intr(dev, + softs->os_specific.pqi_irq[i], + INTR_TYPE_CAM | INTR_MPSAFE,\ + NULL, + common_ithread_routine, + &softs->os_specific.msi_ctx[i], + &softs->os_specific.intrcookie[i]); + if (error) { + DBG_ERR("Failed to setup \ + msi/x interrupt error = %d\n", error); + return error; + } + softs->os_specific.intr_registered[i] = TRUE; + } + } + + DBG_FUNC("OUT error = %d\n", error); + + return error; +} + +/* + * Setup interrupt depending on the configuration + */ +int os_setup_intr(pqisrc_softstate_t *softs) +{ + int error = 0; + + DBG_FUNC("IN\n"); + + if (softs->intr_type == INTR_TYPE_FIXED) { + error = register_legacy_intr(softs); + } + else { + error = register_msix_intr(softs); + } + if (error) { + DBG_FUNC("OUT failed error = %d\n", error); + return error; + } + + DBG_FUNC("OUT error = %d\n", error); + + return error; +} + +/* + * Deregistration of legacy interrupt + */ +void deregister_pqi_intx(pqisrc_softstate_t *softs) +{ + device_t dev; + + DBG_FUNC("IN\n"); + + dev = softs->os_specific.pqi_dev; + if (softs->os_specific.pqi_irq[0] != NULL) { + if (softs->os_specific.intr_registered[0]) { + bus_teardown_intr(dev, softs->os_specific.pqi_irq[0], + softs->os_specific.intrcookie[0]); + softs->os_specific.intr_registered[0] = FALSE; + } + bus_release_resource(dev, SYS_RES_IRQ, + softs->os_specific.pqi_irq_rid[0], + softs->os_specific.pqi_irq[0]); + softs->os_specific.pqi_irq[0] = NULL; + os_mem_free(softs, (char*)softs->os_specific.msi_ctx, sizeof(pqi_intr_ctx_t)); + } + + DBG_FUNC("OUT\n"); +} + +/* + * Deregistration of MSIx interrupt + */ +void deregister_pqi_msix(pqisrc_softstate_t *softs) +{ + device_t dev; + dev = softs->os_specific.pqi_dev; + int msix_count = softs->intr_count; + int i = 0; + + DBG_FUNC("IN\n"); + + os_mem_free(softs, (char*)softs->os_specific.msi_ctx, sizeof(pqi_intr_ctx_t) * msix_count); + softs->os_specific.msi_ctx = NULL; + + for (; i < msix_count; ++i) { + if (softs->os_specific.pqi_irq[i] != NULL) { + if (softs->os_specific.intr_registered[i]) { + bus_teardown_intr(dev, + softs->os_specific.pqi_irq[i], + softs->os_specific.intrcookie[i]); + softs->os_specific.intr_registered[i] = FALSE; + } + bus_release_resource(dev, SYS_RES_IRQ, + softs->os_specific.pqi_irq_rid[i], + softs->os_specific.pqi_irq[i]); + softs->os_specific.pqi_irq[i] = NULL; + } + } + + DBG_FUNC("OUT\n"); +} + +/* + * Function to destroy interrupts registered + */ +int os_destroy_intr(pqisrc_softstate_t *softs) +{ + device_t dev; + dev = softs->os_specific.pqi_dev; + + DBG_FUNC("IN\n"); + + if (softs->intr_type == INTR_TYPE_FIXED) { + deregister_pqi_intx(softs); + } else if (softs->intr_type == INTR_TYPE_MSIX) { + deregister_pqi_msix(softs); + } + if (softs->os_specific.msi_enabled) { + pci_release_msi(dev); + softs->os_specific.msi_enabled = FALSE; + } + + DBG_FUNC("OUT\n"); + + return PQI_STATUS_SUCCESS; +} + +/* + * Free interrupt related resources for the adapter + */ +void os_free_intr_config(pqisrc_softstate_t *softs) +{ + device_t dev; + dev = softs->os_specific.pqi_dev; + + DBG_FUNC("IN\n"); + + if (softs->os_specific.msi_enabled) { + pci_release_msi(dev); + softs->os_specific.msi_enabled = FALSE; + } + + DBG_FUNC("OUT\n"); +} Property changes on: head/sys/dev/smartpqi/smartpqi_intr.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_ioctl.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_ioctl.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_ioctl.c (revision 333019) @@ -0,0 +1,402 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +/* + * Management interface for smartpqi driver + */ + +#include "smartpqi_includes.h" + +/* + * Wrapper function to copy to user from kernel + */ +int os_copy_to_user(struct pqisrc_softstate *softs, void *dest_buf, + void *src_buf, int size, int mode) +{ + return(copyout(src_buf, dest_buf, size)); +} + +/* + * Wrapper function to copy from user to kernel + */ +int os_copy_from_user(struct pqisrc_softstate *softs, void *dest_buf, + void *src_buf, int size, int mode) +{ + return(copyin(src_buf, dest_buf, size)); +} + +/* + * Device open function for ioctl entry + */ +static int smartpqi_open(struct cdev *cdev, int flags, int devtype, + struct thread *td) +{ + int error = PQI_STATUS_SUCCESS; + + return error; +} + +/* + * Device close function for ioctl entry + */ +static int smartpqi_close(struct cdev *cdev, int flags, int devtype, + struct thread *td) +{ + int error = PQI_STATUS_SUCCESS; + + return error; +} + +/* + * ioctl for getting driver info + */ +static void smartpqi_get_driver_info_ioctl(caddr_t udata, struct cdev *cdev) +{ + struct pqisrc_softstate *softs = cdev->si_drv1; + pdriver_info driver_info = (pdriver_info)udata; + + DBG_FUNC("IN udata = %p cdev = %p\n", udata, cdev); + + driver_info->major_version = PQISRC_DRIVER_MAJOR; + driver_info->minor_version = PQISRC_DRIVER_MINOR; + driver_info->release_version = PQISRC_DRIVER_RELEASE; + driver_info->build_revision = PQISRC_DRIVER_REVISION; + driver_info->max_targets = PQI_MAX_DEVICES - 1; + driver_info->max_io = softs->max_io_for_scsi_ml; + driver_info->max_transfer_length = softs->pqi_cap.max_transfer_size; + + DBG_FUNC("OUT\n"); +} + +/* + * ioctl for getting controller info + */ +static void smartpqi_get_pci_info_ioctl(caddr_t udata, struct cdev *cdev) +{ + struct pqisrc_softstate *softs = cdev->si_drv1; + device_t dev = softs->os_specific.pqi_dev; + pqi_pci_info_t *pci_info = (pqi_pci_info_t *)udata; + uint32_t sub_vendor = 0; + uint32_t sub_device = 0; + uint32_t vendor = 0; + uint32_t device = 0; + + DBG_FUNC("IN udata = %p cdev = %p\n", udata, cdev); + + pci_info->bus = pci_get_bus(dev); + pci_info->dev_fn = pci_get_function(dev); + pci_info->domain = pci_get_domain(dev); + sub_vendor = pci_read_config(dev, PCIR_SUBVEND_0, 2); + sub_device = pci_read_config(dev, PCIR_SUBDEV_0, 2); + pci_info->board_id = ((sub_device << 16) & 0xffff0000) | sub_vendor; + vendor = pci_get_vendor(dev); + device = pci_get_device(dev); + pci_info->chip_id = ((device << 16) & 0xffff0000) | vendor; + DBG_FUNC("OUT\n"); +} + + +/* + * ioctl entry point for user + */ +static int smartpqi_ioctl(struct cdev *cdev, u_long cmd, caddr_t udata, + int flags, struct thread *td) +{ + int error = PQI_STATUS_SUCCESS; + struct pqisrc_softstate *softs = cdev->si_drv1; + + DBG_FUNC("IN cmd = 0x%lx udata = %p cdev = %p\n", cmd, udata, cdev); + + if (!udata) { + DBG_ERR("udata is null !!\n"); + } + + if (pqisrc_ctrl_offline(softs)){ + DBG_ERR("Controller s offline !!\n"); + return ENOTTY; + } + + switch (cmd) { + case CCISS_GETDRIVVER: + smartpqi_get_driver_info_ioctl(udata, cdev); + break; + case CCISS_GETPCIINFO: + smartpqi_get_pci_info_ioctl(udata, cdev); + break; + case SMARTPQI_PASS_THRU: + case CCISS_PASSTHRU: + error = pqisrc_passthru_ioctl(softs, udata, 0); + error = PQI_STATUS_SUCCESS; + break; + case CCISS_REGNEWD: + error = pqisrc_scan_devices(softs); + break; + default: + DBG_WARN( "!IOCTL cmd 0x%lx not supported", cmd); + error = ENOTTY; + break; + } + + DBG_FUNC("OUT error = %d\n", error); + return error; +} + +static d_open_t smartpqi_open; +static d_ioctl_t smartpqi_ioctl; +static d_close_t smartpqi_close; + +static struct cdevsw smartpqi_cdevsw = +{ + .d_version = D_VERSION, + .d_open = smartpqi_open, + .d_close = smartpqi_close, + .d_ioctl = smartpqi_ioctl, + .d_name = "smartpqi", +}; + +/* + * Function to create device node for ioctl + */ +int create_char_dev(struct pqisrc_softstate *softs, int card_index) +{ + int error = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN idx = %d\n", card_index); + + softs->os_specific.cdev = make_dev(&smartpqi_cdevsw, card_index, + UID_ROOT, GID_OPERATOR, 0640, + "smartpqi%u", card_index); + if(softs->os_specific.cdev) { + softs->os_specific.cdev->si_drv1 = softs; + } else { + error = PQI_STATUS_FAILURE; + } + + DBG_FUNC("OUT error = %d\n", error); + return error; +} + +/* + * Function to destroy device node for ioctl + */ +void destroy_char_dev(struct pqisrc_softstate *softs) +{ + DBG_FUNC("IN\n"); + if (softs->os_specific.cdev) { + destroy_dev(softs->os_specific.cdev); + softs->os_specific.cdev = NULL; + } + DBG_FUNC("OUT\n"); +} + +/* + * Function used to send passthru commands to adapter + * to support management tools. For eg. ssacli, sscon. + */ +int +pqisrc_passthru_ioctl(struct pqisrc_softstate *softs, void *arg, int mode) +{ + int ret = PQI_STATUS_SUCCESS; + char *drv_buf = NULL; + uint32_t tag = 0; + IOCTL_Command_struct *iocommand = (IOCTL_Command_struct *)arg; + dma_mem_t ioctl_dma_buf; + pqisrc_raid_req_t request; + raid_path_error_info_elem_t error_info; + ib_queue_t *ib_q = &softs->op_raid_ib_q[PQI_DEFAULT_IB_QUEUE]; + ob_queue_t *ob_q = &softs->op_ob_q[PQI_DEFAULT_IB_QUEUE]; + rcb_t *rcb = NULL; + + memset(&request, 0, sizeof(request)); + memset(&error_info, 0, sizeof(error_info)); + + DBG_FUNC("IN"); + + if (pqisrc_ctrl_offline(softs)) + return PQI_STATUS_FAILURE; + + if (!arg) + return (PQI_STATUS_FAILURE); + + if (iocommand->buf_size < 1 && + iocommand->Request.Type.Direction != PQIIOCTL_NONE) + return PQI_STATUS_FAILURE; + if (iocommand->Request.CDBLen > sizeof(request.cdb)) + return PQI_STATUS_FAILURE; + + switch (iocommand->Request.Type.Direction) { + case PQIIOCTL_NONE: + case PQIIOCTL_WRITE: + case PQIIOCTL_READ: + case PQIIOCTL_BIDIRECTIONAL: + break; + default: + return PQI_STATUS_FAILURE; + } + + if (iocommand->buf_size > 0) { + memset(&ioctl_dma_buf, 0, sizeof(struct dma_mem)); + ioctl_dma_buf.tag = "Ioctl_PassthruCmd_Buffer"; + ioctl_dma_buf.size = iocommand->buf_size; + ioctl_dma_buf.align = PQISRC_DEFAULT_DMA_ALIGN; + /* allocate memory */ + ret = os_dma_mem_alloc(softs, &ioctl_dma_buf); + if (ret) { + DBG_ERR("Failed to Allocate dma mem for Ioctl PassthruCmd Buffer : %d\n", ret); + ret = PQI_STATUS_FAILURE; + goto out; + } + + DBG_INFO("ioctl_dma_buf.dma_addr = %p\n",(void*)ioctl_dma_buf.dma_addr); + DBG_INFO("ioctl_dma_buf.virt_addr = %p\n",(void*)ioctl_dma_buf.virt_addr); + + drv_buf = (char *)ioctl_dma_buf.virt_addr; + if (iocommand->Request.Type.Direction & PQIIOCTL_WRITE) { + if ((ret = os_copy_from_user(softs, (void *)drv_buf, (void *)iocommand->buf, + iocommand->buf_size, mode)) != 0) { + ret = PQI_STATUS_FAILURE; + goto free_mem; + } + } + } + + request.header.iu_type = PQI_IU_TYPE_RAID_PATH_IO_REQUEST; + request.header.iu_length = offsetof(pqisrc_raid_req_t, sg_descriptors[1]) - + PQI_REQUEST_HEADER_LENGTH; + memcpy(request.lun_number, iocommand->LUN_info.LunAddrBytes, + sizeof(request.lun_number)); + memcpy(request.cdb, iocommand->Request.CDB, iocommand->Request.CDBLen); + request.additional_cdb_bytes_usage = PQI_ADDITIONAL_CDB_BYTES_0; + + switch (iocommand->Request.Type.Direction) { + case PQIIOCTL_NONE: + request.data_direction = SOP_DATA_DIR_NONE; + break; + case PQIIOCTL_WRITE: + request.data_direction = SOP_DATA_DIR_FROM_DEVICE; + break; + case PQIIOCTL_READ: + request.data_direction = SOP_DATA_DIR_TO_DEVICE; + break; + case PQIIOCTL_BIDIRECTIONAL: + request.data_direction = SOP_DATA_DIR_BIDIRECTIONAL; + break; + } + + request.task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; + if (iocommand->buf_size > 0) { + request.buffer_length = iocommand->buf_size; + request.sg_descriptors[0].addr = ioctl_dma_buf.dma_addr; + request.sg_descriptors[0].len = iocommand->buf_size; + request.sg_descriptors[0].flags = SG_FLAG_LAST; + } + tag = pqisrc_get_tag(&softs->taglist); + request.request_id = tag; + request.response_queue_id = ob_q->q_id; + request.error_index = request.request_id; + rcb = &softs->rcb[tag]; + + rcb->success_cmp_callback = pqisrc_process_internal_raid_response_success; + rcb->error_cmp_callback = pqisrc_process_internal_raid_response_error; + rcb->tag = tag; + rcb->req_pending = true; + /* Submit Command */ + ret = pqisrc_submit_cmnd(softs, ib_q, &request); + if (ret != PQI_STATUS_SUCCESS) { + DBG_ERR("Unable to submit command\n"); + goto err_out; + } + + ret = pqisrc_wait_on_condition(softs, rcb); + if (ret != PQI_STATUS_SUCCESS) { + DBG_ERR("Passthru IOCTL cmd timed out !!\n"); + goto err_out; + } + + memset(&iocommand->error_info, 0, sizeof(iocommand->error_info)); + + + if (rcb->status) { + size_t sense_data_length; + + memcpy(&error_info, rcb->error_info, sizeof(error_info)); + iocommand->error_info.ScsiStatus = error_info.status; + sense_data_length = error_info.sense_data_len; + + if (!sense_data_length) + sense_data_length = error_info.resp_data_len; + + if (sense_data_length && + (sense_data_length > sizeof(error_info.data))) + sense_data_length = sizeof(error_info.data); + + if (sense_data_length) { + if (sense_data_length > + sizeof(iocommand->error_info.SenseInfo)) + sense_data_length = + sizeof(iocommand->error_info.SenseInfo); + memcpy (iocommand->error_info.SenseInfo, + error_info.data, sense_data_length); + iocommand->error_info.SenseLen = sense_data_length; + } + + if (error_info.data_out_result == + PQI_RAID_DATA_IN_OUT_UNDERFLOW){ + rcb->status = REQUEST_SUCCESS; + } + } + + if (rcb->status == REQUEST_SUCCESS && iocommand->buf_size > 0 && + (iocommand->Request.Type.Direction & PQIIOCTL_READ)) { + + if ((ret = os_copy_to_user(softs, (void*)iocommand->buf, + (void*)drv_buf, iocommand->buf_size, mode)) != 0) { + DBG_ERR("Failed to copy the response\n"); + goto err_out; + } + } + + os_reset_rcb(rcb); + pqisrc_put_tag(&softs->taglist, request.request_id); + if (iocommand->buf_size > 0) + os_dma_mem_free(softs,&ioctl_dma_buf); + + DBG_FUNC("OUT\n"); + return ret; +err_out: + os_reset_rcb(rcb); + pqisrc_put_tag(&softs->taglist, request.request_id); + +free_mem: + if (iocommand->buf_size > 0) + os_dma_mem_free(softs, &ioctl_dma_buf); + +out: + DBG_FUNC("Failed OUT\n"); + return PQI_STATUS_FAILURE; +} Property changes on: head/sys/dev/smartpqi/smartpqi_ioctl.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_ioctl.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_ioctl.h (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_ioctl.h (revision 333019) @@ -0,0 +1,144 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#ifndef _PQI_IOCTL_H_ +#define _PQI_IOCTL_H_ + +/* IOCTL passthrough macros and structures */ + +#define SENSEINFOBYTES 32 /* note that this value may vary + between host implementations */ + +/* transfer direction */ +#define PQIIOCTL_NONE 0x00 +#define PQIIOCTL_WRITE 0x01 +#define PQIIOCTL_READ 0x02 +#define PQIIOCTL_BIDIRECTIONAL (PQIIOCTL_READ | PQIIOCTL_WRITE) + + +/* Type defs used in the following structs */ +#define BYTE uint8_t +#define WORD uint16_t +#define HWORD uint16_t +#define DWORD uint32_t + + + +/* Command List Structure */ +typedef union _SCSI3Addr_struct { + struct { + BYTE Dev; + BYTE Bus:6; + BYTE Mode:2; /* b00 */ + } PeripDev; + struct { + BYTE DevLSB; + BYTE DevMSB:6; + BYTE Mode:2; /* b01 */ + } LogDev; + struct { + BYTE Dev:5; + BYTE Bus:3; + BYTE Targ:6; + BYTE Mode:2; /* b10 */ + } LogUnit; + +}OS_ATTRIBUTE_PACKED SCSI3Addr_struct; + +typedef struct _PhysDevAddr_struct { + DWORD TargetId:24; + DWORD Bus:6; + DWORD Mode:2; + SCSI3Addr_struct Target[2]; /* 2 level target device addr */ + +}OS_ATTRIBUTE_PACKED PhysDevAddr_struct; + +typedef struct _LogDevAddr_struct { + DWORD VolId:30; + DWORD Mode:2; + BYTE reserved[4]; + +}OS_ATTRIBUTE_PACKED LogDevAddr_struct; + +typedef union _LUNAddr_struct { + BYTE LunAddrBytes[8]; + SCSI3Addr_struct SCSI3Lun[4]; + PhysDevAddr_struct PhysDev; + LogDevAddr_struct LogDev; + +}OS_ATTRIBUTE_PACKED LUNAddr_struct; + +typedef struct _RequestBlock_struct { + BYTE CDBLen; + struct { + BYTE Type:3; + BYTE Attribute:3; + BYTE Direction:2; + } Type; + HWORD Timeout; + BYTE CDB[16]; + +}OS_ATTRIBUTE_PACKED RequestBlock_struct; + +typedef union _MoreErrInfo_struct{ + struct { + BYTE Reserved[3]; + BYTE Type; + DWORD ErrorInfo; + } Common_Info; + struct{ + BYTE Reserved[2]; + BYTE offense_size; /* size of offending entry */ + BYTE offense_num; /* byte # of offense 0-base */ + DWORD offense_value; + } Invalid_Cmd; + +}OS_ATTRIBUTE_PACKED MoreErrInfo_struct; + +typedef struct _ErrorInfo_struct { + BYTE ScsiStatus; + BYTE SenseLen; + HWORD CommandStatus; + DWORD ResidualCnt; + MoreErrInfo_struct MoreErrInfo; + BYTE SenseInfo[SENSEINFOBYTES]; + +}OS_ATTRIBUTE_PACKED ErrorInfo_struct; + + +typedef struct pqi_ioctl_passthruCmd_struct { + LUNAddr_struct LUN_info; + RequestBlock_struct Request; + ErrorInfo_struct error_info; + WORD buf_size; /* size in bytes of the buf */ + passthru_buf_type_t buf; + +}OS_ATTRIBUTE_PACKED IOCTL_Command_struct; + + +#endif /* _PQI_IOCTL_H_ */ Property changes on: head/sys/dev/smartpqi/smartpqi_ioctl.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_main.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_main.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_main.c (revision 333019) @@ -0,0 +1,500 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +/* + * Driver for the Microsemi Smart storage controllers + */ + +#include "smartpqi_includes.h" +#include "smartpqi_prototypes.h" + +/* + * Supported devices + */ +struct pqi_ident +{ + u_int16_t vendor; + u_int16_t device; + u_int16_t subvendor; + u_int16_t subdevice; + int hwif; + char *desc; +} pqi_identifiers[] = { + /* (MSCC PM8205 8x12G based) */ + {0x9005, 0x028f, 0x103c, 0x600, PQI_HWIF_SRCV, "P408i-p SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x601, PQI_HWIF_SRCV, "P408e-p SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x602, PQI_HWIF_SRCV, "P408i-a SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x603, PQI_HWIF_SRCV, "P408i-c SR Gen10"}, + {0x9005, 0x028f, 0x1028, 0x1FE0, PQI_HWIF_SRCV, "SmartRAID 3162-8i/eDell"}, + {0x9005, 0x028f, 0x9005, 0x608, PQI_HWIF_SRCV, "SmartRAID 3162-8i/e"}, + {0x9005, 0x028f, 0x103c, 0x609, PQI_HWIF_SRCV, "P408i-sb SR G10"}, + + /* (MSCC PM8225 8x12G based) */ + {0x9005, 0x028f, 0x103c, 0x650, PQI_HWIF_SRCV, "E208i-p SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x651, PQI_HWIF_SRCV, "E208e-p SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x652, PQI_HWIF_SRCV, "E208i-c SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x654, PQI_HWIF_SRCV, "E208i-a SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x655, PQI_HWIF_SRCV, "P408e-m SR Gen10"}, + + /* (MSCC PM8221 8x12G based) */ + {0x9005, 0x028f, 0x103c, 0x700, PQI_HWIF_SRCV, "P204i-c SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x701, PQI_HWIF_SRCV, "P204i-b SR Gen10"}, + + /* (MSCC PM8204 8x12G based) */ + {0x9005, 0x028f, 0x9005, 0x800, PQI_HWIF_SRCV, "SmartRAID 3154-8i"}, + {0x9005, 0x028f, 0x9005, 0x801, PQI_HWIF_SRCV, "SmartRAID 3152-8i"}, + {0x9005, 0x028f, 0x9005, 0x802, PQI_HWIF_SRCV, "SmartRAID 3151-4i"}, + {0x9005, 0x028f, 0x9005, 0x803, PQI_HWIF_SRCV, "SmartRAID 3101-4i"}, + {0x9005, 0x028f, 0x9005, 0x804, PQI_HWIF_SRCV, "SmartRAID 3154-8e"}, + {0x9005, 0x028f, 0x9005, 0x805, PQI_HWIF_SRCV, "SmartRAID 3102-8i"}, + {0x9005, 0x028f, 0x9005, 0x806, PQI_HWIF_SRCV, "SmartRAID 3100"}, + {0x9005, 0x028f, 0x9005, 0x807, PQI_HWIF_SRCV, "SmartRAID 3162-8i"}, + {0x9005, 0x028f, 0x152d, 0x8a22, PQI_HWIF_SRCV, "QS-8204-8i"}, + + /* (MSCC PM8222 8x12G based) */ + {0x9005, 0x028f, 0x9005, 0x900, PQI_HWIF_SRCV, "SmartHBA 2100-8i"}, + {0x9005, 0x028f, 0x9005, 0x901, PQI_HWIF_SRCV, "SmartHBA 2100-4i"}, + {0x9005, 0x028f, 0x9005, 0x902, PQI_HWIF_SRCV, "HBA 1100-8i"}, + {0x9005, 0x028f, 0x9005, 0x903, PQI_HWIF_SRCV, "HBA 1100-4i"}, + {0x9005, 0x028f, 0x9005, 0x904, PQI_HWIF_SRCV, "SmartHBA 2100-8e"}, + {0x9005, 0x028f, 0x9005, 0x905, PQI_HWIF_SRCV, "HBA 1100-8e"}, + {0x9005, 0x028f, 0x9005, 0x906, PQI_HWIF_SRCV, "SmartHBA 2100-4i4e"}, + {0x9005, 0x028f, 0x9005, 0x907, PQI_HWIF_SRCV, "HBA 1100"}, + {0x9005, 0x028f, 0x9005, 0x908, PQI_HWIF_SRCV, "SmartHBA 2100"}, + {0x9005, 0x028f, 0x9005, 0x90a, PQI_HWIF_SRCV, "SmartHBA 2100A-8i"}, + + /* (SRCx MSCC FVB 24x12G based) */ + {0x9005, 0x028f, 0x103c, 0x1001, PQI_HWIF_SRCV, "MSCC FVB"}, + + /* (MSCC PM8241 24x12G based) */ + + /* (MSCC PM8242 24x12G based) */ + {0x9005, 0x028f, 0x152d, 0x8a37, PQI_HWIF_SRCV, "QS-8242-24i"}, + {0x9005, 0x028f, 0x9005, 0x1300, PQI_HWIF_SRCV, "HBA 1100-8i8e"}, + {0x9005, 0x028f, 0x9005, 0x1301, PQI_HWIF_SRCV, "HBA 1100-24i"}, + {0x9005, 0x028f, 0x9005, 0x1302, PQI_HWIF_SRCV, "SmartHBA 2100-8i8e"}, + {0x9005, 0x028f, 0x9005, 0x1303, PQI_HWIF_SRCV, "SmartHBA 2100-24i"}, + + /* (MSCC PM8236 16x12G based) */ + {0x9005, 0x028f, 0x152d, 0x8a24, PQI_HWIF_SRCV, "QS-8236-16i"}, + {0x9005, 0x028f, 0x9005, 0x1380, PQI_HWIF_SRCV, "SmartRAID 3154-16i"}, + + /* (MSCC PM8237 24x12G based) */ + {0x9005, 0x028f, 0x103c, 0x1100, PQI_HWIF_SRCV, "P816i-a SR Gen10"}, + {0x9005, 0x028f, 0x103c, 0x1101, PQI_HWIF_SRCV, "P416ie-m SR G10"}, + + /* (MSCC PM8238 16x12G based) */ + {0x9005, 0x028f, 0x152d, 0x8a23, PQI_HWIF_SRCV, "QS-8238-16i"}, + {0x9005, 0x028f, 0x9005, 0x1280, PQI_HWIF_SRCV, "HBA 1100-16i"}, + {0x9005, 0x028f, 0x9005, 0x1281, PQI_HWIF_SRCV, "HBA 1100-16e"}, + + /* (MSCC PM8240 24x12G based) */ + {0x9005, 0x028f, 0x152d, 0x8a36, PQI_HWIF_SRCV, "QS-8240-24i"}, + {0x9005, 0x028f, 0x9005, 0x1200, PQI_HWIF_SRCV, "SmartRAID 3154-24i"}, + {0x9005, 0x028f, 0x9005, 0x1201, PQI_HWIF_SRCV, "SmartRAID 3154-8i16e"}, + {0x9005, 0x028f, 0x9005, 0x1202, PQI_HWIF_SRCV, "SmartRAID 3154-8i8e"}, + + {0, 0, 0, 0, 0, 0} +}; + +struct pqi_ident +pqi_family_identifiers[] = { + {0x9005, 0x028f, 0, 0, PQI_HWIF_SRCV, "Smart Array Storage Controller"}, + {0, 0, 0, 0, 0, 0} +}; + +/* + * Function to identify the installed adapter. + */ +static struct pqi_ident * +pqi_find_ident(device_t dev) +{ + struct pqi_ident *m; + u_int16_t vendid, devid, sub_vendid, sub_devid; + + vendid = pci_get_vendor(dev); + devid = pci_get_device(dev); + sub_vendid = pci_get_subvendor(dev); + sub_devid = pci_get_subdevice(dev); + + for (m = pqi_identifiers; m->vendor != 0; m++) { + if ((m->vendor == vendid) && (m->device == devid) && + (m->subvendor == sub_vendid) && + (m->subdevice == sub_devid)) { + return (m); + } + } + + for (m = pqi_family_identifiers; m->vendor != 0; m++) { + if ((m->vendor == vendid) && (m->device == devid)) { + return (m); + } + } + + return (NULL); +} + +/* + * Determine whether this is one of our supported adapters. + */ +static int +smartpqi_probe(device_t dev) +{ + struct pqi_ident *id; + + if ((id = pqi_find_ident(dev)) != NULL) { + device_set_desc(dev, id->desc); + return(BUS_PROBE_VENDOR); + } + + return(ENXIO); +} + +/* + * Store Bus/Device/Function in softs + */ +void pqisrc_save_controller_info(struct pqisrc_softstate *softs) +{ + device_t dev = softs->os_specific.pqi_dev; + + softs->bus_id = (uint32_t)pci_get_bus(dev); + softs->device_id = (uint32_t)pci_get_device(dev); + softs->func_id = (uint32_t)pci_get_function(dev); +} + + +/* + * Allocate resources for our device, set up the bus interface. + * Initialize the PQI related functionality, scan devices, register sim to + * upper layer, create management interface device node etc. + */ +static int +smartpqi_attach(device_t dev) +{ + struct pqisrc_softstate *softs = NULL; + struct pqi_ident *id = NULL; + int error = 0; + u_int32_t command = 0, i = 0; + int card_index = device_get_unit(dev); + rcb_t *rcbp = NULL; + + /* + * Initialise softc. + */ + softs = device_get_softc(dev); + + if (!softs) { + printf("Could not get softc\n"); + error = EINVAL; + goto out; + } + memset(softs, 0, sizeof(*softs)); + softs->os_specific.pqi_dev = dev; + + DBG_FUNC("IN\n"); + + /* assume failure is 'not configured' */ + error = ENXIO; + + /* + * Verify that the adapter is correctly set up in PCI space. + */ + pci_enable_busmaster(softs->os_specific.pqi_dev); + command = pci_read_config(softs->os_specific.pqi_dev, PCIR_COMMAND, 2); + if ((command & PCIM_CMD_MEMEN) == 0) { + DBG_ERR("memory window not available command = %d\n", command); + error = ENXIO; + goto out; + } + + /* + * Detect the hardware interface version, set up the bus interface + * indirection. + */ + id = pqi_find_ident(dev); + softs->os_specific.pqi_hwif = id->hwif; + + switch(softs->os_specific.pqi_hwif) { + case PQI_HWIF_SRCV: + DBG_INFO("set hardware up for PMC SRCv for %p", softs); + break; + default: + softs->os_specific.pqi_hwif = PQI_HWIF_UNKNOWN; + DBG_ERR("unknown hardware type\n"); + error = ENXIO; + goto out; + } + + pqisrc_save_controller_info(softs); + + /* + * Allocate the PCI register window. + */ + softs->os_specific.pqi_regs_rid0 = PCIR_BAR(0); + if ((softs->os_specific.pqi_regs_res0 = + bus_alloc_resource_any(softs->os_specific.pqi_dev, SYS_RES_MEMORY, + &softs->os_specific.pqi_regs_rid0, RF_ACTIVE)) == NULL) { + DBG_ERR("couldn't allocate register window 0\n"); + /* assume failure is 'out of memory' */ + error = ENOMEM; + goto out; + } + + bus_get_resource_start(softs->os_specific.pqi_dev, SYS_RES_MEMORY, + softs->os_specific.pqi_regs_rid0); + + softs->pci_mem_handle.pqi_btag = rman_get_bustag(softs->os_specific.pqi_regs_res0); + softs->pci_mem_handle.pqi_bhandle = rman_get_bushandle(softs->os_specific.pqi_regs_res0); + /* softs->pci_mem_base_vaddr = (uintptr_t)rman_get_virtual(softs->os_specific.pqi_regs_res0); */ + softs->pci_mem_base_vaddr = (char *)rman_get_virtual(softs->os_specific.pqi_regs_res0); + + /* + * Allocate the parent bus DMA tag appropriate for our PCI interface. + * + * Note that some of these controllers are 64-bit capable. + */ + if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ + PAGE_SIZE, 0, /* algnmnt, boundary */ + BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ + BUS_SPACE_UNRESTRICTED, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* No locking needed */ + &softs->os_specific.pqi_parent_dmat)) { + DBG_ERR("can't allocate parent DMA tag\n"); + /* assume failure is 'out of memory' */ + error = ENOMEM; + goto dma_out; + } + + softs->os_specific.sim_registered = FALSE; + softs->os_name = "FreeBSD "; + + /* Initialize the PQI library */ + error = pqisrc_init(softs); + if (error) { + DBG_ERR("Failed to initialize pqi lib error = %d\n", error); + error = PQI_STATUS_FAILURE; + goto out; + } + + mtx_init(&softs->os_specific.cam_lock, "cam_lock", NULL, MTX_DEF); + softs->os_specific.mtx_init = TRUE; + mtx_init(&softs->os_specific.map_lock, "map_lock", NULL, MTX_DEF); + + /* + * Create DMA tag for mapping buffers into controller-addressable space. + */ + if (bus_dma_tag_create(softs->os_specific.pqi_parent_dmat,/* parent */ + 1, 0, /* algnmnt, boundary */ + BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + softs->pqi_cap.max_sg_elem*PAGE_SIZE,/*maxsize*/ + softs->pqi_cap.max_sg_elem, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + BUS_DMA_ALLOCNOW, /* flags */ + busdma_lock_mutex, /* lockfunc */ + &softs->os_specific.map_lock, /* lockfuncarg*/ + &softs->os_specific.pqi_buffer_dmat)) { + DBG_ERR("can't allocate buffer DMA tag for pqi_buffer_dmat\n"); + return (ENOMEM); + } + + rcbp = &softs->rcb[1]; + for( i = 1; i <= softs->pqi_cap.max_outstanding_io; i++, rcbp++ ) { + if ((error = bus_dmamap_create(softs->os_specific.pqi_buffer_dmat, 0, &rcbp->cm_datamap)) != 0) { + DBG_ERR("Cant create datamap for buf @" + "rcbp = %p maxio = %d error = %d\n", + rcbp, softs->pqi_cap.max_outstanding_io, error); + goto dma_out; + } + } + + os_start_heartbeat_timer((void *)softs); /* Start the heart-beat timer */ + softs->os_specific.wellness_periodic = timeout( os_wellness_periodic, + softs, 120*hz); + /* Register our shutdown handler. */ + softs->os_specific.eh = EVENTHANDLER_REGISTER(shutdown_final, + smartpqi_shutdown, softs, SHUTDOWN_PRI_DEFAULT); + + error = pqisrc_scan_devices(softs); + if (error) { + DBG_ERR("Failed to scan lib error = %d\n", error); + error = PQI_STATUS_FAILURE; + goto out; + } + + error = register_sim(softs, card_index); + if (error) { + DBG_ERR("Failed to register sim index = %d error = %d\n", + card_index, error); + goto out; + } + + smartpqi_target_rescan(softs); + + TASK_INIT(&softs->os_specific.event_task, 0, pqisrc_event_worker,softs); + + error = create_char_dev(softs, card_index); + if (error) { + DBG_ERR("Failed to register character device index=%d r=%d\n", + card_index, error); + goto out; + } + goto out; + +dma_out: + if (softs->os_specific.pqi_regs_res0 != NULL) + bus_release_resource(softs->os_specific.pqi_dev, SYS_RES_MEMORY, + softs->os_specific.pqi_regs_rid0, + softs->os_specific.pqi_regs_res0); +out: + DBG_FUNC("OUT error = %d\n", error); + return(error); +} + +/* + * Deallocate resources for our device. + */ +static int +smartpqi_detach(device_t dev) +{ + struct pqisrc_softstate *softs = NULL; + softs = device_get_softc(dev); + DBG_FUNC("IN\n"); + + EVENTHANDLER_DEREGISTER(shutdown_final, softs->os_specific.eh); + + /* kill the periodic event */ + untimeout(os_wellness_periodic, softs, + softs->os_specific.wellness_periodic); + /* Kill the heart beat event */ + untimeout(os_start_heartbeat_timer, softs, + softs->os_specific.heartbeat_timeout_id); + + smartpqi_shutdown(softs); + destroy_char_dev(softs); + pqisrc_uninit(softs); + deregister_sim(softs); + pci_release_msi(dev); + + DBG_FUNC("OUT\n"); + return 0; +} + +/* + * Bring the controller to a quiescent state, ready for system suspend. + */ +static int +smartpqi_suspend(device_t dev) +{ + struct pqisrc_softstate *softs; + softs = device_get_softc(dev); + DBG_FUNC("IN\n"); + + DBG_INFO("Suspending the device %p\n", softs); + softs->os_specific.pqi_state |= SMART_STATE_SUSPEND; + + DBG_FUNC("OUT\n"); + return(0); +} + +/* + * Bring the controller back to a state ready for operation. + */ +static int +smartpqi_resume(device_t dev) +{ + struct pqisrc_softstate *softs; + softs = device_get_softc(dev); + DBG_FUNC("IN\n"); + + softs->os_specific.pqi_state &= ~SMART_STATE_SUSPEND; + + DBG_FUNC("OUT\n"); + return(0); +} + +/* + * Do whatever is needed during a system shutdown. + */ +int +smartpqi_shutdown(void *arg) +{ + struct pqisrc_softstate *softs = NULL; + int rval = 0; + + DBG_FUNC("IN\n"); + + softs = (struct pqisrc_softstate *)arg; + + rval = pqisrc_flush_cache(softs, PQISRC_SHUTDOWN); + if (rval != PQI_STATUS_SUCCESS) { + DBG_ERR("Unable to flush adapter cache! rval = %d", rval); + } + + DBG_FUNC("OUT\n"); + + return rval; +} + + +static int smartpqi_probe(device_t dev); +static int smartpqi_attach(device_t dev); +static int smartpqi_detach(device_t dev); +static int smartpqi_suspend(device_t dev); +static int smartpqi_resume(device_t dev); + +/* + * PCI bus interface. + */ +static device_method_t pqi_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, smartpqi_probe), + DEVMETHOD(device_attach, smartpqi_attach), + DEVMETHOD(device_detach, smartpqi_detach), + DEVMETHOD(device_suspend, smartpqi_suspend), + DEVMETHOD(device_resume, smartpqi_resume), + { 0, 0 } +}; + +static devclass_t pqi_devclass; +static driver_t smartpqi_pci_driver = { + "smartpqi", + pqi_methods, + sizeof(struct pqisrc_softstate) +}; + +DRIVER_MODULE(smartpqi, pci, smartpqi_pci_driver, pqi_devclass, 0, 0); +MODULE_DEPEND(smartpqi, pci, 1, 1, 1); + + Property changes on: head/sys/dev/smartpqi/smartpqi_main.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_mem.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_mem.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_mem.c (revision 333019) @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +MALLOC_DEFINE(M_SMARTRAID, "smartraidbuf", "Buffers for the smartraid driver"); + +/* + * DMA map load callback function + */ +static void +os_dma_map(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + bus_addr_t *paddr = (bus_addr_t *)arg; + *paddr = segs[0].ds_addr; +} + +int os_dma_setup(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + DBG_FUNC("OUT\n"); + return PQI_STATUS_SUCCESS; +} + +int os_dma_destroy(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + DBG_FUNC("OUT\n"); + return PQI_STATUS_SUCCESS; +} + +/* + * DMA mem resource allocation wrapper function + */ +int os_dma_mem_alloc(pqisrc_softstate_t *softs, struct dma_mem *dma_mem) +{ + int ret = 0; + + /* DBG_FUNC("IN\n"); */ + + /* DMA memory needed - allocate it */ + if ((ret = bus_dma_tag_create( + softs->os_specific.pqi_parent_dmat, /* parent */ + dma_mem->align, 0, /* algnmnt, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + dma_mem->size, /* maxsize */ + 1, /* nsegments */ + dma_mem->size, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* No locking needed */ + &dma_mem->dma_tag)) != 0 ) { + DBG_ERR("can't allocate DMA tag with error = 0x%x\n", ret); + goto err_out; + } + if ((ret = bus_dmamem_alloc(dma_mem->dma_tag, (void **)&dma_mem->virt_addr, + BUS_DMA_NOWAIT, &dma_mem->dma_map)) != 0) { + DBG_ERR("can't allocate DMA memory for required object \ + with error = 0x%x\n", ret); + goto err_mem; + } + + if((ret = bus_dmamap_load(dma_mem->dma_tag, dma_mem->dma_map, + dma_mem->virt_addr, dma_mem->size, + os_dma_map, &dma_mem->dma_addr, 0)) != 0) { + DBG_ERR("can't load DMA memory for required \ + object with error = 0x%x\n", ret); + goto err_load; + } + + memset(dma_mem->virt_addr, 0, dma_mem->size); + + /* DBG_FUNC("OUT\n"); */ + return ret; + +err_load: + if(dma_mem->virt_addr) + bus_dmamem_free(dma_mem->dma_tag, dma_mem->virt_addr, + dma_mem->dma_map); +err_mem: + if(dma_mem->dma_tag) + bus_dma_tag_destroy(dma_mem->dma_tag); +err_out: + DBG_FUNC("failed OUT\n"); + return ret; +} + +/* + * DMA mem resource deallocation wrapper function + */ +void os_dma_mem_free(pqisrc_softstate_t *softs, struct dma_mem *dma_mem) +{ + /* DBG_FUNC("IN\n"); */ + + if(dma_mem->dma_addr) { + bus_dmamap_unload(dma_mem->dma_tag, dma_mem->dma_map); + dma_mem->dma_addr = 0; + } + + if(dma_mem->virt_addr) { + bus_dmamem_free(dma_mem->dma_tag, dma_mem->virt_addr, + dma_mem->dma_map); + dma_mem->virt_addr = NULL; + } + + if(dma_mem->dma_tag) { + bus_dma_tag_destroy(dma_mem->dma_tag); + dma_mem->dma_tag = NULL; + } + + /* DBG_FUNC("OUT\n"); */ +} + + +/* + * Mem resource allocation wrapper function + */ +void *os_mem_alloc(pqisrc_softstate_t *softs, size_t size) +{ + void *addr = NULL; + + /* DBG_FUNC("IN\n"); */ + + addr = malloc((unsigned long)size, M_SMARTRAID, + M_NOWAIT | M_ZERO); + +/* DBG_FUNC("OUT\n"); */ + + return addr; +} + +/* + * Mem resource deallocation wrapper function + */ +void os_mem_free(pqisrc_softstate_t *softs, + char *addr, size_t size) +{ + /* DBG_FUNC("IN\n"); */ + + free((void*)addr, M_SMARTRAID); + + /* DBG_FUNC("OUT\n"); */ +} + +/* + * dma/bus resource deallocation wrapper function + */ +void os_resource_free(pqisrc_softstate_t *softs) +{ + if(softs->os_specific.pqi_parent_dmat) + bus_dma_tag_destroy(softs->os_specific.pqi_parent_dmat); + + if (softs->os_specific.pqi_regs_res0 != NULL) + bus_release_resource(softs->os_specific.pqi_dev, + SYS_RES_MEMORY, + softs->os_specific.pqi_regs_rid0, + softs->os_specific.pqi_regs_res0); +} Property changes on: head/sys/dev/smartpqi/smartpqi_mem.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_misc.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_misc.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_misc.c (revision 333019) @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* + * Populate hostwell time variables in bcd format from FreeBSD format + */ +void os_get_time(struct bmic_host_wellness_time *host_wellness_time) +{ + struct timespec ts; + struct clocktime ct; + + getnanotime(&ts); + clock_ts_to_ct(&ts, &ct); + + + /* Fill the time In BCD Format */ + host_wellness_time->hour= (uint8_t)bin2bcd(ct.hour); + host_wellness_time->min = (uint8_t)bin2bcd(ct.min); + host_wellness_time->sec= (uint8_t)bin2bcd(ct.sec); + host_wellness_time->reserved = 0; + host_wellness_time->month = (uint8_t)bin2bcd(ct.mon); + host_wellness_time->day = (uint8_t)bin2bcd(ct.day); + host_wellness_time->century = (uint8_t)bin2bcd(ct.year / 100); + host_wellness_time->year = (uint8_t)bin2bcd(ct.year % 100); + +} + +/* + * Update host time to f/w every 24 hours in a periodic timer. + */ + +void os_wellness_periodic(void *data) +{ + struct pqisrc_softstate *softs = (struct pqisrc_softstate *)data; + int ret = 0; + + + /* update time to FW */ + if (!pqisrc_ctrl_offline(softs)){ + if( (ret = pqisrc_write_current_time_to_host_wellness(softs)) != 0 ) + DBG_ERR("Failed to update time to FW in periodic ret = %d\n", ret); + } + + /* reschedule ourselves */ + softs->os_specific.wellness_periodic = timeout(os_wellness_periodic, + softs, OS_HOST_WELLNESS_TIMEOUT * hz); +} + +/* + * Routine used to stop the heart-beat timer + */ +void os_stop_heartbeat_timer(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + + /* Kill the heart beat event */ + untimeout(os_start_heartbeat_timer, softs, + softs->os_specific.heartbeat_timeout_id); + + DBG_FUNC("OUT\n"); +} + +/* + * Routine used to start the heart-beat timer + */ +void os_start_heartbeat_timer(void *data) +{ + struct pqisrc_softstate *softs = (struct pqisrc_softstate *)data; + DBG_FUNC("IN\n"); + + pqisrc_heartbeat_timer_handler(softs); + if (!pqisrc_ctrl_offline(softs)) { + softs->os_specific.heartbeat_timeout_id = + timeout(os_start_heartbeat_timer, softs, + OS_FW_HEARTBEAT_TIMER_INTERVAL * hz); + } + + DBG_FUNC("OUT\n"); +} + +/* + * Mutex initialization function + */ +int os_init_spinlock(struct pqisrc_softstate *softs, struct mtx *lock, + char *lockname) +{ + mtx_init(lock, lockname, NULL, MTX_SPIN); + return 0; + +} + +/* + * Mutex uninitialization function + */ +void os_uninit_spinlock(struct mtx *lock) +{ + mtx_destroy(lock); + return; + +} + +/* + * Semaphore initialization function + */ +int os_create_semaphore(const char *name, int value, struct sema *sema) +{ + sema_init(sema, value, name); + return PQI_STATUS_SUCCESS; + +} + +/* + * Semaphore uninitialization function + */ +int os_destroy_semaphore(struct sema *sema) +{ + sema_destroy(sema); + return PQI_STATUS_SUCCESS; + +} + +/* + * Semaphore grab function + */ +void inline os_sema_lock(struct sema *sema) +{ + sema_post(sema); +} + +/* + * Semaphore release function + */ +void inline os_sema_unlock(struct sema *sema) +{ + sema_wait(sema); +} + + +/* + * string copy wrapper function + */ +int os_strlcpy(char *dst, char *src, int size) +{ + return strlcpy(dst, src, size); +} Property changes on: head/sys/dev/smartpqi/smartpqi_misc.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_prototypes.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_prototypes.h (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_prototypes.h (revision 333019) @@ -0,0 +1,263 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#ifndef _PQI_PROTOTYPES_H +#define _PQI_PROTOTYPES_H + +/* Function prototypes */ + +/*pqi_init.c */ +int pqisrc_init(pqisrc_softstate_t *); +void pqisrc_uninit(pqisrc_softstate_t *); +void pqisrc_pqi_uninit(pqisrc_softstate_t *); +int pqisrc_process_config_table(pqisrc_softstate_t *); +int pqisrc_flush_cache(pqisrc_softstate_t *, enum pqisrc_flush_cache_event_type); +int pqisrc_wait_for_pqi_reset_completion(pqisrc_softstate_t *); + +/* pqi_sis.c*/ +int pqisrc_sis_init(pqisrc_softstate_t *); +void pqisrc_sis_uninit(pqisrc_softstate_t *); +int pqisrc_reenable_sis(pqisrc_softstate_t *); +void pqisrc_trigger_nmi_sis(pqisrc_softstate_t *); +void sis_disable_msix(pqisrc_softstate_t *); +int pqisrc_force_sis(pqisrc_softstate_t *); +int pqisrc_sis_wait_for_db_bit_to_clear(pqisrc_softstate_t *, uint32_t); + +/* pqi_queue.c */ +int pqisrc_submit_admin_req(pqisrc_softstate_t *, + gen_adm_req_iu_t *, gen_adm_resp_iu_t *); +int pqisrc_create_admin_queue(pqisrc_softstate_t *); +int pqisrc_destroy_admin_queue(pqisrc_softstate_t *); +int pqisrc_create_op_queues(pqisrc_softstate_t *); + +/* pqi_cmd.c */ +int pqisrc_submit_cmnd(pqisrc_softstate_t *,ib_queue_t *,void *); + +/* pqi_tag.c */ +#ifndef LOCKFREE_STACK +int pqisrc_init_taglist(pqisrc_softstate_t *,pqi_taglist_t *,uint32_t); +void pqisrc_destroy_taglist(pqisrc_softstate_t *,pqi_taglist_t *); +void pqisrc_put_tag(pqi_taglist_t *,uint32_t); +uint32_t pqisrc_get_tag(pqi_taglist_t *); +#else +int pqisrc_init_taglist(pqisrc_softstate_t *, lockless_stack_t *, uint32_t); +void pqisrc_destroy_taglist(pqisrc_softstate_t *, lockless_stack_t *); +void pqisrc_put_tag(lockless_stack_t *,uint32_t); +uint32_t pqisrc_get_tag(lockless_stack_t *); +#endif /* LOCKFREE_STACK */ + +/* pqi_discovery.c */ +void pqisrc_remove_device(pqisrc_softstate_t *, pqi_scsi_dev_t *); +int pqisrc_get_ctrl_fw_version(pqisrc_softstate_t *); +int pqisrc_rescan_devices(pqisrc_softstate_t *); +int pqisrc_scan_devices(pqisrc_softstate_t *); +void pqisrc_process_raid_path_io_response(pqisrc_softstate_t *, uint16_t, struct pqi_io_response *); +void pqisrc_process_io_error_response(pqisrc_softstate_t *, int, uint16_t, struct pqi_io_response *); +void pqisrc_cleanup_devices(pqisrc_softstate_t *); +void pqisrc_device_mem_free(pqisrc_softstate_t *, pqi_scsi_dev_t *); +boolean_t pqisrc_is_external_raid_device(pqi_scsi_dev_t *device); +void pqisrc_free_device(pqisrc_softstate_t * softs,pqi_scsi_dev_t *device); + +/* pqi_helper.c */ +boolean_t pqisrc_ctrl_offline(pqisrc_softstate_t *); +void pqisrc_heartbeat_timer_handler(pqisrc_softstate_t *); +int pqisrc_wait_on_condition(pqisrc_softstate_t *, rcb_t *); +boolean_t pqisrc_device_equal(pqi_scsi_dev_t *, pqi_scsi_dev_t *); +boolean_t pqisrc_is_hba_lunid(uint8_t *); +boolean_t pqisrc_is_logical_device(pqi_scsi_dev_t *); +void pqisrc_sanitize_inquiry_string(unsigned char *, int ); +void pqisrc_display_device_info(pqisrc_softstate_t *, char *, pqi_scsi_dev_t *); +boolean_t pqisrc_scsi3addr_equal(uint8_t *, uint8_t *); +void check_struct_sizes(void); +char *pqisrc_raidlevel_to_string(uint8_t); + +/* pqi_response.c */ +void pqisrc_signal_event(pqisrc_softstate_t *softs, rcb_t *rcb); +void pqisrc_process_internal_raid_response_success(pqisrc_softstate_t *, + rcb_t *); +void pqisrc_process_internal_raid_response_error(pqisrc_softstate_t *, + rcb_t *, uint16_t); +void pqisrc_process_io_response_success(pqisrc_softstate_t *, + rcb_t *); +void pqisrc_process_aio_response_error(pqisrc_softstate_t *, + rcb_t *, uint16_t); +void pqisrc_process_raid_response_error(pqisrc_softstate_t *, + rcb_t *, uint16_t); +void pqisrc_process_response_queue(pqisrc_softstate_t *, int); + + +/* pqi_request.c */ +int pqisrc_build_send_io(pqisrc_softstate_t *,rcb_t *); + + +int pqisrc_send_scsi_cmd_raidbypass(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device, rcb_t *rcb, uint8_t*); + + +int pqisrc_send_tmf(pqisrc_softstate_t *, pqi_scsi_dev_t *, + rcb_t *, int, int); +int pqisrc_write_current_time_to_host_wellness(pqisrc_softstate_t *softs); +int pqisrc_write_driver_version_to_host_wellness(pqisrc_softstate_t *softs); + +/* pqi_event.c*/ +int pqisrc_report_event_config(pqisrc_softstate_t *); +int pqisrc_set_event_config(pqisrc_softstate_t *); +int pqisrc_process_event_intr_src(pqisrc_softstate_t *,int); +void pqisrc_ack_all_events(void *arg); + + +void pqisrc_event_worker(void *, int); +int pqisrc_scsi_setup(struct pqisrc_softstate *); +void pqisrc_scsi_cleanup(struct pqisrc_softstate *); +boolean_t pqisrc_update_scsi_sense(const uint8_t *, int, + struct sense_header_scsi *); +int pqisrc_build_send_raid_request(pqisrc_softstate_t *, pqisrc_raid_req_t *, + void *, size_t, uint8_t, uint16_t, uint8_t *, + raid_path_error_info_elem_t *); + +int pqisrc_submit_management_req(pqisrc_softstate_t *, + pqi_event_config_request_t *); +void pqisrc_take_devices_offline(pqisrc_softstate_t *); +void pqisrc_take_ctrl_offline(pqisrc_softstate_t *); +void pqisrc_free_rcb(pqisrc_softstate_t *, int); +void pqisrc_decide_opq_config(pqisrc_softstate_t *); +int pqisrc_configure_op_queues(pqisrc_softstate_t *); +int pqisrc_pqi_init(pqisrc_softstate_t *); +int pqi_reset(pqisrc_softstate_t *); +int pqisrc_check_pqimode(pqisrc_softstate_t *); +int pqisrc_check_fw_status(pqisrc_softstate_t *); +int pqisrc_init_struct_base(pqisrc_softstate_t *); +int pqisrc_get_sis_pqi_cap(pqisrc_softstate_t *); +int pqisrc_get_preferred_settings(pqisrc_softstate_t *); +int pqisrc_get_adapter_properties(pqisrc_softstate_t *, + uint32_t *, uint32_t *); + +void pqisrc_get_admin_queue_config(pqisrc_softstate_t *); +void pqisrc_decide_admin_queue_config(pqisrc_softstate_t *); +int pqisrc_allocate_and_init_adminq(pqisrc_softstate_t *); +int pqisrc_create_delete_adminq(pqisrc_softstate_t *, uint32_t); +void pqisrc_print_adminq_config(pqisrc_softstate_t *); +int pqisrc_delete_op_queue(pqisrc_softstate_t *, + uint32_t, boolean_t); +void pqisrc_destroy_event_queue(pqisrc_softstate_t *); + +void pqisrc_destroy_op_ib_queues(pqisrc_softstate_t *); + +void pqisrc_destroy_op_ob_queues(pqisrc_softstate_t *); + +int pqisrc_change_op_ibq_queue_prop(pqisrc_softstate_t *, + ib_queue_t *, uint32_t); +int pqisrc_create_op_obq(pqisrc_softstate_t *, + ob_queue_t *); +int pqisrc_create_op_ibq(pqisrc_softstate_t *, + ib_queue_t *); +int pqisrc_create_op_aio_ibq(pqisrc_softstate_t *, ib_queue_t *); +int pqisrc_create_op_raid_ibq(pqisrc_softstate_t *, ib_queue_t *); +int pqisrc_alloc_and_create_event_queue(pqisrc_softstate_t *); +int pqisrc_alloc_and_create_ib_queues(pqisrc_softstate_t *); +int pqisrc_alloc_and_create_ib_queues(pqisrc_softstate_t *); +int pqisrc_alloc_and_create_ob_queues(pqisrc_softstate_t *); +int pqisrc_process_task_management_response(pqisrc_softstate_t *, + pqi_tmf_resp_t *); + + +/* pqi_ioctl.c*/ + +int +pqisrc_passthru_ioctl(struct pqisrc_softstate *, void *, int); + + +/* Functions Prototypes */ +/* FreeBSD_mem.c */ +int os_dma_mem_alloc(pqisrc_softstate_t *,struct dma_mem *); +void os_dma_mem_free(pqisrc_softstate_t *,struct dma_mem *); +void *os_mem_alloc(pqisrc_softstate_t *,size_t); +void os_mem_free(pqisrc_softstate_t *,char *,size_t); +void os_resource_free(pqisrc_softstate_t *); +int os_dma_setup(pqisrc_softstate_t *); +int os_dma_destroy(pqisrc_softstate_t *); + +/* FreeBSD intr.c */ +int os_get_intr_config(pqisrc_softstate_t *); +int os_setup_intr(pqisrc_softstate_t *); +int os_destroy_intr(pqisrc_softstate_t *); +int os_get_processor_config(pqisrc_softstate_t *); +void os_free_intr_config(pqisrc_softstate_t *); + +/* FreeBSD_ioctl.c */ +int os_copy_to_user(struct pqisrc_softstate *, void *, + void *, int, int); +int os_copy_from_user(struct pqisrc_softstate *, void *, + void *, int, int); +int create_char_dev(struct pqisrc_softstate *, int); +void destroy_char_dev(struct pqisrc_softstate *); + +/* FreeBSD_misc.c*/ +int os_init_spinlock(struct pqisrc_softstate *, struct mtx *, char *); +void os_uninit_spinlock(struct mtx *); +int os_create_semaphore(const char *, int,struct sema *); +int os_destroy_semaphore(struct sema *); +void os_sema_lock(struct sema *); +void os_sema_unlock(struct sema *); + +int os_strlcpy(char *dst, char *src, int len); +void os_complete_outstanding_cmds_nodevice(pqisrc_softstate_t *); +void os_stop_heartbeat_timer(pqisrc_softstate_t *); +void os_start_heartbeat_timer(void *); + +/* FreeBSD_cam.c */ +int pqisrc_scsi_setup(struct pqisrc_softstate *); +void pqisrc_scsi_cleanup(struct pqisrc_softstate *); +uint8_t os_get_task_attr(rcb_t *); +void os_wellness_periodic(void *); +void smartpqi_target_rescan(struct pqisrc_softstate *); + +/* FreeBSD_intr.c FreeBSD_main.c */ +void pqisrc_event_worker(void *, int); +void os_add_device(pqisrc_softstate_t *, pqi_scsi_dev_t *); +void os_remove_device(pqisrc_softstate_t *, pqi_scsi_dev_t *); +void os_io_response_success(rcb_t *); +void os_aio_response_error(rcb_t *, aio_path_error_info_elem_t *); +void smartpqi_adjust_queue_depth(struct cam_path *, uint32_t ); +void os_raid_response_error(rcb_t *, raid_path_error_info_elem_t *); +void os_wellness_periodic(void *); +void os_reset_rcb( rcb_t *); +int register_sim(struct pqisrc_softstate *, int); +void deregister_sim(struct pqisrc_softstate *); +int check_for_scsi_opcode(uint8_t *, boolean_t *, uint64_t *, + uint32_t *); +int register_legacy_intr(pqisrc_softstate_t *); +int register_msix_intr(pqisrc_softstate_t *); +void deregister_pqi_intx(pqisrc_softstate_t *); +void deregister_pqi_msix(pqisrc_softstate_t *); +void os_get_time(struct bmic_host_wellness_time *); +void os_eventtaskqueue_enqueue(pqisrc_softstate_t *); +void pqisrc_save_controller_info(struct pqisrc_softstate *); +int smartpqi_shutdown(void *); + +#endif // _SMARTPQI_PROTOTYPES_H Property changes on: head/sys/dev/smartpqi/smartpqi_prototypes.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_queue.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_queue.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_queue.c (revision 333019) @@ -0,0 +1,995 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* + * Submit an admin IU to the adapter. + * Add interrupt support, if required + */ +int pqisrc_submit_admin_req(pqisrc_softstate_t *softs, + gen_adm_req_iu_t *req, gen_adm_resp_iu_t *resp) +{ + int ret = PQI_STATUS_SUCCESS; + ob_queue_t *ob_q = &softs->admin_ob_queue; + ib_queue_t *ib_q = &softs->admin_ib_queue; + int tmo = PQISRC_ADMIN_CMD_RESP_TIMEOUT; + + DBG_FUNC("IN\n"); + + req->header.iu_type = + PQI_IU_TYPE_GENERAL_ADMIN_REQUEST; + req->header.comp_feature = 0x00; + req->header.iu_length = PQI_STANDARD_IU_LENGTH; + req->res1 = 0; + req->work = 0; + + /* Get the tag */ + req->req_id = pqisrc_get_tag(&softs->taglist); + if (INVALID_ELEM == req->req_id) { + DBG_ERR("Tag not available0x%x\n",(uint16_t)req->req_id); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + softs->rcb[req->req_id].tag = req->req_id; + + /* Submit the command to the admin ib queue */ + ret = pqisrc_submit_cmnd(softs, ib_q, req); + if (ret != PQI_STATUS_SUCCESS) { + DBG_ERR("Unable to submit command\n"); + goto err_cmd; + } + + /* Wait for completion */ + COND_WAIT((*(ob_q->pi_virt_addr) != ob_q->ci_local), tmo); + if (tmo <= 0) { + DBG_ERR("Admin cmd timeout\n"); + DBG_ERR("tmo : %d\n",tmo); \ + ret = PQI_STATUS_TIMEOUT; + goto err_cmd; + } + + /* Copy the response */ + memcpy(resp, ob_q->array_virt_addr + (ob_q->ci_local * ob_q->elem_size), + sizeof(gen_adm_resp_iu_t)); + + /* Update CI */ + ob_q->ci_local = (ob_q->ci_local + 1 ) % ob_q->num_elem; + PCI_MEM_PUT32(softs, ob_q->ci_register_abs, + ob_q->ci_register_offset, LE_32(ob_q->ci_local)); + + /* Validate the response data */ + ASSERT(req->fn_code == resp->fn_code); + ASSERT(resp->header.iu_type == PQI_IU_TYPE_GENERAL_ADMIN_RESPONSE); + ret = resp->status; + if (ret) + goto err_cmd; + + os_reset_rcb(&softs->rcb[req->req_id]); + pqisrc_put_tag(&softs->taglist,req->req_id); + DBG_FUNC("OUT\n"); + return ret; +err_cmd: + os_reset_rcb(&softs->rcb[req->req_id]); + pqisrc_put_tag(&softs->taglist,req->req_id); +err_out: + DBG_FUNC("failed OUT : %d\n", ret); + return ret; +} + +/* + * Get the administration queue config parameters. + */ +void pqisrc_get_admin_queue_config(pqisrc_softstate_t *softs) +{ + uint64_t val = 0; + + + val = LE_64(PCI_MEM_GET64(softs, &softs->pqi_reg->pqi_dev_adminq_cap, PQI_ADMINQ_CAP)); + + /* pqi_cap = (struct pqi_dev_adminq_cap *)&val;*/ + softs->admin_ib_queue.num_elem = val & 0xFF; + softs->admin_ob_queue.num_elem = (val & 0xFF00) >> 8; + /* Note : size in unit of 16 byte s*/ + softs->admin_ib_queue.elem_size = ((val & 0xFF0000) >> 16) * 16; + softs->admin_ob_queue.elem_size = ((val & 0xFF000000) >> 24) * 16; + + DBG_FUNC(" softs->admin_ib_queue.num_elem : %d\n", + softs->admin_ib_queue.num_elem); + DBG_FUNC(" softs->admin_ib_queue.elem_size : %d\n", + softs->admin_ib_queue.elem_size); +} + +/* + * Decide the no of elements in admin ib and ob queues. + */ +void pqisrc_decide_admin_queue_config(pqisrc_softstate_t *softs) +{ + /* Determine num elements in Admin IBQ */ + softs->admin_ib_queue.num_elem = MIN(softs->admin_ib_queue.num_elem, + PQISRC_MAX_ADMIN_IB_QUEUE_ELEM_NUM); + + /* Determine num elements in Admin OBQ */ + softs->admin_ob_queue.num_elem = MIN(softs->admin_ob_queue.num_elem, + PQISRC_MAX_ADMIN_OB_QUEUE_ELEM_NUM); +} + +/* + * Allocate DMA memory for admin queue and initialize. + */ +int pqisrc_allocate_and_init_adminq(pqisrc_softstate_t *softs) +{ + uint32_t ib_array_size = 0; + uint32_t ob_array_size = 0; + uint32_t alloc_size = 0; + char *virt_addr = NULL; + dma_addr_t dma_addr = 0; + int ret = PQI_STATUS_SUCCESS; + + ib_array_size = (softs->admin_ib_queue.num_elem * + softs->admin_ib_queue.elem_size); + + ob_array_size = (softs->admin_ob_queue.num_elem * + softs->admin_ob_queue.elem_size); + + alloc_size = ib_array_size + ob_array_size + + 2 * sizeof(uint32_t) + PQI_ADDR_ALIGN_MASK_64 + 1; /* for IB CI and OB PI */ + /* Allocate memory for Admin Q */ + softs->admin_queue_dma_mem.tag = "admin_queue"; + softs->admin_queue_dma_mem.size = alloc_size; + softs->admin_queue_dma_mem.align = PQI_ADMINQ_ELEM_ARRAY_ALIGN; + ret = os_dma_mem_alloc(softs, &softs->admin_queue_dma_mem); + if (ret) { + DBG_ERR("Failed to Allocate Admin Q ret : %d\n", ret); + goto err_out; + } + + /* Setup the address */ + virt_addr = softs->admin_queue_dma_mem.virt_addr; + dma_addr = softs->admin_queue_dma_mem.dma_addr; + + /* IB */ + softs->admin_ib_queue.q_id = 0; + softs->admin_ib_queue.array_virt_addr = virt_addr; + softs->admin_ib_queue.array_dma_addr = dma_addr; + softs->admin_ib_queue.pi_local = 0; + /* OB */ + softs->admin_ob_queue.q_id = 0; + softs->admin_ob_queue.array_virt_addr = virt_addr + ib_array_size; + softs->admin_ob_queue.array_dma_addr = dma_addr + ib_array_size; + softs->admin_ob_queue.ci_local = 0; + + /* IB CI */ + softs->admin_ib_queue.ci_virt_addr = + (uint32_t*)((uint8_t*)softs->admin_ob_queue.array_virt_addr + + ob_array_size); + softs->admin_ib_queue.ci_dma_addr = + (dma_addr_t)((uint8_t*)softs->admin_ob_queue.array_dma_addr + + ob_array_size); + + /* OB PI */ + softs->admin_ob_queue.pi_virt_addr = + (uint32_t*)((uint8_t*)(softs->admin_ib_queue.ci_virt_addr) + + PQI_ADDR_ALIGN_MASK_64 + 1); + softs->admin_ob_queue.pi_dma_addr = + (dma_addr_t)((uint8_t*)(softs->admin_ib_queue.ci_dma_addr) + + PQI_ADDR_ALIGN_MASK_64 + 1); + + DBG_INFO("softs->admin_ib_queue.ci_dma_addr : %p,softs->admin_ob_queue.pi_dma_addr :%p\n", + (void*)softs->admin_ib_queue.ci_dma_addr, (void*)softs->admin_ob_queue.pi_dma_addr ); + + /* Verify alignment */ + ASSERT(!(softs->admin_ib_queue.array_dma_addr & + PQI_ADDR_ALIGN_MASK_64)); + ASSERT(!(softs->admin_ib_queue.ci_dma_addr & + PQI_ADDR_ALIGN_MASK_64)); + ASSERT(!(softs->admin_ob_queue.array_dma_addr & + PQI_ADDR_ALIGN_MASK_64)); + ASSERT(!(softs->admin_ob_queue.pi_dma_addr & + PQI_ADDR_ALIGN_MASK_64)); + + DBG_FUNC("OUT\n"); + return ret; + +err_out: + DBG_FUNC("failed OUT\n"); + return PQI_STATUS_FAILURE; +} + +/* + * Subroutine used to create (or) delete the admin queue requested. + */ +int pqisrc_create_delete_adminq(pqisrc_softstate_t *softs, + uint32_t cmd) +{ + int tmo = 0; + int ret = PQI_STATUS_SUCCESS; + + /* Create Admin Q pair writing to Admin Q config function reg */ + + PCI_MEM_PUT64(softs, &softs->pqi_reg->admin_q_config, PQI_ADMINQ_CONFIG, LE_64(cmd)); + + if (cmd == PQI_ADMIN_QUEUE_CONF_FUNC_CREATE_Q_PAIR) + tmo = PQISRC_ADMIN_QUEUE_CREATE_TIMEOUT; + else + tmo = PQISRC_ADMIN_QUEUE_DELETE_TIMEOUT; + + /* Wait for completion */ + COND_WAIT((PCI_MEM_GET64(softs, &softs->pqi_reg->admin_q_config, PQI_ADMINQ_CONFIG) == + PQI_ADMIN_QUEUE_CONF_FUNC_STATUS_IDLE), tmo); + if (tmo <= 0) { + DBG_ERR("Unable to create/delete admin queue pair\n"); + ret = PQI_STATUS_TIMEOUT; + } + + return ret; +} + +/* + * Debug admin queue configuration params. + */ +void pqisrc_print_adminq_config(pqisrc_softstate_t *softs) +{ + DBG_INFO(" softs->admin_ib_queue.array_dma_addr : %p\n", + (void*)softs->admin_ib_queue.array_dma_addr); + DBG_INFO(" softs->admin_ib_queue.array_virt_addr : %p\n", + (void*)softs->admin_ib_queue.array_virt_addr); + DBG_INFO(" softs->admin_ib_queue.num_elem : %d\n", + softs->admin_ib_queue.num_elem); + DBG_INFO(" softs->admin_ib_queue.elem_size : %d\n", + softs->admin_ib_queue.elem_size); + DBG_INFO(" softs->admin_ob_queue.array_dma_addr : %p\n", + (void*)softs->admin_ob_queue.array_dma_addr); + DBG_INFO(" softs->admin_ob_queue.array_virt_addr : %p\n", + (void*)softs->admin_ob_queue.array_virt_addr); + DBG_INFO(" softs->admin_ob_queue.num_elem : %d\n", + softs->admin_ob_queue.num_elem); + DBG_INFO(" softs->admin_ob_queue.elem_size : %d\n", + softs->admin_ob_queue.elem_size); + DBG_INFO(" softs->admin_ib_queue.pi_register_abs : %p\n", + (void*)softs->admin_ib_queue.pi_register_abs); + DBG_INFO(" softs->admin_ob_queue.ci_register_abs : %p\n", + (void*)softs->admin_ob_queue.ci_register_abs); +} + +/* + * Function used to create an admin queue. + */ +int pqisrc_create_admin_queue(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS;; + uint32_t admin_q_param = 0; + + DBG_FUNC("IN\n"); + + /* Get admin queue details - pqi2-r00a - table 24 */ + pqisrc_get_admin_queue_config(softs); + + /* Decide admin Q config */ + pqisrc_decide_admin_queue_config(softs); + + /* Allocate and init Admin Q pair */ + ret = pqisrc_allocate_and_init_adminq(softs); + if (ret) { + DBG_ERR("Failed to Allocate Admin Q ret : %d\n", ret); + goto err_out; + } + + /* Write IB Q element array address */ + PCI_MEM_PUT64(softs, &softs->pqi_reg->admin_ibq_elem_array_addr, + PQI_ADMIN_IBQ_ELEM_ARRAY_ADDR, LE_64(softs->admin_ib_queue.array_dma_addr)); + + /* Write OB Q element array address */ + PCI_MEM_PUT64(softs, &softs->pqi_reg->admin_obq_elem_array_addr, + PQI_ADMIN_OBQ_ELEM_ARRAY_ADDR, LE_64(softs->admin_ob_queue.array_dma_addr)); + + /* Write IB Q CI address */ + PCI_MEM_PUT64(softs, &softs->pqi_reg->admin_ibq_ci_addr, + PQI_ADMIN_IBQ_CI_ADDR, LE_64(softs->admin_ib_queue.ci_dma_addr)); + + /* Write OB Q PI address */ + PCI_MEM_PUT64(softs, &softs->pqi_reg->admin_obq_pi_addr, + PQI_ADMIN_OBQ_PI_ADDR, LE_64(softs->admin_ob_queue.pi_dma_addr)); + + + /* Write Admin Q params pqi-r200a table 36 */ + + admin_q_param = softs->admin_ib_queue.num_elem | + (softs->admin_ob_queue.num_elem << 8)| + PQI_ADMIN_QUEUE_MSIX_DISABLE; + + PCI_MEM_PUT32(softs, &softs->pqi_reg->admin_q_param, + PQI_ADMINQ_PARAM, LE_32(admin_q_param)); + + /* Submit cmd to create Admin Q pair */ + ret = pqisrc_create_delete_adminq(softs, + PQI_ADMIN_QUEUE_CONF_FUNC_CREATE_Q_PAIR); + if (ret) { + DBG_ERR("Failed to Allocate Admin Q ret : %d\n", ret); + goto err_q_create; + } + + /* Admin queue created, get ci,pi offset */ + softs->admin_ib_queue.pi_register_offset =(PQISRC_PQI_REG_OFFSET + + PCI_MEM_GET64(softs, &softs->pqi_reg->admin_ibq_pi_offset, PQI_ADMIN_IBQ_PI_OFFSET)); + + softs->admin_ib_queue.pi_register_abs =(uint32_t *)(softs->pci_mem_base_vaddr + + softs->admin_ib_queue.pi_register_offset); + + softs->admin_ob_queue.ci_register_offset = (PQISRC_PQI_REG_OFFSET + + PCI_MEM_GET64(softs, &softs->pqi_reg->admin_obq_ci_offset, PQI_ADMIN_OBQ_CI_OFFSET)); + + softs->admin_ob_queue.ci_register_abs = (uint32_t *)(softs->pci_mem_base_vaddr + + softs->admin_ob_queue.ci_register_offset); + + os_strlcpy(softs->admin_ib_queue.lockname, "admin_ibqlock", LOCKNAME_SIZE); + + ret =OS_INIT_PQILOCK(softs, &softs->admin_ib_queue.lock, + softs->admin_ib_queue.lockname); + if(ret){ + DBG_ERR("Admin spinlock initialization failed\n"); + softs->admin_ib_queue.lockcreated = false; + goto err_out; + } + softs->admin_ib_queue.lockcreated = true; + + /* Print admin q config details */ + pqisrc_print_adminq_config(softs); + + DBG_FUNC("OUT\n"); + return ret; + +err_q_create: + os_dma_mem_free(softs, &softs->admin_queue_dma_mem); +err_out: + DBG_FUNC("failed OUT\n"); + return ret; +} + +/* + * Subroutine used to delete an operational queue. + */ +int pqisrc_delete_op_queue(pqisrc_softstate_t *softs, + uint32_t q_id, boolean_t ibq) +{ + int ret = PQI_STATUS_SUCCESS; + /* Firmware doesn't support this now */ + +#if 0 + gen_adm_req_iu_t admin_req; + gen_adm_resp_iu_t admin_resp; + + + memset(&admin_req, 0, sizeof(admin_req)); + memset(&admin_resp, 0, sizeof(admin_resp)); + + DBG_FUNC("IN\n"); + + admin_req.req_type.create_op_iq.qid = q_id; + + if (ibq) + admin_req.fn_code = PQI_FUNCTION_DELETE_OPERATIONAL_IQ; + else + admin_req.fn_code = PQI_FUNCTION_DELETE_OPERATIONAL_OQ; + + + ret = pqisrc_submit_admin_req(softs, &admin_req, &admin_resp); + + DBG_FUNC("OUT\n"); +#endif + return ret; +} + +/* + * Function used to destroy the event queue. + */ +void pqisrc_destroy_event_queue(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + + if (softs->event_q.created == true) { + int ret = PQI_STATUS_SUCCESS; + ret = pqisrc_delete_op_queue(softs, softs->event_q.q_id, false); + if (ret) { + DBG_ERR("Failed to Delete Event Q %d\n", softs->event_q.q_id); + } + softs->event_q.created = false; + } + + /* Free the memory */ + os_dma_mem_free(softs, &softs->event_q_dma_mem); + + DBG_FUNC("OUT\n"); +} + +/* + * Function used to destroy operational ib queues. + */ +void pqisrc_destroy_op_ib_queues(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + ib_queue_t *op_ib_q = NULL; + int i; + + DBG_FUNC("IN\n"); + + for (i = 0; i < softs->num_op_raid_ibq; i++) { + /* OP RAID IB Q */ + op_ib_q = &softs->op_raid_ib_q[i]; + if (op_ib_q->created == true) { + ret = pqisrc_delete_op_queue(softs, op_ib_q->q_id, true); + if (ret) { + DBG_ERR("Failed to Delete Raid IB Q %d\n",op_ib_q->q_id); + } + op_ib_q->created = false; + } + + if(op_ib_q->lockcreated==true){ + OS_UNINIT_PQILOCK(&op_ib_q->lock); + op_ib_q->lockcreated = false; + } + + /* OP AIO IB Q */ + op_ib_q = &softs->op_aio_ib_q[i]; + if (op_ib_q->created == true) { + ret = pqisrc_delete_op_queue(softs, op_ib_q->q_id, true); + if (ret) { + DBG_ERR("Failed to Delete AIO IB Q %d\n",op_ib_q->q_id); + } + op_ib_q->created = false; + } + + if(op_ib_q->lockcreated==true){ + OS_UNINIT_PQILOCK(&op_ib_q->lock); + op_ib_q->lockcreated = false; + } + } + + /* Free the memory */ + os_dma_mem_free(softs, &softs->op_ibq_dma_mem); + DBG_FUNC("OUT\n"); +} + +/* + * Function used to destroy operational ob queues. + */ +void pqisrc_destroy_op_ob_queues(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + int i; + + DBG_FUNC("IN\n"); + + for (i = 0; i < softs->num_op_obq; i++) { + ob_queue_t *op_ob_q = NULL; + op_ob_q = &softs->op_ob_q[i]; + if (op_ob_q->created == true) { + ret = pqisrc_delete_op_queue(softs, op_ob_q->q_id, false); + if (ret) { + DBG_ERR("Failed to Delete OB Q %d\n",op_ob_q->q_id); + } + op_ob_q->created = false; + } + } + + /* Free the memory */ + os_dma_mem_free(softs, &softs->op_obq_dma_mem); + DBG_FUNC("OUT\n"); +} + +/* + * Function used to destroy an admin queue. + */ +int pqisrc_destroy_admin_queue(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); +#if 0 + ret = pqisrc_create_delete_adminq(softs, + PQI_ADMIN_QUEUE_CONF_FUNC_DEL_Q_PAIR); +#endif + os_dma_mem_free(softs, &softs->admin_queue_dma_mem); + + DBG_FUNC("OUT\n"); + return ret; +} + +/* + * Function used to change operational ib queue properties. + */ +int pqisrc_change_op_ibq_queue_prop(pqisrc_softstate_t *softs, + ib_queue_t *op_ib_q, uint32_t prop) +{ + int ret = PQI_STATUS_SUCCESS;; + gen_adm_req_iu_t admin_req; + gen_adm_resp_iu_t admin_resp; + + memset(&admin_req, 0, sizeof(admin_req)); + memset(&admin_resp, 0, sizeof(admin_resp)); + + DBG_FUNC("IN\n"); + + admin_req.fn_code = PQI_FUNCTION_CHANGE_OPERATIONAL_IQ_PROP; + admin_req.req_type.change_op_iq_prop.qid = op_ib_q->q_id; + admin_req.req_type.change_op_iq_prop.vend_specific = prop; + + ret = pqisrc_submit_admin_req(softs, &admin_req, &admin_resp); + + DBG_FUNC("OUT\n"); + return ret; +} + +/* + * Function used to create an operational ob queue. + */ +int pqisrc_create_op_obq(pqisrc_softstate_t *softs, + ob_queue_t *op_ob_q) +{ + int ret = PQI_STATUS_SUCCESS;; + gen_adm_req_iu_t admin_req; + gen_adm_resp_iu_t admin_resp; + + DBG_FUNC("IN\n"); + + memset(&admin_req, 0, sizeof(admin_req)); + memset(&admin_resp, 0, sizeof(admin_resp)); + + admin_req.fn_code = PQI_FUNCTION_CREATE_OPERATIONAL_OQ; + admin_req.req_type.create_op_oq.qid = op_ob_q->q_id; + admin_req.req_type.create_op_oq.intr_msg_num = op_ob_q->intr_msg_num; + admin_req.req_type.create_op_oq.elem_arr_addr = op_ob_q->array_dma_addr; + admin_req.req_type.create_op_oq.ob_pi_addr = op_ob_q->pi_dma_addr; + admin_req.req_type.create_op_oq.num_elem = op_ob_q->num_elem; + admin_req.req_type.create_op_oq.elem_len = op_ob_q->elem_size / 16; + + DBG_INFO("admin_req.req_type.create_op_oq.qid : %x\n",admin_req.req_type.create_op_oq.qid); + DBG_INFO("admin_req.req_type.create_op_oq.intr_msg_num : %x\n", admin_req.req_type.create_op_oq.intr_msg_num ); + + ret = pqisrc_submit_admin_req(softs, &admin_req, &admin_resp); + if( PQI_STATUS_SUCCESS == ret) { + op_ob_q->ci_register_offset = (PQISRC_PQI_REG_OFFSET + + admin_resp.resp_type.create_op_oq.ci_offset); + op_ob_q->ci_register_abs = (uint32_t *)(softs->pci_mem_base_vaddr + + op_ob_q->ci_register_offset); + } else { + int i = 0; + DBG_WARN("Error Status Descriptors\n"); + for(i = 0; i < 4;i++) + DBG_WARN(" %x ",admin_resp.resp_type.create_op_oq.status_desc[i]); + } + + DBG_FUNC("OUT ret : %d\n", ret); + + return ret; +} + +/* + * Function used to create an operational ib queue. + */ +int pqisrc_create_op_ibq(pqisrc_softstate_t *softs, + ib_queue_t *op_ib_q) +{ + int ret = PQI_STATUS_SUCCESS;; + gen_adm_req_iu_t admin_req; + gen_adm_resp_iu_t admin_resp; + + DBG_FUNC("IN\n"); + + memset(&admin_req, 0, sizeof(admin_req)); + memset(&admin_resp, 0, sizeof(admin_resp)); + + admin_req.fn_code = PQI_FUNCTION_CREATE_OPERATIONAL_IQ; + admin_req.req_type.create_op_iq.qid = op_ib_q->q_id; + admin_req.req_type.create_op_iq.elem_arr_addr = op_ib_q->array_dma_addr; + admin_req.req_type.create_op_iq.iq_ci_addr = op_ib_q->ci_dma_addr; + admin_req.req_type.create_op_iq.num_elem = op_ib_q->num_elem; + admin_req.req_type.create_op_iq.elem_len = op_ib_q->elem_size / 16; + + ret = pqisrc_submit_admin_req(softs, &admin_req, &admin_resp); + + if( PQI_STATUS_SUCCESS == ret) { + op_ib_q->pi_register_offset =(PQISRC_PQI_REG_OFFSET + + admin_resp.resp_type.create_op_iq.pi_offset); + + op_ib_q->pi_register_abs =(uint32_t *)(softs->pci_mem_base_vaddr + + op_ib_q->pi_register_offset); + } else { + int i = 0; + DBG_WARN("Error Status Decsriptors\n"); + for(i = 0; i < 4;i++) + DBG_WARN(" %x ",admin_resp.resp_type.create_op_iq.status_desc[i]); + } + + DBG_FUNC("OUT ret : %d\n", ret); + return ret; +} + +/* + * subroutine used to create an operational ib queue for AIO. + */ +int pqisrc_create_op_aio_ibq(pqisrc_softstate_t *softs, + ib_queue_t *op_aio_ib_q) +{ + int ret = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); + + ret = pqisrc_create_op_ibq(softs,op_aio_ib_q); + if ( PQI_STATUS_SUCCESS == ret) + ret = pqisrc_change_op_ibq_queue_prop(softs, + op_aio_ib_q, PQI_CHANGE_OP_IQ_PROP_ASSIGN_AIO); + + DBG_FUNC("OUT ret : %d\n", ret); + return ret; +} + +/* + * subroutine used to create an operational ib queue for RAID. + */ +int pqisrc_create_op_raid_ibq(pqisrc_softstate_t *softs, + ib_queue_t *op_raid_ib_q) +{ + int ret = PQI_STATUS_SUCCESS;; + + DBG_FUNC("IN\n"); + + ret = pqisrc_create_op_ibq(softs,op_raid_ib_q); + + DBG_FUNC("OUT\n"); + return ret; +} + +/* + * Allocate and create an event queue to process supported events. + */ +int pqisrc_alloc_and_create_event_queue(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t alloc_size = 0; + uint32_t num_elem; + char *virt_addr = NULL; + dma_addr_t dma_addr = 0; + uint32_t event_q_pi_dma_start_offset = 0; + uint32_t event_q_pi_virt_start_offset = 0; + char *event_q_pi_virt_start_addr = NULL; + ob_queue_t *event_q = NULL; + + + DBG_FUNC("IN\n"); + + /* + * Calculate memory requirements. + * If event queue is shared for IO response, number of + * elements in event queue depends on num elements in OP OB Q + * also. Since event queue element size (32) is more than IO + * response size , event queue element size need not be checked + * for queue size calculation. + */ +#ifdef SHARE_EVENT_QUEUE_FOR_IO + num_elem = MIN(softs->num_elem_per_op_obq, PQISRC_NUM_EVENT_Q_ELEM); +#else + num_elem = PQISRC_NUM_EVENT_Q_ELEM; +#endif + + alloc_size = num_elem * PQISRC_EVENT_Q_ELEM_SIZE; + event_q_pi_dma_start_offset = alloc_size; + event_q_pi_virt_start_offset = alloc_size; + alloc_size += sizeof(uint32_t); /*For IBQ CI*/ + + /* Allocate memory for event queues */ + softs->event_q_dma_mem.tag = "event_queue"; + softs->event_q_dma_mem.size = alloc_size; + softs->event_q_dma_mem.align = PQI_OPQ_ELEM_ARRAY_ALIGN; + ret = os_dma_mem_alloc(softs, &softs->event_q_dma_mem); + if (ret) { + DBG_ERR("Failed to Allocate Event Q ret : %d\n" + , ret); + goto err_out; + } + + /* Set up the address */ + virt_addr = softs->event_q_dma_mem.virt_addr; + dma_addr = softs->event_q_dma_mem.dma_addr; + event_q_pi_dma_start_offset += dma_addr; + event_q_pi_virt_start_addr = virt_addr + event_q_pi_virt_start_offset; + + event_q = &softs->event_q; + ASSERT(!(dma_addr & PQI_ADDR_ALIGN_MASK_64)); + FILL_QUEUE_ARRAY_ADDR(event_q,virt_addr,dma_addr); + event_q->q_id = PQI_OP_EVENT_QUEUE_ID; + event_q->num_elem = num_elem; + event_q->elem_size = PQISRC_EVENT_Q_ELEM_SIZE; + event_q->pi_dma_addr = event_q_pi_dma_start_offset; + event_q->pi_virt_addr = (uint32_t *)event_q_pi_virt_start_addr; + event_q->intr_msg_num = 0; /* vector zero for event */ + ASSERT(!(event_q->pi_dma_addr & PQI_ADDR_ALIGN_MASK_4)); + + ret = pqisrc_create_op_obq(softs,event_q); + if (ret) { + DBG_ERR("Failed to Create EventQ %d\n",event_q->q_id); + goto err_out_create; + } + event_q->created = true; + + DBG_FUNC("OUT\n"); + return ret; + +err_out_create: + pqisrc_destroy_event_queue(softs); +err_out: + DBG_FUNC("OUT failed %d\n", ret); + return PQI_STATUS_FAILURE; +} + +/* + * Allocate DMA memory and create operational ib queues. + */ +int pqisrc_alloc_and_create_ib_queues(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t alloc_size = 0; + char *virt_addr = NULL; + dma_addr_t dma_addr = 0; + uint32_t ibq_size = 0; + uint32_t ib_ci_dma_start_offset = 0; + char *ib_ci_virt_start_addr = NULL; + uint32_t ib_ci_virt_start_offset = 0; + uint32_t ibq_id = PQI_MIN_OP_IB_QUEUE_ID; + ib_queue_t *op_ib_q = NULL; + uint32_t num_op_ibq = softs->num_op_raid_ibq + + softs->num_op_aio_ibq; + int i = 0; + + DBG_FUNC("IN\n"); + + /* Calculate memory requirements */ + ibq_size = softs->num_elem_per_op_ibq * softs->ibq_elem_size; + alloc_size = num_op_ibq * ibq_size; + /* CI indexes starts after Queue element array */ + ib_ci_dma_start_offset = alloc_size; + ib_ci_virt_start_offset = alloc_size; + alloc_size += num_op_ibq * sizeof(uint32_t); /*For IBQ CI*/ + + /* Allocate memory for IB queues */ + softs->op_ibq_dma_mem.tag = "op_ib_queue"; + softs->op_ibq_dma_mem.size = alloc_size; + softs->op_ibq_dma_mem.align = PQI_OPQ_ELEM_ARRAY_ALIGN; + ret = os_dma_mem_alloc(softs, &softs->op_ibq_dma_mem); + if (ret) { + DBG_ERR("Failed to Allocate Operational IBQ memory ret : %d\n", + ret); + goto err_out; + } + + /* Set up the address */ + virt_addr = softs->op_ibq_dma_mem.virt_addr; + dma_addr = softs->op_ibq_dma_mem.dma_addr; + ib_ci_dma_start_offset += dma_addr; + ib_ci_virt_start_addr = virt_addr + ib_ci_virt_start_offset; + + ASSERT(softs->num_op_raid_ibq == softs->num_op_aio_ibq); + + for (i = 0; i < softs->num_op_raid_ibq; i++) { + /* OP RAID IB Q */ + op_ib_q = &softs->op_raid_ib_q[i]; + ASSERT(!(dma_addr & PQI_ADDR_ALIGN_MASK_64)); + FILL_QUEUE_ARRAY_ADDR(op_ib_q,virt_addr,dma_addr); + op_ib_q->q_id = ibq_id++; + + snprintf(op_ib_q->lockname, LOCKNAME_SIZE, "raid_ibqlock%d", i); + ret = OS_INIT_PQILOCK(softs, &op_ib_q->lock, op_ib_q->lockname); + if(ret){ + DBG_ERR("raid_ibqlock %d init failed\n", i); + op_ib_q->lockcreated = false; + goto err_lock; + } + op_ib_q->lockcreated = true; + op_ib_q->num_elem = softs->num_elem_per_op_ibq; + op_ib_q->elem_size = softs->ibq_elem_size; + op_ib_q->ci_dma_addr = ib_ci_dma_start_offset + + (2 * i * sizeof(uint32_t)); + op_ib_q->ci_virt_addr = (uint32_t*)(ib_ci_virt_start_addr + + (2 * i * sizeof(uint32_t))); + ASSERT(!(op_ib_q->ci_dma_addr & PQI_ADDR_ALIGN_MASK_4)); + ret = pqisrc_create_op_raid_ibq(softs, op_ib_q); + if (ret) { + DBG_ERR("[ %s ] Failed to Create OP Raid IBQ %d\n", + __func__, op_ib_q->q_id); + goto err_out_create; + } + op_ib_q->created = true; + + /* OP AIO IB Q */ + virt_addr += ibq_size; + dma_addr += ibq_size; + op_ib_q = &softs->op_aio_ib_q[i]; + ASSERT(!(dma_addr & PQI_ADDR_ALIGN_MASK_64)); + FILL_QUEUE_ARRAY_ADDR(op_ib_q,virt_addr,dma_addr); + op_ib_q->q_id = ibq_id++; + snprintf(op_ib_q->lockname, LOCKNAME_SIZE, "aio_ibqlock%d", i); + ret = OS_INIT_PQILOCK(softs, &op_ib_q->lock, op_ib_q->lockname); + if(ret){ + DBG_ERR("aio_ibqlock %d init failed\n", i); + op_ib_q->lockcreated = false; + goto err_lock; + } + op_ib_q->lockcreated = true; + op_ib_q->num_elem = softs->num_elem_per_op_ibq; + op_ib_q->elem_size = softs->ibq_elem_size; + op_ib_q->ci_dma_addr = ib_ci_dma_start_offset + + (((2 * i) + 1) * sizeof(uint32_t)); + op_ib_q->ci_virt_addr = (uint32_t*)(ib_ci_virt_start_addr + + (((2 * i) + 1) * sizeof(uint32_t))); + ASSERT(!(op_ib_q->ci_dma_addr & PQI_ADDR_ALIGN_MASK_4)); + ret = pqisrc_create_op_aio_ibq(softs, op_ib_q); + if (ret) { + DBG_ERR("Failed to Create OP AIO IBQ %d\n",op_ib_q->q_id); + goto err_out_create; + } + op_ib_q->created = true; + + virt_addr += ibq_size; + dma_addr += ibq_size; + } + + DBG_FUNC("OUT\n"); + return ret; + +err_lock: +err_out_create: + pqisrc_destroy_op_ib_queues(softs); +err_out: + DBG_FUNC("OUT failed %d\n", ret); + return PQI_STATUS_FAILURE; +} + +/* + * Allocate DMA memory and create operational ob queues. + */ +int pqisrc_alloc_and_create_ob_queues(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t alloc_size = 0; + char *virt_addr = NULL; + dma_addr_t dma_addr = 0; + uint32_t obq_size = 0; + uint32_t ob_pi_dma_start_offset = 0; + uint32_t ob_pi_virt_start_offset = 0; + char *ob_pi_virt_start_addr = NULL; + uint32_t obq_id = PQI_MIN_OP_OB_QUEUE_ID; + ob_queue_t *op_ob_q = NULL; + uint32_t num_op_obq = softs->num_op_obq; + int i = 0; + + DBG_FUNC("IN\n"); + + /* + * OB Q element array should be 64 byte aligned. + * So the number of elements in OB Q should be multiple + * of 4, so that OB Queue element size (16) * num elements + * will be multiple of 64. + */ + + ALIGN_BOUNDARY(softs->num_elem_per_op_obq, 4); + obq_size = softs->num_elem_per_op_obq * softs->obq_elem_size; + alloc_size += num_op_obq * obq_size; + /* PI indexes starts after Queue element array */ + ob_pi_dma_start_offset = alloc_size; + ob_pi_virt_start_offset = alloc_size; + alloc_size += num_op_obq * sizeof(uint32_t); /*For OBQ PI*/ + + /* Allocate memory for OB queues */ + softs->op_obq_dma_mem.tag = "op_ob_queue"; + softs->op_obq_dma_mem.size = alloc_size; + softs->op_obq_dma_mem.align = PQI_OPQ_ELEM_ARRAY_ALIGN; + ret = os_dma_mem_alloc(softs, &softs->op_obq_dma_mem); + if (ret) { + DBG_ERR("Failed to Allocate Operational OBQ memory ret : %d\n", + ret); + goto err_out; + } + + /* Set up the address */ + virt_addr = softs->op_obq_dma_mem.virt_addr; + dma_addr = softs->op_obq_dma_mem.dma_addr; + ob_pi_dma_start_offset += dma_addr; + ob_pi_virt_start_addr = virt_addr + ob_pi_virt_start_offset; + + DBG_INFO("softs->num_op_obq %d\n",softs->num_op_obq); + + for (i = 0; i < softs->num_op_obq; i++) { + op_ob_q = &softs->op_ob_q[i]; + ASSERT(!(dma_addr & PQI_ADDR_ALIGN_MASK_64)); + FILL_QUEUE_ARRAY_ADDR(op_ob_q,virt_addr,dma_addr); + op_ob_q->q_id = obq_id++; + if(softs->share_opq_and_eventq == true) + op_ob_q->intr_msg_num = i; + else + op_ob_q->intr_msg_num = i + 1; /* msg num zero for event */ + op_ob_q->num_elem = softs->num_elem_per_op_obq; + op_ob_q->elem_size = softs->obq_elem_size; + op_ob_q->pi_dma_addr = ob_pi_dma_start_offset + + (i * sizeof(uint32_t)); + op_ob_q->pi_virt_addr = (uint32_t*)(ob_pi_virt_start_addr + + (i * sizeof(uint32_t))); + ASSERT(!(op_ob_q->pi_dma_addr & PQI_ADDR_ALIGN_MASK_4)); + + ret = pqisrc_create_op_obq(softs,op_ob_q); + if (ret) { + DBG_ERR("Failed to Create OP OBQ %d\n",op_ob_q->q_id); + goto err_out_create; + } + op_ob_q->created = true; + virt_addr += obq_size; + dma_addr += obq_size; + } + + DBG_FUNC("OUT\n"); + return ret; + +err_out_create: + pqisrc_destroy_op_ob_queues(softs); +err_out: + DBG_FUNC("OUT failed %d\n", ret); + return PQI_STATUS_FAILURE; +} + +/* + * Function used to create operational queues for the adapter. + */ +int pqisrc_create_op_queues(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + + DBG_FUNC("IN\n"); + + /* Create Operational IB queues */ + ret = pqisrc_alloc_and_create_ib_queues(softs); + if (ret) + goto err_out; + /* Create Operational OB queues */ + ret = pqisrc_alloc_and_create_ob_queues(softs); + if (ret) + goto err_out_obq; + + /* Create Event queue */ + ret = pqisrc_alloc_and_create_event_queue(softs); + if (ret) + goto err_out_eventq; + + DBG_FUNC("OUT\n"); + return ret; +err_out_eventq: + pqisrc_destroy_op_ob_queues(softs); +err_out_obq: + pqisrc_destroy_op_ib_queues(softs); +err_out: + DBG_FUNC("OUT failed %d\n", ret); + return PQI_STATUS_FAILURE; +} Property changes on: head/sys/dev/smartpqi/smartpqi_queue.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_request.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_request.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_request.c (revision 333019) @@ -0,0 +1,791 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +#define SG_FLAG_LAST 0x40000000 +#define SG_FLAG_CHAIN 0x80000000 + +/* Subroutine to find out embedded sgl count in IU */ +static inline +uint32_t pqisrc_embedded_sgl_count(uint32_t elem_alloted) +{ + uint32_t embedded_sgl_count = MAX_EMBEDDED_SG_IN_FIRST_IU; + DBG_FUNC(" IN "); + /** + calculate embedded sgl count using num_elem_alloted for IO + **/ + if(elem_alloted - 1) + embedded_sgl_count += ((elem_alloted - 1) * MAX_EMBEDDED_SG_IN_IU); + DBG_IO("embedded_sgl_count :%d\n",embedded_sgl_count); + + DBG_FUNC(" OUT "); + + return embedded_sgl_count; + +} + +/* Subroutine to find out contiguous free elem in IU */ +static inline +uint32_t pqisrc_contiguous_free_elem(uint32_t pi, uint32_t ci, uint32_t elem_in_q) +{ + uint32_t contiguous_free_elem = 0; + + DBG_FUNC(" IN "); + + if(pi >= ci) { + contiguous_free_elem = (elem_in_q - pi); + if(ci == 0) + contiguous_free_elem -= 1; + } else { + contiguous_free_elem = (ci - pi - 1); + } + + DBG_FUNC(" OUT "); + + return contiguous_free_elem; +} + +/* Subroutine to find out num of elements need for the request */ +static uint32_t +pqisrc_num_elem_needed(pqisrc_softstate_t *softs, uint32_t SG_Count) +{ + uint32_t num_sg; + uint32_t num_elem_required = 1; + DBG_FUNC(" IN "); + DBG_IO("SGL_Count :%d",SG_Count); + /******** + If SG_Count greater than max sg per IU i.e 4 or 68 + (4 is with out spanning or 68 is with spanning) chaining is required. + OR, If SG_Count <= MAX_EMBEDDED_SG_IN_FIRST_IU then, + on these two cases one element is enough. + ********/ + if(SG_Count > softs->max_sg_per_iu || SG_Count <= MAX_EMBEDDED_SG_IN_FIRST_IU) + return num_elem_required; + /* + SGL Count Other Than First IU + */ + num_sg = SG_Count - MAX_EMBEDDED_SG_IN_FIRST_IU; + num_elem_required += PQISRC_DIV_ROUND_UP(num_sg, MAX_EMBEDDED_SG_IN_IU); + DBG_FUNC(" OUT "); + return num_elem_required; +} + +/* Subroutine to build SG list for the IU submission*/ +static +boolean_t pqisrc_build_sgl(sgt_t *sg_array, rcb_t *rcb, iu_header_t *iu_hdr, + uint32_t num_elem_alloted) +{ + uint32_t i; + uint32_t num_sg = OS_GET_IO_SG_COUNT(rcb); + sgt_t *sgt = sg_array; + sgt_t *sg_chain = NULL; + boolean_t partial = false; + + DBG_FUNC(" IN "); + + DBG_IO("SGL_Count :%d",num_sg); + if (0 == num_sg) { + goto out; + } + + if (num_sg <= pqisrc_embedded_sgl_count(num_elem_alloted)) { + for (i = 0; i < num_sg; i++, sgt++) { + sgt->addr= OS_GET_IO_SG_ADDR(rcb,i); + sgt->len= OS_GET_IO_SG_LEN(rcb,i); + sgt->flags= 0; + } + + sg_array[num_sg - 1].flags = SG_FLAG_LAST; + } else { + /** + SGL Chaining + **/ + sg_chain = rcb->sg_chain_virt; + sgt->addr = rcb->sg_chain_dma; + sgt->len = num_sg * sizeof(sgt_t); + sgt->flags = SG_FLAG_CHAIN; + + sgt = sg_chain; + for (i = 0; i < num_sg; i++, sgt++) { + sgt->addr = OS_GET_IO_SG_ADDR(rcb,i); + sgt->len = OS_GET_IO_SG_LEN(rcb,i); + sgt->flags = 0; + } + + sg_chain[num_sg - 1].flags = SG_FLAG_LAST; + num_sg = 1; + partial = true; + + } +out: + iu_hdr->iu_length = num_sg * sizeof(sgt_t); + DBG_FUNC(" OUT "); + return partial; + +} + +/*Subroutine used to Build the RAID request */ +static void +pqisrc_build_raid_io(pqisrc_softstate_t *softs, rcb_t *rcb, + pqisrc_raid_req_t *raid_req, uint32_t num_elem_alloted) +{ + DBG_FUNC(" IN "); + + raid_req->header.iu_type = PQI_IU_TYPE_RAID_PATH_IO_REQUEST; + raid_req->header.comp_feature = 0; + raid_req->response_queue_id = OS_GET_IO_RESP_QID(softs, rcb); + raid_req->work_area[0] = 0; + raid_req->work_area[1] = 0; + raid_req->request_id = rcb->tag; + raid_req->nexus_id = 0; + raid_req->buffer_length = GET_SCSI_BUFFLEN(rcb); + memcpy(raid_req->lun_number, rcb->dvp->scsi3addr, + sizeof(raid_req->lun_number)); + raid_req->protocol_spec = 0; + raid_req->data_direction = rcb->data_dir; + raid_req->reserved1 = 0; + raid_req->fence = 0; + raid_req->error_index = raid_req->request_id; + raid_req->reserved2 = 0; + raid_req->task_attribute = OS_GET_TASK_ATTR(rcb); + raid_req->command_priority = 0; + raid_req->reserved3 = 0; + raid_req->reserved4 = 0; + raid_req->reserved5 = 0; + + /* As cdb and additional_cdb_bytes are contiguous, + update them in a single statement */ + memcpy(raid_req->cdb, rcb->cdbp, rcb->cmdlen); +#if 0 + DBG_IO("CDB :"); + for(i = 0; i < rcb->cmdlen ; i++) + DBG_IO(" 0x%x \n ",raid_req->cdb[i]); +#endif + + switch (rcb->cmdlen) { + case 6: + case 10: + case 12: + case 16: + raid_req->additional_cdb_bytes_usage = + PQI_ADDITIONAL_CDB_BYTES_0; + break; + case 20: + raid_req->additional_cdb_bytes_usage = + PQI_ADDITIONAL_CDB_BYTES_4; + break; + case 24: + raid_req->additional_cdb_bytes_usage = + PQI_ADDITIONAL_CDB_BYTES_8; + break; + case 28: + raid_req->additional_cdb_bytes_usage = + PQI_ADDITIONAL_CDB_BYTES_12; + break; + case 32: + default: /* todo:review again */ + raid_req->additional_cdb_bytes_usage = + PQI_ADDITIONAL_CDB_BYTES_16; + break; + } + + /* Frame SGL Descriptor */ + raid_req->partial = pqisrc_build_sgl(&raid_req->sg_descriptors[0], rcb, + &raid_req->header, num_elem_alloted); + + raid_req->header.iu_length += + offsetof(pqisrc_raid_req_t, sg_descriptors) - sizeof(iu_header_t); + +#if 0 + DBG_IO("raid_req->header.iu_type : 0x%x", raid_req->header.iu_type); + DBG_IO("raid_req->response_queue_id :%d\n"raid_req->response_queue_id); + DBG_IO("raid_req->request_id : 0x%x", raid_req->request_id); + DBG_IO("raid_req->buffer_length : 0x%x", raid_req->buffer_length); + DBG_IO("raid_req->task_attribute : 0x%x", raid_req->task_attribute); + DBG_IO("raid_req->lun_number : 0x%x", raid_req->lun_number); + DBG_IO("raid_req->error_index : 0x%x", raid_req->error_index); + DBG_IO("raid_req->sg_descriptors[0].addr : %p", (void*)raid_req->sg_descriptors[0].addr); + DBG_IO("raid_req->sg_descriptors[0].len : 0x%x", raid_req->sg_descriptors[0].len); + DBG_IO("raid_req->sg_descriptors[0].flags : 0%x", raid_req->sg_descriptors[0].flags); +#endif + rcb->success_cmp_callback = pqisrc_process_io_response_success; + rcb->error_cmp_callback = pqisrc_process_raid_response_error; + rcb->resp_qid = raid_req->response_queue_id; + + DBG_FUNC(" OUT "); + +} + +/*Subroutine used to Build the AIO request */ +static void +pqisrc_build_aio_io(pqisrc_softstate_t *softs, rcb_t *rcb, + pqi_aio_req_t *aio_req, uint32_t num_elem_alloted) +{ + DBG_FUNC(" IN "); + + aio_req->header.iu_type = PQI_IU_TYPE_AIO_PATH_IO_REQUEST; + aio_req->header.comp_feature = 0; + aio_req->response_queue_id = OS_GET_IO_RESP_QID(softs, rcb); + aio_req->work_area[0] = 0; + aio_req->work_area[1] = 0; + aio_req->req_id = rcb->tag; + aio_req->res1[0] = 0; + aio_req->res1[1] = 0; + aio_req->nexus = rcb->ioaccel_handle; + aio_req->buf_len = GET_SCSI_BUFFLEN(rcb); + aio_req->data_dir = rcb->data_dir; + aio_req->mem_type = 0; + aio_req->fence = 0; + aio_req->res2 = 0; + aio_req->task_attr = OS_GET_TASK_ATTR(rcb); + aio_req->cmd_prio = 0; + aio_req->res3 = 0; + aio_req->err_idx = aio_req->req_id; + aio_req->cdb_len = rcb->cmdlen; + memcpy(aio_req->cdb, rcb->cdbp, rcb->cmdlen); +#if 0 + DBG_IO("CDB : \n"); + for(int i = 0; i < rcb->cmdlen ; i++) + DBG_IO(" 0x%x \n",aio_req->cdb[i]); +#endif + memset(aio_req->lun,0,sizeof(aio_req->lun)); + memset(aio_req->res4,0,sizeof(aio_req->res4)); + + if(rcb->encrypt_enable == true) { + aio_req->encrypt_enable = true; + aio_req->encrypt_key_index = LE_16(rcb->enc_info.data_enc_key_index); + aio_req->encrypt_twk_low = LE_32(rcb->enc_info.encrypt_tweak_lower); + aio_req->encrypt_twk_high = LE_32(rcb->enc_info.encrypt_tweak_upper); + } else { + aio_req->encrypt_enable = 0; + aio_req->encrypt_key_index = 0; + aio_req->encrypt_twk_high = 0; + aio_req->encrypt_twk_low = 0; + } + + /* Frame SGL Descriptor */ + aio_req->partial = pqisrc_build_sgl(&aio_req->sg_desc[0], rcb, + &aio_req->header, num_elem_alloted); + + aio_req->num_sg = aio_req->header.iu_length / sizeof(sgt_t); + + DBG_INFO("aio_req->num_sg :%d",aio_req->num_sg); + + aio_req->header.iu_length += offsetof(pqi_aio_req_t, sg_desc) - + sizeof(iu_header_t); +#if 0 + DBG_IO("aio_req->header.iu_type : 0x%x \n",aio_req->header.iu_type); + DBG_IO("aio_req->resp_qid :0x%x",aio_req->resp_qid); + DBG_IO("aio_req->req_id : 0x%x \n",aio_req->req_id); + DBG_IO("aio_req->nexus : 0x%x \n",aio_req->nexus); + DBG_IO("aio_req->buf_len : 0x%x \n",aio_req->buf_len); + DBG_IO("aio_req->data_dir : 0x%x \n",aio_req->data_dir); + DBG_IO("aio_req->task_attr : 0x%x \n",aio_req->task_attr); + DBG_IO("aio_req->err_idx : 0x%x \n",aio_req->err_idx); + DBG_IO("aio_req->num_sg :%d",aio_req->num_sg); + DBG_IO("aio_req->sg_desc[0].addr : %p \n", (void*)aio_req->sg_desc[0].addr); + DBG_IO("aio_req->sg_desc[0].len : 0%x \n", aio_req->sg_desc[0].len); + DBG_IO("aio_req->sg_desc[0].flags : 0%x \n", aio_req->sg_desc[0].flags); +#endif + + rcb->success_cmp_callback = pqisrc_process_io_response_success; + rcb->error_cmp_callback = pqisrc_process_aio_response_error; + rcb->resp_qid = aio_req->response_queue_id; + + DBG_FUNC(" OUT "); + +} + +/*Function used to build and send RAID/AIO */ +int pqisrc_build_send_io(pqisrc_softstate_t *softs,rcb_t *rcb) +{ + ib_queue_t *ib_q_array = softs->op_aio_ib_q; + ib_queue_t *ib_q = NULL; + char *ib_iu = NULL; + IO_PATH_T io_path = AIO_PATH; + uint32_t TraverseCount = 0; + int first_qindex = OS_GET_IO_REQ_QINDEX(softs, rcb); + int qindex = first_qindex; + uint32_t num_op_ib_q = softs->num_op_aio_ibq; + uint32_t num_elem_needed; + uint32_t num_elem_alloted = 0; + pqi_scsi_dev_t *devp = rcb->dvp; + uint8_t raidbypass_cdb[16]; + + DBG_FUNC(" IN "); + + + rcb->cdbp = OS_GET_CDBP(rcb); + + if(IS_AIO_PATH(devp)) { + /** IO for Physical Drive **/ + /** Send in AIO PATH**/ + rcb->ioaccel_handle = devp->ioaccel_handle; + } else { + int ret = PQI_STATUS_FAILURE; + /** IO for RAID Volume **/ + if (devp->offload_enabled) { + /** ByPass IO ,Send in AIO PATH **/ + ret = pqisrc_send_scsi_cmd_raidbypass(softs, + devp, rcb, raidbypass_cdb); + } + + if (PQI_STATUS_FAILURE == ret) { + /** Send in RAID PATH **/ + io_path = RAID_PATH; + num_op_ib_q = softs->num_op_raid_ibq; + ib_q_array = softs->op_raid_ib_q; + } else { + rcb->cdbp = raidbypass_cdb; + } + } + + num_elem_needed = pqisrc_num_elem_needed(softs, OS_GET_IO_SG_COUNT(rcb)); + DBG_IO("num_elem_needed :%d",num_elem_needed); + + do { + uint32_t num_elem_available; + ib_q = (ib_q_array + qindex); + PQI_LOCK(&ib_q->lock); + num_elem_available = pqisrc_contiguous_free_elem(ib_q->pi_local, + *(ib_q->ci_virt_addr), ib_q->num_elem); + + DBG_IO("num_elem_avialable :%d\n",num_elem_available); + if(num_elem_available >= num_elem_needed) { + num_elem_alloted = num_elem_needed; + break; + } + DBG_IO("Current queue is busy! Hop to next queue\n"); + + PQI_UNLOCK(&ib_q->lock); + qindex = (qindex + 1) % num_op_ib_q; + if(qindex == first_qindex) { + if (num_elem_needed == 1) + break; + TraverseCount += 1; + num_elem_needed = 1; + } + }while(TraverseCount < 2); + + DBG_IO("num_elem_alloted :%d",num_elem_alloted); + if (num_elem_alloted == 0) { + DBG_WARN("OUT: IB Queues were full\n"); + return PQI_STATUS_QFULL; + } + + /* Get IB Queue Slot address to build IU */ + ib_iu = ib_q->array_virt_addr + (ib_q->pi_local * ib_q->elem_size); + + if(io_path == AIO_PATH) { + /** Build AIO structure **/ + pqisrc_build_aio_io(softs, rcb, (pqi_aio_req_t*)ib_iu, + num_elem_alloted); + } else { + /** Build RAID structure **/ + pqisrc_build_raid_io(softs, rcb, (pqisrc_raid_req_t*)ib_iu, + num_elem_alloted); + } + + rcb->req_pending = true; + + /* Update the local PI */ + ib_q->pi_local = (ib_q->pi_local + num_elem_alloted) % ib_q->num_elem; + + DBG_INFO("ib_q->pi_local : %x\n", ib_q->pi_local); + DBG_INFO("*ib_q->ci_virt_addr: %x\n",*(ib_q->ci_virt_addr)); + + /* Inform the fw about the new IU */ + PCI_MEM_PUT32(softs, ib_q->pi_register_abs, ib_q->pi_register_offset, ib_q->pi_local); + + PQI_UNLOCK(&ib_q->lock); + DBG_FUNC(" OUT "); + return PQI_STATUS_SUCCESS; +} + +/* Subroutine used to set encryption info as part of RAID bypass IO*/ +static inline void pqisrc_set_enc_info( + struct pqi_enc_info *enc_info, struct raid_map *raid_map, + uint64_t first_block) +{ + uint32_t volume_blk_size; + + /* + * Set the encryption tweak values based on logical block address. + * If the block size is 512, the tweak value is equal to the LBA. + * For other block sizes, tweak value is (LBA * block size) / 512. + */ + volume_blk_size = GET_LE32((uint8_t *)&raid_map->volume_blk_size); + if (volume_blk_size != 512) + first_block = (first_block * volume_blk_size) / 512; + + enc_info->data_enc_key_index = + GET_LE16((uint8_t *)&raid_map->data_encryption_key_index); + enc_info->encrypt_tweak_upper = ((uint32_t)(((first_block) >> 16) >> 16)); + enc_info->encrypt_tweak_lower = ((uint32_t)(first_block)); +} + + +/* + * Attempt to perform offload RAID mapping for a logical volume I/O. + */ + +#define HPSA_RAID_0 0 +#define HPSA_RAID_4 1 +#define HPSA_RAID_1 2 /* also used for RAID 10 */ +#define HPSA_RAID_5 3 /* also used for RAID 50 */ +#define HPSA_RAID_51 4 +#define HPSA_RAID_6 5 /* also used for RAID 60 */ +#define HPSA_RAID_ADM 6 /* also used for RAID 1+0 ADM */ +#define HPSA_RAID_MAX HPSA_RAID_ADM +#define HPSA_RAID_UNKNOWN 0xff + +/* Subroutine used to parse the scsi opcode and build the CDB for RAID bypass*/ +int check_for_scsi_opcode(uint8_t *cdb, boolean_t *is_write, uint64_t *fst_blk, + uint32_t *blk_cnt) { + + switch (cdb[0]) { + case SCMD_WRITE_6: + *is_write = true; + case SCMD_READ_6: + *fst_blk = (uint64_t)(((cdb[1] & 0x1F) << 16) | + (cdb[2] << 8) | cdb[3]); + *blk_cnt = (uint32_t)cdb[4]; + if (*blk_cnt == 0) + *blk_cnt = 256; + break; + case SCMD_WRITE_10: + *is_write = true; + case SCMD_READ_10: + *fst_blk = (uint64_t)GET_BE32(&cdb[2]); + *blk_cnt = (uint32_t)GET_BE16(&cdb[7]); + break; + case SCMD_WRITE_12: + *is_write = true; + case SCMD_READ_12: + *fst_blk = (uint64_t)GET_BE32(&cdb[2]); + *blk_cnt = GET_BE32(&cdb[6]); + break; + case SCMD_WRITE_16: + *is_write = true; + case SCMD_READ_16: + *fst_blk = GET_BE64(&cdb[2]); + *blk_cnt = GET_BE32(&cdb[10]); + break; + default: + /* Process via normal I/O path. */ + return PQI_STATUS_FAILURE; + } + return PQI_STATUS_SUCCESS; +} + +/* + * Function used to build and send RAID bypass request to the adapter + */ +int pqisrc_send_scsi_cmd_raidbypass(pqisrc_softstate_t *softs, + pqi_scsi_dev_t *device, rcb_t *rcb, uint8_t *cdb) +{ + struct raid_map *raid_map; + boolean_t is_write = false; + uint32_t map_idx; + uint64_t fst_blk, lst_blk; + uint32_t blk_cnt, blks_per_row; + uint64_t fst_row, lst_row; + uint32_t fst_row_offset, lst_row_offset; + uint32_t fst_col, lst_col; + uint32_t r5or6_blks_per_row; + uint64_t r5or6_fst_row, r5or6_lst_row; + uint32_t r5or6_fst_row_offset, r5or6_lst_row_offset; + uint32_t r5or6_fst_col, r5or6_lst_col; + uint16_t data_disks_per_row, total_disks_per_row; + uint16_t layout_map_count; + uint32_t stripesz; + uint16_t strip_sz; + uint32_t fst_grp, lst_grp, cur_grp; + uint32_t map_row; + uint64_t disk_block; + uint32_t disk_blk_cnt; + uint8_t cdb_length; + int offload_to_mirror; + int i; + DBG_FUNC(" IN \n"); + DBG_IO("!!!!!\n"); + + /* Check for eligible opcode, get LBA and block count. */ + memcpy(cdb, OS_GET_CDBP(rcb), rcb->cmdlen); + + for(i = 0; i < rcb->cmdlen ; i++) + DBG_IO(" CDB [ %d ] : %x\n",i,cdb[i]); + if(check_for_scsi_opcode(cdb, &is_write, + &fst_blk, &blk_cnt) == PQI_STATUS_FAILURE) + return PQI_STATUS_FAILURE; + /* Check for write to non-RAID-0. */ + if (is_write && device->raid_level != SA_RAID_0) + return PQI_STATUS_FAILURE;; + + if(blk_cnt == 0) + return PQI_STATUS_FAILURE; + + lst_blk = fst_blk + blk_cnt - 1; + raid_map = device->raid_map; + + /* Check for invalid block or wraparound. */ + if (lst_blk >= GET_LE64((uint8_t *)&raid_map->volume_blk_cnt) || + lst_blk < fst_blk) + return PQI_STATUS_FAILURE; + + data_disks_per_row = GET_LE16((uint8_t *)&raid_map->data_disks_per_row); + strip_sz = GET_LE16((uint8_t *)(&raid_map->strip_size)); + layout_map_count = GET_LE16((uint8_t *)(&raid_map->layout_map_count)); + + /* Calculate stripe information for the request. */ + blks_per_row = data_disks_per_row * strip_sz; + + /* use __udivdi3 ? */ + fst_row = fst_blk / blks_per_row; + lst_row = lst_blk / blks_per_row; + fst_row_offset = (uint32_t)(fst_blk - (fst_row * blks_per_row)); + lst_row_offset = (uint32_t)(lst_blk - (lst_row * blks_per_row)); + fst_col = fst_row_offset / strip_sz; + lst_col = lst_row_offset / strip_sz; + + /* If this isn't a single row/column then give to the controller. */ + if (fst_row != lst_row || fst_col != lst_col) + return PQI_STATUS_FAILURE; + + /* Proceeding with driver mapping. */ + total_disks_per_row = data_disks_per_row + + GET_LE16((uint8_t *)(&raid_map->metadata_disks_per_row)); + map_row = ((uint32_t)(fst_row >> raid_map->parity_rotation_shift)) % + GET_LE16((uint8_t *)(&raid_map->row_cnt)); + map_idx = (map_row * total_disks_per_row) + fst_col; + + /* RAID 1 */ + if (device->raid_level == SA_RAID_1) { + if (device->offload_to_mirror) + map_idx += data_disks_per_row; + device->offload_to_mirror = !device->offload_to_mirror; + } else if (device->raid_level == SA_RAID_ADM) { + /* RAID ADM */ + /* + * Handles N-way mirrors (R1-ADM) and R10 with # of drives + * divisible by 3. + */ + offload_to_mirror = device->offload_to_mirror; + if (offload_to_mirror == 0) { + /* use physical disk in the first mirrored group. */ + map_idx %= data_disks_per_row; + } else { + do { + /* + * Determine mirror group that map_idx + * indicates. + */ + cur_grp = map_idx / data_disks_per_row; + + if (offload_to_mirror != cur_grp) { + if (cur_grp < + layout_map_count - 1) { + /* + * Select raid index from + * next group. + */ + map_idx += data_disks_per_row; + cur_grp++; + } else { + /* + * Select raid index from first + * group. + */ + map_idx %= data_disks_per_row; + cur_grp = 0; + } + } + } while (offload_to_mirror != cur_grp); + } + + /* Set mirror group to use next time. */ + offload_to_mirror = + (offload_to_mirror >= layout_map_count - 1) ? + 0 : offload_to_mirror + 1; + if(offload_to_mirror >= layout_map_count) + return PQI_STATUS_FAILURE; + + device->offload_to_mirror = offload_to_mirror; + /* + * Avoid direct use of device->offload_to_mirror within this + * function since multiple threads might simultaneously + * increment it beyond the range of device->layout_map_count -1. + */ + } else if ((device->raid_level == SA_RAID_5 || + device->raid_level == SA_RAID_6) && layout_map_count > 1) { + /* RAID 50/60 */ + /* Verify first and last block are in same RAID group */ + r5or6_blks_per_row = strip_sz * data_disks_per_row; + stripesz = r5or6_blks_per_row * layout_map_count; + + fst_grp = (fst_blk % stripesz) / r5or6_blks_per_row; + lst_grp = (lst_blk % stripesz) / r5or6_blks_per_row; + + if (fst_grp != lst_grp) + return PQI_STATUS_FAILURE; + + /* Verify request is in a single row of RAID 5/6 */ + fst_row = r5or6_fst_row = + fst_blk / stripesz; + r5or6_lst_row = lst_blk / stripesz; + + if (r5or6_fst_row != r5or6_lst_row) + return PQI_STATUS_FAILURE; + + /* Verify request is in a single column */ + fst_row_offset = r5or6_fst_row_offset = + (uint32_t)((fst_blk % stripesz) % + r5or6_blks_per_row); + + r5or6_lst_row_offset = + (uint32_t)((lst_blk % stripesz) % + r5or6_blks_per_row); + + fst_col = r5or6_fst_row_offset / strip_sz; + r5or6_fst_col = fst_col; + r5or6_lst_col = r5or6_lst_row_offset / strip_sz; + + if (r5or6_fst_col != r5or6_lst_col) + return PQI_STATUS_FAILURE; + + /* Request is eligible */ + map_row = + ((uint32_t)(fst_row >> raid_map->parity_rotation_shift)) % + GET_LE16((uint8_t *)(&raid_map->row_cnt)); + + map_idx = (fst_grp * + (GET_LE16((uint8_t *)(&raid_map->row_cnt)) * + total_disks_per_row)) + + (map_row * total_disks_per_row) + fst_col; + } + + if (map_idx >= RAID_MAP_MAX_ENTRIES) + return PQI_STATUS_FAILURE; + + rcb->ioaccel_handle = raid_map->dev_data[map_idx].ioaccel_handle; + disk_block = GET_LE64((uint8_t *)(&raid_map->disk_starting_blk)) + + fst_row * strip_sz + + (fst_row_offset - fst_col * strip_sz); + disk_blk_cnt = blk_cnt; + + /* Handle differing logical/physical block sizes. */ + if (raid_map->phys_blk_shift) { + disk_block <<= raid_map->phys_blk_shift; + disk_blk_cnt <<= raid_map->phys_blk_shift; + } + + if (disk_blk_cnt > 0xffff) + return PQI_STATUS_FAILURE; + + /* Build the new CDB for the physical disk I/O. */ + if (disk_block > 0xffffffff) { + cdb[0] = is_write ? SCMD_WRITE_16 : SCMD_READ_16; + cdb[1] = 0; + PUT_BE64(disk_block, &cdb[2]); + PUT_BE32(disk_blk_cnt, &cdb[10]); + cdb[14] = 0; + cdb[15] = 0; + cdb_length = 16; + } else { + cdb[0] = is_write ? SCMD_WRITE_10 : SCMD_READ_10; + cdb[1] = 0; + PUT_BE32(disk_block, &cdb[2]); + cdb[6] = 0; + PUT_BE16(disk_blk_cnt, &cdb[7]); + cdb[9] = 0; + cdb_length = 10; + } + + if (GET_LE16((uint8_t *)(&raid_map->flags)) & + RAID_MAP_ENCRYPTION_ENABLED) { + pqisrc_set_enc_info(&rcb->enc_info, raid_map, + fst_blk); + rcb->encrypt_enable = true; + } else { + rcb->encrypt_enable = false; + } + + rcb->cmdlen = cdb_length; + + + DBG_FUNC("OUT"); + + return PQI_STATUS_SUCCESS; +} + +/* Function used to submit a TMF to the adater */ +int pqisrc_send_tmf(pqisrc_softstate_t *softs, pqi_scsi_dev_t *devp, + rcb_t *rcb, int req_id, int tmf_type) +{ + int rval = PQI_STATUS_SUCCESS; + pqi_tmf_req_t tmf_req; + + memset(&tmf_req, 0, sizeof(pqi_tmf_req_t)); + + DBG_FUNC("IN"); + + tmf_req.header.iu_type = PQI_REQUEST_IU_TASK_MANAGEMENT; + tmf_req.header.iu_length = sizeof(tmf_req) - sizeof(iu_header_t); + tmf_req.req_id = rcb->tag; + + memcpy(tmf_req.lun, devp->scsi3addr, sizeof(tmf_req.lun)); + tmf_req.tmf = tmf_type; + tmf_req.req_id_to_manage = req_id; + tmf_req.resp_qid = OS_GET_TMF_RESP_QID(softs, rcb); + tmf_req.obq_id_to_manage = rcb->resp_qid; + + rcb->req_pending = true; + + rval = pqisrc_submit_cmnd(softs, + &softs->op_raid_ib_q[OS_GET_TMF_REQ_QINDEX(softs, rcb)], &tmf_req); + if (rval != PQI_STATUS_SUCCESS) { + DBG_ERR("Unable to submit command rval=%d\n", rval); + return rval; + } + + rval = pqisrc_wait_on_condition(softs, rcb); + if (rval != PQI_STATUS_SUCCESS){ + DBG_ERR("Task Management tmf_type : %d timeout\n", tmf_type); + rcb->status = REQUEST_FAILED; + } + + if (rcb->status != REQUEST_SUCCESS) { + DBG_ERR_BTL(devp, "Task Management failed tmf_type:%d " + "stat:0x%x\n", tmf_type, rcb->status); + rval = PQI_STATUS_FAILURE; + } + + DBG_FUNC("OUT"); + return rval; +} Property changes on: head/sys/dev/smartpqi/smartpqi_request.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_response.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_response.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_response.c (revision 333019) @@ -0,0 +1,236 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* + * Process internal RAID response in the case of success. + */ +void pqisrc_process_internal_raid_response_success(pqisrc_softstate_t *softs, + rcb_t *rcb) +{ + DBG_FUNC("IN"); + + rcb->status = REQUEST_SUCCESS; + rcb->req_pending = false; + + DBG_FUNC("OUT"); +} + +/* + * Process internal RAID response in the case of failure. + */ +void pqisrc_process_internal_raid_response_error(pqisrc_softstate_t *softs, + rcb_t *rcb, uint16_t err_idx) +{ + raid_path_error_info_elem_t error_info; + + DBG_FUNC("IN"); + + rcb->error_info = (char *) (softs->err_buf_dma_mem.virt_addr) + + (err_idx * PQI_ERROR_BUFFER_ELEMENT_LENGTH); + rcb->status = REQUEST_SUCCESS; + memcpy(&error_info, rcb->error_info, sizeof(error_info)); + + DBG_INFO("error_status 0x%x data_in_result 0x%x data_out_result 0x%x\n", + error_info.status, error_info.data_in_result, error_info.data_out_result); + + if (error_info.status != 0) + rcb->status = REQUEST_FAILED; + if (error_info.data_in_result != PQI_RAID_DATA_IN_OUT_GOOD) + rcb->status = REQUEST_FAILED; + if (error_info.data_out_result != PQI_RAID_DATA_IN_OUT_GOOD) + rcb->status = REQUEST_FAILED; + + rcb->req_pending = false; + + DBG_FUNC("OUT"); +} + +/* + * Process the AIO/RAID IO in the case of success. + */ +void pqisrc_process_io_response_success(pqisrc_softstate_t *softs, + rcb_t *rcb) +{ + DBG_FUNC("IN"); + + os_io_response_success(rcb); + + DBG_FUNC("OUT"); +} + +/* + * Process the error info for AIO in the case of failure. + */ +void pqisrc_process_aio_response_error(pqisrc_softstate_t *softs, + rcb_t *rcb, uint16_t err_idx) +{ + aio_path_error_info_elem_t *err_info = NULL; + + DBG_FUNC("IN"); + + err_info = (aio_path_error_info_elem_t*) + softs->err_buf_dma_mem.virt_addr + + err_idx; + + if(err_info == NULL) { + DBG_ERR("err_info structure is NULL err_idx :%x", err_idx); + return; + } + + os_aio_response_error(rcb, err_info); + + DBG_FUNC("OUT"); +} + +/* + * Process the error info for RAID IO in the case of failure. + */ +void pqisrc_process_raid_response_error(pqisrc_softstate_t *softs, + rcb_t *rcb, uint16_t err_idx) +{ + raid_path_error_info_elem_t *err_info = NULL; + + DBG_FUNC("IN"); + + err_info = (raid_path_error_info_elem_t*) + softs->err_buf_dma_mem.virt_addr + + err_idx; + + if(err_info == NULL) { + DBG_ERR("err_info structure is NULL err_idx :%x", err_idx); + return; + } + + os_raid_response_error(rcb, err_info); + + DBG_FUNC("OUT"); +} + +/* + * Process the Task Management function response. + */ +int pqisrc_process_task_management_response(pqisrc_softstate_t *softs, + pqi_tmf_resp_t *tmf_resp) +{ + int ret = REQUEST_SUCCESS; + uint32_t tag = (uint32_t)tmf_resp->req_id; + rcb_t *rcb = &softs->rcb[tag]; + + ASSERT(rcb->tag == tag); + + DBG_FUNC("IN\n"); + + switch (tmf_resp->resp_code) { + case SOP_TASK_MANAGEMENT_FUNCTION_COMPLETE: + case SOP_TASK_MANAGEMENT_FUNCTION_SUCCEEDED: + ret = REQUEST_SUCCESS; + break; + default: + DBG_ERR("TMF Failed, Response code : 0x%x\n", tmf_resp->resp_code); + ret = REQUEST_FAILED; + break; + } + + rcb->status = ret; + rcb->req_pending = false; + + DBG_FUNC("OUT"); + return ret; +} + +/* + * Function used to process the response from the adapter + * which is invoked by IRQ handler. + */ +void +pqisrc_process_response_queue(pqisrc_softstate_t *softs, int oq_id) +{ + ob_queue_t *ob_q; + struct pqi_io_response *response; + uint32_t oq_pi, oq_ci; + + DBG_FUNC("IN"); + + OS_ATOMIC64_INC(softs, num_intrs); + + ob_q = &softs->op_ob_q[oq_id - 1]; /* zero for event Q */ + oq_ci = ob_q->ci_local; + oq_pi = *(ob_q->pi_virt_addr); + + DBG_INFO("ci : %d pi : %d qid : %d\n", oq_ci, oq_pi, ob_q->q_id); + + while (1) { + rcb_t *rcb = NULL; + uint32_t tag = 0; + uint32_t offset; + + if (oq_pi == oq_ci) + break; + /* Get the response */ + offset = oq_ci * ob_q->elem_size; + response = (struct pqi_io_response *)(ob_q->array_virt_addr + + offset); + tag = response->request_id; + rcb = &softs->rcb[tag]; + /* Make sure we are processing a valid response. */ + ASSERT(rcb->tag == tag && rcb->req_pending); + rcb->req_pending = false; + + DBG_INFO("response.header.iu_type : %x \n", response->header.iu_type); + + switch (response->header.iu_type) { + case PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS: + case PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS: + rcb->success_cmp_callback(softs, rcb); + break; + case PQI_RESPONSE_IU_RAID_PATH_IO_ERROR: + case PQI_RESPONSE_IU_AIO_PATH_IO_ERROR: + rcb->error_cmp_callback(softs, rcb, LE_16(response->error_index)); + break; + case PQI_RESPONSE_IU_GENERAL_MANAGEMENT: + rcb->req_pending = false; + break; + case PQI_RESPONSE_IU_TASK_MANAGEMENT: + rcb->status = pqisrc_process_task_management_response(softs, (void *)response); + break; + + default: + DBG_ERR("Invalid Response IU 0x%x\n",response->header.iu_type); + break; + } + + oq_ci = (oq_ci + 1) % ob_q->num_elem; + } + + ob_q->ci_local = oq_ci; + PCI_MEM_PUT32(softs, ob_q->ci_register_abs, + ob_q->ci_register_offset, ob_q->ci_local ); + DBG_FUNC("OUT"); +} Property changes on: head/sys/dev/smartpqi/smartpqi_response.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_sis.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_sis.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_sis.c (revision 333019) @@ -0,0 +1,451 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +/* */ +void sis_disable_msix(pqisrc_softstate_t *softs) +{ + uint32_t db_reg; + + DBG_FUNC("IN\n"); + + db_reg = PCI_MEM_GET32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR); + db_reg &= ~SIS_ENABLE_MSIX; + PCI_MEM_PUT32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR, db_reg); + + DBG_FUNC("OUT\n"); +} + +/* Trigger a NMI as part of taking controller offline procedure */ +void pqisrc_trigger_nmi_sis(pqisrc_softstate_t *softs) +{ + + DBG_FUNC("IN\n"); + + PCI_MEM_PUT32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR, LE_32(TRIGGER_NMI_SIS)); + DBG_FUNC("OUT\n"); +} + +/* Switch the adapter back to SIS mode during uninitialization */ +int pqisrc_reenable_sis(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t timeout = SIS_ENABLE_TIMEOUT; + + DBG_FUNC("IN\n"); + + PCI_MEM_PUT32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR, LE_32(REENABLE_SIS)); + + COND_WAIT(((PCI_MEM_GET32(softs, &softs->ioa_reg->ioa_to_host_db, LEGACY_SIS_ODBR_R) & + REENABLE_SIS) == 0), timeout) + if (!timeout) { + DBG_WARN(" [ %s ] failed to re enable sis\n",__func__); + ret = PQI_STATUS_TIMEOUT; + } + + DBG_FUNC("OUT\n"); + return ret; +} + +/* Validate the FW status PQI_CTRL_KERNEL_UP_AND_RUNNING */ +int pqisrc_check_fw_status(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t timeout = SIS_STATUS_OK_TIMEOUT; + + DBG_FUNC("IN\n"); + + OS_SLEEP(1000000); + COND_WAIT((GET_FW_STATUS(softs) & + PQI_CTRL_KERNEL_UP_AND_RUNNING), timeout); + if (!timeout) { + DBG_ERR("FW check status timedout\n"); + ret = PQI_STATUS_TIMEOUT; + } + + DBG_FUNC("OUT\n"); + return ret; +} + +/* Function used to submit a SIS command to the adapter */ +static int pqisrc_send_sis_cmd(pqisrc_softstate_t *softs, + uint32_t *mb) +{ + int ret = PQI_STATUS_SUCCESS; + int i = 0; + uint32_t timeout = SIS_CMD_COMPLETE_TIMEOUT; + + int val; + + DBG_FUNC("IN\n"); + + + /* Copy Command to mailbox */ + for (i = 0; i < 6; i++) + PCI_MEM_PUT32(softs, &softs->ioa_reg->mb[i], + LEGACY_SIS_SRCV_MAILBOX+i*4, LE_32(mb[i])); + + PCI_MEM_PUT32(softs, &softs->ioa_reg->ioa_to_host_db_clr, + LEGACY_SIS_ODBR_R, LE_32(0x1000)); + + /* Submit the command */ + PCI_MEM_PUT32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR, LE_32(SIS_CMD_SUBMIT)); + +#ifdef SIS_POLL_WAIT + /* Wait for 20 milli sec to poll */ + OS_BUSYWAIT(SIS_POLL_START_WAIT_TIME); +#endif + + val = PCI_MEM_GET32(softs, &softs->ioa_reg->ioa_to_host_db, LEGACY_SIS_ODBR_R); + + DBG_FUNC("val : %x\n",val); + /* Spin waiting for the command to complete */ + COND_WAIT((PCI_MEM_GET32(softs, &softs->ioa_reg->ioa_to_host_db, LEGACY_SIS_ODBR_R) & + SIS_CMD_COMPLETE), timeout); + if (!timeout) { + DBG_ERR("Sync command %x, timedout\n", mb[0]); + ret = PQI_STATUS_TIMEOUT; + goto err_out; + } + /* Check command status */ + mb[0] = LE_32(PCI_MEM_GET32(softs, &softs->ioa_reg->mb[0], LEGACY_SIS_SRCV_MAILBOX)); + + if (mb[0] != SIS_CMD_STATUS_SUCCESS) { + DBG_ERR("SIS cmd failed with status = 0x%x\n", + mb[0]); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + + /* Copy the mailbox back */ + for (i = 1; i < 6; i++) + mb[i] = LE_32(PCI_MEM_GET32(softs, &softs->ioa_reg->mb[i], LEGACY_SIS_SRCV_MAILBOX+i*4)); + + DBG_FUNC("OUT\n"); + return ret; + +err_out: + DBG_FUNC("OUT failed\n"); + return ret; +} + +/* First SIS command for the adapter to check PQI support */ +int pqisrc_get_adapter_properties(pqisrc_softstate_t *softs, + uint32_t *prop, uint32_t *ext_prop) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t mb[6] = {0}; + + DBG_FUNC("IN\n"); + + mb[0] = SIS_CMD_GET_ADAPTER_PROPERTIES; + ret = pqisrc_send_sis_cmd(softs, mb); + if (!ret) { + DBG_INFO("GET_PROPERTIES prop = %x, ext_prop = %x\n", + mb[1], mb[4]); + *prop = mb[1]; + *ext_prop = mb[4]; + } + + DBG_FUNC("OUT\n"); + return ret; +} + +/* Second SIS command to the adapter GET_COMM_PREFERRED_SETTINGS */ +int pqisrc_get_preferred_settings(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t mb[6] = {0}; + + DBG_FUNC("IN\n"); + + mb[0] = SIS_CMD_GET_COMM_PREFERRED_SETTINGS; + ret = pqisrc_send_sis_cmd(softs, mb); + if (!ret) { + /* 31:16 maximum command size in KB */ + softs->pref_settings.max_cmd_size = mb[1] >> 16; + /* 15:00: Maximum FIB size in bytes */ + softs->pref_settings.max_fib_size = mb[1] & 0x0000FFFF; + DBG_INFO("cmd size = %x, fib size = %x\n", + softs->pref_settings.max_cmd_size, + softs->pref_settings.max_fib_size); + } + + DBG_FUNC("OUT\n"); + return ret; +} + +/* Get supported PQI capabilities from the adapter */ +int pqisrc_get_sis_pqi_cap(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t mb[6] = {0}; + + DBG_FUNC("IN\n"); + + mb[0] = SIS_CMD_GET_PQI_CAPABILITIES; + ret = pqisrc_send_sis_cmd(softs, mb); + if (!ret) { + softs->pqi_cap.max_sg_elem = mb[1]; + softs->pqi_cap.max_transfer_size = mb[2]; + softs->pqi_cap.max_outstanding_io = mb[3]; +#ifdef DMA_ATTR + softs->os_specific.buf_dma_attr.dma_attr_sgllen = + softs->pqi_cap.max_sg_elem; + softs->os_specific.buf_dma_attr.dma_attr_maxxfer = + softs->pqi_cap.max_transfer_size; + softs->os_specific.buf_dma_attr.dma_attr_count_max = + softs->pqi_cap.max_transfer_size - 1; +#endif + softs->pqi_cap.conf_tab_off = mb[4]; + + softs->pqi_cap.conf_tab_sz = mb[5]; + + DBG_INFO("max_sg_elem = %x\n", + softs->pqi_cap.max_sg_elem); + DBG_INFO("max_transfer_size = %x\n", + softs->pqi_cap.max_transfer_size); + DBG_INFO("max_outstanding_io = %x\n", + softs->pqi_cap.max_outstanding_io); + } + + DBG_FUNC("OUT\n"); + return ret; +} + +/* Send INIT STRUCT BASE ADDR - one of the SIS command */ +int pqisrc_init_struct_base(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t elem_size = 0; + uint32_t num_elem = 0; + struct dma_mem init_struct_mem = {0}; + struct init_base_struct *init_struct = NULL; + uint32_t mb[6] = {0}; + + DBG_FUNC("IN\n"); + + /* Allocate init struct */ + memset(&init_struct_mem, 0, sizeof(struct dma_mem)); + init_struct_mem.size = sizeof(struct init_base_struct); + init_struct_mem.align = PQISRC_INIT_STRUCT_DMA_ALIGN; + init_struct_mem.tag = "init_struct"; + ret = os_dma_mem_alloc(softs, &init_struct_mem); + if (ret) { + DBG_ERR("Failed to Allocate error buffer ret : %d\n", + ret); + goto err_out; + } + + /* Calculate error buffer size */ + /* The valid tag values are from 1, 2, ..., softs->max_outstanding_io + * The rcb and error buffer will be accessed by using the tag as index + * As 0 tag index is not used, we need to allocate one extra. + */ + num_elem = softs->pqi_cap.max_outstanding_io + 1; + elem_size = PQISRC_ERR_BUF_ELEM_SIZE; + softs->err_buf_dma_mem.size = num_elem * elem_size; + + /* Allocate error buffer */ + softs->err_buf_dma_mem.align = PQISRC_ERR_BUF_DMA_ALIGN; + softs->err_buf_dma_mem.tag = "error_buffer"; + ret = os_dma_mem_alloc(softs, &softs->err_buf_dma_mem); + if (ret) { + DBG_ERR("Failed to Allocate error buffer ret : %d\n", + ret); + goto err_error_buf_alloc; + } + + /* Fill init struct */ + init_struct = (struct init_base_struct *)DMA_TO_VIRT(&init_struct_mem); + init_struct->revision = PQISRC_INIT_STRUCT_REVISION; + init_struct->flags = 0; + init_struct->err_buf_paddr_l = DMA_PHYS_LOW(&softs->err_buf_dma_mem); + init_struct->err_buf_paddr_h = DMA_PHYS_HIGH(&softs->err_buf_dma_mem); + init_struct->err_buf_elem_len = elem_size; + init_struct->err_buf_num_elem = num_elem; + + mb[0] = SIS_CMD_INIT_BASE_STRUCT_ADDRESS; + mb[1] = DMA_PHYS_LOW(&init_struct_mem); + mb[2] = DMA_PHYS_HIGH(&init_struct_mem); + mb[3] = init_struct_mem.size; + + ret = pqisrc_send_sis_cmd(softs, mb); + if (ret) + goto err_sis_cmd; + + DBG_FUNC("OUT\n"); + os_dma_mem_free(softs, &init_struct_mem); + return ret; + +err_sis_cmd: + os_dma_mem_free(softs, &softs->err_buf_dma_mem); +err_error_buf_alloc: + os_dma_mem_free(softs, &init_struct_mem); +err_out: + DBG_FUNC("OUT failed %d\n", ret); + return PQI_STATUS_FAILURE; +} + +/* + * SIS initialization of the adapter in a sequence of + * - GET_ADAPTER_PROPERTIES + * - GET_COMM_PREFERRED_SETTINGS + * - GET_PQI_CAPABILITIES + * - INIT_STRUCT_BASE ADDR + */ +int pqisrc_sis_init(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + uint32_t prop = 0; + uint32_t ext_prop = 0; + + DBG_FUNC("IN\n"); + + ret = pqisrc_force_sis(softs); + if (ret) { + DBG_ERR("Failed to switch back the adapter to SIS mode!\n"); + goto err_out; + } + + /* Check FW status ready */ + ret = pqisrc_check_fw_status(softs); + if (ret) { + DBG_ERR("PQI Controller is not ready !!!\n"); + goto err_out; + } + + /* Check For PQI support(19h) */ + ret = pqisrc_get_adapter_properties(softs, &prop, &ext_prop); + if (ret) { + DBG_ERR("Failed to get adapter properties\n"); + goto err_out; + } + if (!((prop & SIS_SUPPORT_EXT_OPT) && + (ext_prop & SIS_SUPPORT_PQI))) { + DBG_ERR("PQI Mode Not Supported\n"); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + + softs->pqi_reset_quiesce_allowed = false; + if (ext_prop & SIS_SUPPORT_PQI_RESET_QUIESCE) + softs->pqi_reset_quiesce_allowed = true; + + /* Send GET_COMM_PREFERRED_SETTINGS (26h) */ + ret = pqisrc_get_preferred_settings(softs); + if (ret) { + DBG_ERR("Failed to get adapter pref settings\n"); + goto err_out; + } + + /* Get PQI settings , 3000h*/ + ret = pqisrc_get_sis_pqi_cap(softs); + if (ret) { + DBG_ERR("Failed to get PQI Capabilities\n"); + goto err_out; + } + + /* We need to allocate DMA memory here , + * Do any os specific DMA setup. + */ + ret = os_dma_setup(softs); + if (ret) { + DBG_ERR("Failed to Setup DMA\n"); + goto err_out; + } + + /* Init struct base addr */ + ret = pqisrc_init_struct_base(softs); + if (ret) { + DBG_ERR("Failed to set init struct base addr\n"); + goto err_dma; + } + + + DBG_FUNC("OUT\n"); + return ret; + +err_dma: + os_dma_destroy(softs); +err_out: + DBG_FUNC("OUT failed\n"); + return ret; +} + +/* Deallocate the resources used during SIS initialization */ +void pqisrc_sis_uninit(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN\n"); + + os_dma_mem_free(softs, &softs->err_buf_dma_mem); + + os_dma_destroy(softs); + os_resource_free(softs); + pqi_reset(softs); + + + DBG_FUNC("OUT\n"); +} + +int pqisrc_sis_wait_for_db_bit_to_clear(pqisrc_softstate_t *softs, uint32_t bit) +{ + int rcode = PQI_STATUS_SUCCESS; + uint32_t db_reg; + uint32_t loop_cnt = 0; + + DBG_FUNC("IN\n"); + + while (1) { + db_reg = PCI_MEM_GET32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR); + if ((db_reg & bit) == 0) + break; + if (GET_FW_STATUS(softs) & PQI_CTRL_KERNEL_PANIC) { + DBG_ERR("controller kernel panic\n"); + rcode = PQI_STATUS_FAILURE; + break; + } + if (loop_cnt++ == SIS_DB_BIT_CLEAR_TIMEOUT_CNT) { + DBG_ERR("door-bell reg bit 0x%x not cleared\n", bit); + rcode = PQI_STATUS_TIMEOUT; + break; + } + OS_SLEEP(500); + } + + DBG_FUNC("OUT\n"); + + return rcode; +} Property changes on: head/sys/dev/smartpqi/smartpqi_sis.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_structures.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_structures.h (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_structures.h (revision 333019) @@ -0,0 +1,1010 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#ifndef _PQI_STRUCTURES_H +#define _PQI_STRUCTURES_H + + + + +struct bmic_host_wellness_driver_version { + uint8_t start_tag[4]; + uint8_t driver_version_tag[2]; + uint16_t driver_version_length; + char driver_version[32]; + uint8_t end_tag[2]; + +}OS_ATTRIBUTE_PACKED; + + +struct bmic_host_wellness_time { + uint8_t start_tag[4]; + uint8_t time_tag[2]; + uint16_t time_length; + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t reserved; + uint8_t month; + uint8_t day; + uint8_t century; + uint8_t year; + uint8_t dont_write_tag[2]; + uint8_t end_tag[2]; + +}OS_ATTRIBUTE_PACKED; + + +/* As per PQI Spec pqi-2r00a , 6.2.2. */ + +/* device capability register , for admin q table 24 */ +struct pqi_dev_adminq_cap { + uint8_t max_admin_ibq_elem; + uint8_t max_admin_obq_elem; + uint8_t admin_ibq_elem_len; + uint8_t admin_obq_elem_len; + uint16_t max_pqi_dev_reset_tmo; + uint8_t res[2]; +}OS_ATTRIBUTE_PACKED; + +/* admin q parameter reg , table 36 */ +struct admin_q_param { + uint8_t num_iq_elements; + uint8_t num_oq_elements; + uint8_t intr_msg_num; + uint8_t msix_disable; +}OS_ATTRIBUTE_PACKED; + +struct pqi_registers { + uint64_t signature; + uint64_t admin_q_config; + uint64_t pqi_dev_adminq_cap; + uint32_t legacy_intr_status; + uint32_t legacy_intr_mask_set; + uint32_t legacy_intr_mask_clr; + uint8_t res1[28]; + uint32_t pqi_dev_status; + uint8_t res2[4]; + uint64_t admin_ibq_pi_offset; + uint64_t admin_obq_ci_offset; + uint64_t admin_ibq_elem_array_addr; + uint64_t admin_obq_elem_array_addr; + uint64_t admin_ibq_ci_addr; + uint64_t admin_obq_pi_addr; + uint32_t admin_q_param; + uint8_t res3[4]; + uint32_t pqi_dev_err; + uint8_t res4[4]; + uint64_t error_details; + uint32_t dev_reset; + uint32_t power_action; + uint8_t res5[104]; +}OS_ATTRIBUTE_PACKED; + +/* + * IOA controller registers + * Mapped in PCIe BAR 0. + */ + +struct ioa_registers { + uint8_t res1[0x18]; + uint32_t host_to_ioa_db_mask_clr; /* 18h */ + uint8_t res2[4]; + uint32_t host_to_ioa_db; /* 20h */ + uint8_t res3[4]; + uint32_t host_to_ioa_db_clr; /* 28h */ + uint8_t res4[8]; + uint32_t ioa_to_host_glob_int_mask; /* 34h */ + uint8_t res5[0x64]; + uint32_t ioa_to_host_db; /* 9Ch */ + uint32_t ioa_to_host_db_clr; /* A0h */ + uint8_t res6[4]; + uint32_t ioa_to_host_db_mask; /* A8h */ + uint32_t ioa_to_host_db_mask_clr; /* ACh */ + uint32_t scratchpad0; /* B0h */ + uint32_t scratchpad1; /* B4h */ + uint32_t scratchpad2; /* B8h */ + uint32_t scratchpad3_fw_status; /* BCh */ + uint8_t res7[8]; + uint32_t scratchpad4; /* C8h */ + uint8_t res8[0xf34]; /* 0xC8 + 4 + 0xf34 = 1000h */ + uint32_t mb[8]; /* 1000h */ +}OS_ATTRIBUTE_PACKED; + + +/* PQI Preferred settings */ +struct pqi_pref_settings { + uint16_t max_cmd_size; + uint16_t max_fib_size; +}OS_ATTRIBUTE_PACKED; + +/* pqi capability by sis interface */ +struct pqi_cap { + uint32_t max_sg_elem; + uint32_t max_transfer_size; + uint32_t max_outstanding_io; + uint32_t conf_tab_off; + uint32_t conf_tab_sz; +}OS_ATTRIBUTE_PACKED; + +struct pqi_conf_table { + uint8_t sign[8]; /* "CFGTABLE" */ + uint32_t first_section_off; +}; + +struct pqi_conf_table_section_header { + uint16_t section_id; + uint16_t next_section_off; +}; + +struct pqi_conf_table_general_info { + struct pqi_conf_table_section_header header; + uint32_t section_len; + uint32_t max_outstanding_req; + uint32_t max_sg_size; + uint32_t max_sg_per_req; +}; + +struct pqi_conf_table_debug { + struct pqi_conf_table_section_header header; + uint32_t scratchpad; +}; + +struct pqi_conf_table_heartbeat { + struct pqi_conf_table_section_header header; + uint32_t heartbeat_counter; +}; + +typedef union pqi_reset_reg { + struct { + uint32_t reset_type : 3; + uint32_t reserved : 2; + uint32_t reset_action : 3; + uint32_t hold_in_pd1 : 1; + uint32_t reserved2 : 23; + } bits; + uint32_t all_bits; +}pqi_reset_reg_t; + +/* Memory descriptor for DMA memory allocation */ +typedef struct dma_mem { + void *virt_addr; + dma_addr_t dma_addr; + uint32_t size; + uint32_t align; + char *tag; + bus_dma_tag_t dma_tag; + bus_dmamap_t dma_map; +}dma_mem_t; + +/* Lock should be 8 byte aligned */ + +#ifndef LOCKFREE_STACK + +typedef struct pqi_taglist { + uint32_t max_elem; + uint32_t num_elem; + uint32_t head; + uint32_t tail; + uint32_t *elem_array; + boolean_t lockcreated; + char lockname[LOCKNAME_SIZE]; + OS_LOCK_T lock OS_ATTRIBUTE_ALIGNED(8); +}pqi_taglist_t; + +#else /* LOCKFREE_STACK */ + +union head_list { + struct { + uint32_t seq_no; /* To avoid aba problem */ + uint32_t index; /* Index at the top of the stack */ + }top; + uint64_t data; +}; +/* lock-free stack used to push and pop the tag used for IO request */ +typedef struct lockless_stack { + uint32_t *next_index_array; + uint32_t num_elements; + volatile union head_list head OS_ATTRIBUTE_ALIGNED(8); +}lockless_stack_t; + +#endif /* LOCKFREE_STACK */ + +/* + * PQI SGL descriptor layouts. + */ +/* + * SGL (Scatter Gather List) descriptor Codes + */ + +#define SGL_DESCRIPTOR_CODE_DATA_BLOCK 0x0 +#define SGL_DESCRIPTOR_CODE_BIT_BUCKET 0x1 +#define SGL_DESCRIPTOR_CODE_STANDARD_SEGMENT 0x2 +#define SGL_DESCRIPTOR_CODE_LAST_STANDARD_SEGMENT 0x3 +#define SGL_DESCRIPTOR_CODE_LAST_ALTERNATIVE_SGL_SEGMENT 0x4 +#define SGL_DESCRIPTOR_CODE_VENDOR_SPECIFIC 0xF + +typedef struct sgl_descriptor +{ + uint64_t addr; /* !< Bytes 0-7. The starting 64-bit memory byte address of the data block. */ + uint32_t length; /* !< Bytes 8-11. The length in bytes of the data block. Set to 0x00000000 specifies that no data be transferred. */ + uint8_t res[3]; /* !< Bytes 12-14. */ + uint8_t zero : 4; /* !< Byte 15, Bits 0-3. */ + uint8_t type : 4; /* !< Byte 15, Bits 4-7. sgl descriptor type */ +} sg_desc_t; + +/* PQI IUs */ +typedef struct iu_header +{ + uint8_t iu_type; + uint8_t comp_feature; + uint16_t iu_length; +}OS_ATTRIBUTE_PACKED iu_header_t; + + +typedef struct general_admin_request /* REPORT_PQI_DEVICE_CAPABILITY, REPORT_MANUFACTURER_INFO, REPORT_OPERATIONAL_IQ, REPORT_OPERATIONAL_OQ all same layout. */ +{ + iu_header_t header; /* !< Bytes 0-3. */ + uint16_t res1; + uint16_t work; + uint16_t req_id; /* !< Bytes 8-9. request identifier */ + uint8_t fn_code; /* !< Byte 10. which administrator function */ + union { + struct { + uint8_t res2[33]; /* !< Bytes 11-43. function specific */ + uint32_t buf_size; /* !< Bytes 44-47. size in bytes of the Data-In/Out Buffer */ + sg_desc_t sg_desc; /* !< Bytes 48-63. SGL */ + } OS_ATTRIBUTE_PACKED general_func; + + struct { + uint8_t res1; + uint16_t qid; + uint8_t res2[2]; + uint64_t elem_arr_addr; + uint64_t iq_ci_addr; + uint16_t num_elem; + uint16_t elem_len; + uint8_t queue_proto; + uint8_t arb_prio; + uint8_t res3[22]; + uint32_t vend_specific; + } OS_ATTRIBUTE_PACKED create_op_iq; + + struct { + uint8_t res1; + uint16_t qid; + uint8_t res2[2]; + uint64_t elem_arr_addr; + uint64_t ob_pi_addr; + uint16_t num_elem; + uint16_t elem_len; + uint8_t queue_proto; + uint8_t res3[3]; + uint16_t intr_msg_num; + uint16_t coales_count; + uint32_t min_coales_time; + uint32_t max_coales_time; + uint8_t res4[8]; + uint32_t vend_specific; + } OS_ATTRIBUTE_PACKED create_op_oq; + + struct { + uint8_t res1; + uint16_t qid; + uint8_t res2[50]; + } OS_ATTRIBUTE_PACKED delete_op_queue; + + struct { + uint8_t res1; + uint16_t qid; + uint8_t res2[46]; + uint32_t vend_specific; + } OS_ATTRIBUTE_PACKED change_op_iq_prop; + + } OS_ATTRIBUTE_PACKED req_type; + +}OS_ATTRIBUTE_PACKED gen_adm_req_iu_t; + + +typedef struct general_admin_response { + iu_header_t header; + uint16_t res1; + uint16_t work; + uint16_t req_id; + uint8_t fn_code; + uint8_t status; + union { + struct { + uint8_t status_desc[4]; + uint64_t pi_offset; + uint8_t res[40]; + } OS_ATTRIBUTE_PACKED create_op_iq; + + struct { + uint8_t status_desc[4]; + uint64_t ci_offset; + uint8_t res[40]; + } OS_ATTRIBUTE_PACKED create_op_oq; + } OS_ATTRIBUTE_PACKED resp_type; +} OS_ATTRIBUTE_PACKED gen_adm_resp_iu_t ; + +/*report and set Event config IU*/ + +typedef struct pqi_event_config_request { + iu_header_t header; + uint16_t response_queue_id; /* specifies the OQ where the response + IU is to be delivered */ + uint8_t work_area[2]; /* reserved for driver use */ + uint16_t request_id; + union { + uint16_t reserved; /* Report event config iu */ + uint16_t global_event_oq_id; /* Set event config iu */ + }iu_specific; + uint32_t buffer_length; + sg_desc_t sg_desc; +}pqi_event_config_request_t; +#if 0 +typedef struct pqi_set_event_config_request { + iu_header_t header; + uint16_t response_queue_id; /* specifies the OQ where the response + IU is to be delivered */ + uint8_t work_area[2]; /* reserved for driver use */ + uint16_t request_id; + uint16_t global_event_oq_id; + uint32_t buffer_length; + sg_desc_t sg_desc; +}pqi_set_event_config_request_t; +#endif + + /* Report/Set event config data-in/data-out buffer structure */ + +#define PQI_MAX_EVENT_DESCRIPTORS 255 + +struct pqi_event_descriptor { + uint8_t event_type; + uint8_t reserved; + uint16_t oq_id; +}; + +typedef struct pqi_event_config { + uint8_t reserved[2]; + uint8_t num_event_descriptors; + uint8_t reserved1; + struct pqi_event_descriptor descriptors[PQI_MAX_EVENT_DESCRIPTORS]; +}pqi_event_config_t; + +/*management response IUs */ +typedef struct pqi_management_response{ + iu_header_t header; + uint16_t reserved1; + uint8_t work_area[2]; + uint16_t req_id; + uint8_t result; + uint8_t reserved[5]; + uint64_t result_data; +}pqi_management_response_t; + /*Event response IU*/ +typedef struct pqi_event_response { + iu_header_t header; + uint16_t reserved1; + uint8_t work_area[2]; + uint8_t event_type; + uint8_t reserved2 : 7; + uint8_t request_acknowledge : 1; + uint16_t event_id; + uint32_t additional_event_id; + uint8_t data[16]; +}pqi_event_response_t; + + /*event acknowledge IU*/ +typedef struct pqi_event_acknowledge_request { + iu_header_t header; + uint16_t reserved1; + uint8_t work_area[2]; + uint8_t event_type; + uint8_t reserved2; + uint16_t event_id; + uint32_t additional_event_id; +}pqi_event_acknowledge_request_t; + +struct pqi_event { + boolean_t pending; + uint8_t event_type; + uint16_t event_id; + uint32_t additional_event_id; +}; + + +typedef struct op_q_params +{ + uint8_t fn_code; + uint16_t qid; + uint16_t num_elem; + uint16_t elem_len; + uint16_t int_msg_num; + +} OS_ATTRIBUTE_PACKED op_q_params; + + +/* Driver will use this structure to interpret the error + info element returned from a failed requests */ +typedef struct raid_path_error_info_elem { + uint8_t data_in_result; /* !< Byte 0. See SOP spec Table 77. */ + uint8_t data_out_result; /* !< Byte 1. See SOP spec Table 78. */ + uint8_t reserved[3]; /* !< Bytes 2-4. */ + uint8_t status; /* !< Byte 5. See SAM-5 specification "Status" codes Table 40. Defined in Storport.h */ + uint16_t status_qual; /* !< Bytes 6-7. See SAM-5 specification Table 43. */ + uint16_t sense_data_len; /* !< Bytes 8-9. See SOP specification table 79. */ + uint16_t resp_data_len; /* !< Bytes 10-11. See SOP specification table 79. */ + uint32_t data_in_transferred; /* !< Bytes 12-15. If "dada_in_result = 0x01 (DATA_IN BUFFER UNDERFLOW)", Indicates the number of contiguous bytes starting with offset zero in Data-In buffer else Ignored. */ + uint32_t data_out_transferred; /* !< Bytes 16-19. If "data_out_result = 0x01 (DATA_OUT BUFFER UNDERFLOW)", Indicates the number of contiguous bytes starting with offset zero in Data-Out buffer else Ignored. */ + uint8_t data[256]; /* !< Bytes 20-275. Response Data buffer or Sense Data buffer but not both. */ +}OS_ATTRIBUTE_PACKED raid_path_error_info_elem_t; + +#define PQI_ERROR_BUFFER_ELEMENT_LENGTH sizeof(raid_path_error_info_elem_t) + +typedef enum error_data_present +{ + DATA_PRESENT_NO_DATA = 0, /* !< No data present in Data buffer. */ + DATA_PRESENT_RESPONSE_DATA = 1, /* !< Response data is present in Data buffer. */ + DATA_PRESENT_SENSE_DATA = 2 /* !< Sense data is present in Data buffer. */ +} error_data_present_t; + +typedef struct aio_path_error_info_elem +{ + uint8_t status; /* !< Byte 0. See SAM-5 specification "SCSI Status" codes Table 40. Defined in Storport.h */ + uint8_t service_resp; /* !< Byte 1. SCSI Service Response. */ + uint8_t data_pres; /* !< Byte 2. Bits [7:2] reserved. Bits [1:0] - 0=No data, 1=Response data, 2=Sense data. */ + uint8_t reserved1; /* !< Byte 3. Reserved. */ + uint32_t resd_count; /* !< Bytes 4-7. The residual data length in bytes. Need the original transfer size and if Status is OverRun or UnderRun. */ + uint16_t data_len; /* !< Bytes 8-9. The amount of Sense data or Response data returned in Response/Sense Data buffer. */ + uint16_t reserved2; /* !< Bytes 10. Reserved. */ + uint8_t data[256]; /* !< Bytes 11-267. Response data buffer or Sense data buffer but not both. */ + uint8_t padding[8]; /* !< Bytes 268-275. Padding to make AIO_PATH_ERROR_INFO_ELEMENT = RAID_PATH_ERROR_INFO_ELEMENT */ +}OS_ATTRIBUTE_PACKED aio_path_error_info_elem_t; + +struct init_base_struct { + uint32_t revision; /* revision of init structure */ + uint32_t flags; /* reserved */ + uint32_t err_buf_paddr_l; /* lower 32 bits of physical address of error buffer */ + uint32_t err_buf_paddr_h; /* upper 32 bits of physical address of error buffer */ + uint32_t err_buf_elem_len; /* length of each element in error buffer (in bytes) */ + uint32_t err_buf_num_elem; /* number of elements in error buffer */ +}OS_ATTRIBUTE_PACKED; + +/* Queue details */ +typedef struct ib_queue { + uint32_t q_id; + uint32_t num_elem; + uint32_t elem_size; + char *array_virt_addr; + dma_addr_t array_dma_addr; + uint32_t pi_local; + uint32_t pi_register_offset; + uint32_t *pi_register_abs; + uint32_t *ci_virt_addr; + dma_addr_t ci_dma_addr; + boolean_t created; + boolean_t lockcreated; + char lockname[LOCKNAME_SIZE]; + OS_LOCK_T lock OS_ATTRIBUTE_ALIGNED(8); +}ib_queue_t; + +typedef struct ob_queue { + uint32_t q_id; + uint32_t num_elem; + uint32_t elem_size; + uint32_t intr_msg_num; + char *array_virt_addr; + dma_addr_t array_dma_addr; + uint32_t ci_local; + uint32_t ci_register_offset; + uint32_t *ci_register_abs; + uint32_t *pi_virt_addr; + dma_addr_t pi_dma_addr; + boolean_t created; +}ob_queue_t; + +typedef struct pqisrc_sg_desc{ + uint64_t addr; + uint32_t len; + uint32_t flags; +}sgt_t; + + +typedef struct pqi_iu_layer_desc { + uint8_t ib_spanning_supported : 1; + uint8_t res1 : 7; + uint8_t res2[5]; + uint16_t max_ib_iu_len; + uint8_t ob_spanning_supported : 1; + uint8_t res3 : 7; + uint8_t res4[5]; + uint16_t max_ob_iu_len; +}OS_ATTRIBUTE_PACKED pqi_iu_layer_desc_t; + + +/* Response IU data */ +typedef struct pqi_device_capabilities { + uint16_t length; + uint8_t res1[6]; + uint8_t ibq_arb_priority_support_bitmask; + uint8_t max_aw_a; + uint8_t max_aw_b; + uint8_t max_aw_c; + uint8_t max_arb_burst : 3; + uint8_t res2 : 4; + uint8_t iqa : 1; + uint8_t res3[2]; + uint8_t iq_freeze : 1; + uint8_t res4 : 7; + uint16_t max_iqs; + uint16_t max_iq_elements; + uint8_t res5[4]; + uint16_t max_iq_elem_len; + uint16_t min_iq_elem_len; + uint8_t res6[2]; + uint16_t max_oqs; + uint16_t max_oq_elements; + uint16_t intr_coales_time_granularity; + uint16_t max_oq_elem_len; + uint16_t min_oq_elem_len; + uint8_t res7[24]; + pqi_iu_layer_desc_t iu_layer_desc[32]; +}OS_ATTRIBUTE_PACKED pqi_dev_cap_t; + +/* IO path */ + +typedef struct pqi_aio_req { + iu_header_t header; + uint16_t response_queue_id; + uint8_t work_area[2]; + uint16_t req_id; + uint8_t res1[2]; + uint32_t nexus; + uint32_t buf_len; + uint8_t data_dir : 2; + uint8_t partial : 1; + uint8_t mem_type : 1; + uint8_t fence : 1; + uint8_t encrypt_enable : 1; + uint8_t res2 : 2; + uint8_t task_attr : 3; + uint8_t cmd_prio : 4; + uint8_t res3 : 1; + uint16_t encrypt_key_index; + uint32_t encrypt_twk_low; + uint32_t encrypt_twk_high; + uint8_t cdb[16]; + uint16_t err_idx; + uint8_t num_sg; + uint8_t cdb_len; + uint8_t lun[8]; + uint8_t res4[4]; + sgt_t sg_desc[4]; +}OS_ATTRIBUTE_PACKED pqi_aio_req_t; + + +typedef struct pqisrc_raid_request { + iu_header_t header; + uint16_t response_queue_id; /* specifies the OQ where the response + IU is to be delivered */ + uint8_t work_area[2]; /* reserved for driver use */ + uint16_t request_id; + uint16_t nexus_id; + uint32_t buffer_length; + uint8_t lun_number[8]; + uint16_t protocol_spec; + uint8_t data_direction : 2; + uint8_t partial : 1; + uint8_t reserved1 : 4; + uint8_t fence : 1; + uint16_t error_index; + uint8_t reserved2; + uint8_t task_attribute : 3; + uint8_t command_priority : 4; + uint8_t reserved3 : 1; + uint8_t reserved4 : 2; + uint8_t additional_cdb_bytes_usage : 3; + uint8_t reserved5 : 3; + uint8_t cdb[16]; + uint8_t additional_cdb_bytes[16]; + sgt_t sg_descriptors[4]; +}OS_ATTRIBUTE_PACKED pqisrc_raid_req_t; + + +typedef struct pqi_tmf_req { + iu_header_t header; + uint16_t resp_qid; + uint8_t work_area[2]; + uint16_t req_id; + uint16_t nexus; + uint8_t res1[4]; + uint8_t lun[8]; + uint16_t protocol_spec; + uint16_t obq_id_to_manage; + uint16_t req_id_to_manage; + uint8_t tmf; + uint8_t res2 : 7; + uint8_t fence : 1; +}OS_ATTRIBUTE_PACKED pqi_tmf_req_t; + + +typedef struct pqi_tmf_resp { + iu_header_t header; + uint16_t resp_qid; + uint8_t work_area[2]; + uint16_t req_id; + uint16_t nexus; + uint8_t add_resp_info[3]; + uint8_t resp_code; +}pqi_tmf_resp_t; + + +struct pqi_io_response { + iu_header_t header; + uint16_t queue_id; + uint8_t work_area[2]; + uint16_t request_id; + uint16_t error_index; + uint8_t reserved[4]; +}OS_ATTRIBUTE_PACKED; + + +struct pqi_enc_info { + uint16_t data_enc_key_index; + uint32_t encrypt_tweak_lower; + uint32_t encrypt_tweak_upper; +}; + + +typedef struct pqi_scsi_device { + device_type_t devtype; /* as reported by INQUIRY commmand */ + uint8_t device_type; /* as reported by + BMIC_IDENTIFY_PHYSICAL_DEVICE - only + valid for devtype = TYPE_DISK */ + int bus; + int target; + int lun; + uint8_t flags; + uint8_t scsi3addr[8]; + uint64_t wwid; + uint8_t is_physical_device : 1; + uint8_t is_external_raid_device : 1; + uint8_t target_lun_valid : 1; + uint8_t expose_device : 1; + uint8_t no_uld_attach : 1; + uint8_t is_obdr_device : 1; + uint8_t aio_enabled : 1; + uint8_t device_gone : 1; + uint8_t new_device : 1; + uint8_t volume_offline : 1; + uint8_t vendor[8]; /* bytes 8-15 of inquiry data */ + uint8_t model[16]; /* bytes 16-31 of inquiry data */ + uint64_t sas_address; + uint8_t raid_level; + uint16_t queue_depth; /* max. queue_depth for this device */ + uint16_t advertised_queue_depth; + uint32_t ioaccel_handle; + uint8_t volume_status; + uint8_t active_path_index; + uint8_t path_map; + uint8_t bay; + uint8_t box[8]; + uint16_t phys_connector[8]; + int offload_config; /* I/O accel RAID offload configured */ + int offload_enabled; /* I/O accel RAID offload enabled */ + int offload_enabled_pending; + int offload_to_mirror; /* Send next I/O accelerator RAID + offload request to mirror drive. */ + struct raid_map *raid_map; /* I/O accelerator RAID map */ + int reset_in_progress; + os_dev_info_t *dip; /*os specific scsi device information*/ + boolean_t invalid; +}pqi_scsi_dev_t; + + +struct sense_header_scsi { /* See SPC-3 section 4.5 */ + uint8_t response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ + uint8_t sense_key; + uint8_t asc; + uint8_t ascq; + uint8_t byte4; + uint8_t byte5; + uint8_t byte6; + uint8_t additional_length; /* always 0 for fixed sense format */ +}OS_ATTRIBUTE_PACKED; + + + +typedef struct report_lun_header { + uint32_t list_length; + uint8_t extended_response; + uint8_t reserved[3]; +}OS_ATTRIBUTE_PACKED reportlun_header_t; + + +typedef struct report_lun_ext_entry { + uint8_t lunid[8]; + uint64_t wwid; + uint8_t device_type; + uint8_t device_flags; + uint8_t lun_count; /* number of LUNs in a multi-LUN device */ + uint8_t redundant_paths; + uint32_t ioaccel_handle; +}OS_ATTRIBUTE_PACKED reportlun_ext_entry_t; + + +typedef struct report_lun_data_ext { + reportlun_header_t header; + reportlun_ext_entry_t lun_entries[1]; +}OS_ATTRIBUTE_PACKED reportlun_data_ext_t; + +typedef struct raidmap_data { + uint32_t ioaccel_handle; + uint8_t xor_mult[2]; + uint8_t reserved[2]; +}OS_ATTRIBUTE_PACKED raidmap_data_t; + +typedef struct raid_map { + uint32_t structure_size; /* size of entire structure in bytes */ + uint32_t volume_blk_size; /* bytes / block in the volume */ + uint64_t volume_blk_cnt; /* logical blocks on the volume */ + uint8_t phys_blk_shift; /* shift factor to convert between + units of logical blocks and physical + disk blocks */ + uint8_t parity_rotation_shift; /* shift factor to convert between units + of logical stripes and physical + stripes */ + uint16_t strip_size; /* blocks used on each disk / stripe */ + uint64_t disk_starting_blk; /* first disk block used in volume */ + uint64_t disk_blk_cnt; /* disk blocks used by volume / disk */ + uint16_t data_disks_per_row; /* data disk entries / row in the map */ + uint16_t metadata_disks_per_row; /* mirror/parity disk entries / row + in the map */ + uint16_t row_cnt; /* rows in each layout map */ + uint16_t layout_map_count; /* layout maps (1 map per mirror/parity + group) */ + uint16_t flags; + uint16_t data_encryption_key_index; + uint8_t reserved[16]; + raidmap_data_t dev_data[RAID_MAP_MAX_ENTRIES]; +}OS_ATTRIBUTE_PACKED pqisrc_raid_map_t; + + +typedef struct bmic_ident_ctrl { + uint8_t conf_ld_count; + uint32_t conf_sign; + uint8_t fw_version[4]; + uint8_t rom_fw_rev[4]; + uint8_t hw_rev; + uint8_t reserved[140]; + uint16_t extended_lun_count; + uint8_t reserved1[34]; + uint16_t fw_build_number; + uint8_t reserved2[100]; + uint8_t ctrl_mode; + uint8_t reserved3[32]; +}OS_ATTRIBUTE_PACKED bmic_ident_ctrl_t; + +typedef struct bmic_identify_physical_device { + uint8_t scsi_bus; /* SCSI Bus number on controller */ + uint8_t scsi_id; /* SCSI ID on this bus */ + uint16_t block_size; /* sector size in bytes */ + uint32_t total_blocks; /* number for sectors on drive */ + uint32_t reserved_blocks; /* controller reserved (RIS) */ + uint8_t model[40]; /* Physical Drive Model */ + uint8_t serial_number[40]; /* Drive Serial Number */ + uint8_t firmware_revision[8]; /* drive firmware revision */ + uint8_t scsi_inquiry_bits; /* inquiry byte 7 bits */ + uint8_t compaq_drive_stamp; /* 0 means drive not stamped */ + uint8_t last_failure_reason; + uint8_t flags; + uint8_t more_flags; + uint8_t scsi_lun; /* SCSI LUN for phys drive */ + uint8_t yet_more_flags; + uint8_t even_more_flags; + uint32_t spi_speed_rules; + uint8_t phys_connector[2]; /* connector number on controller */ + uint8_t phys_box_on_bus; /* phys enclosure this drive resides */ + uint8_t phys_bay_in_box; /* phys drv bay this drive resides */ + uint32_t rpm; /* drive rotational speed in RPM */ + uint8_t device_type; /* type of drive */ + uint8_t sata_version; /* only valid when device_type = + BMIC_DEVICE_TYPE_SATA */ + uint64_t big_total_block_count; + uint64_t ris_starting_lba; + uint32_t ris_size; + uint8_t wwid[20]; + uint8_t controller_phy_map[32]; + uint16_t phy_count; + uint8_t phy_connected_dev_type[256]; + uint8_t phy_to_drive_bay_num[256]; + uint16_t phy_to_attached_dev_index[256]; + uint8_t box_index; + uint8_t reserved; + uint16_t extra_physical_drive_flags; + uint8_t negotiated_link_rate[256]; + uint8_t phy_to_phy_map[256]; + uint8_t redundant_path_present_map; + uint8_t redundant_path_failure_map; + uint8_t active_path_number; + uint16_t alternate_paths_phys_connector[8]; + uint8_t alternate_paths_phys_box_on_port[8]; + uint8_t multi_lun_device_lun_count; + uint8_t minimum_good_fw_revision[8]; + uint8_t unique_inquiry_bytes[20]; + uint8_t current_temperature_degreesC; + uint8_t temperature_threshold_degreesC; + uint8_t max_temperature_degreesC; + uint8_t logical_blocks_per_phys_block_exp; + uint16_t current_queue_depth_limit; + uint8_t switch_name[10]; + uint16_t switch_port; + uint8_t alternate_paths_switch_name[40]; + uint8_t alternate_paths_switch_port[8]; + uint16_t power_on_hours; + uint16_t percent_endurance_used; + uint8_t drive_authentication; + uint8_t smart_carrier_authentication; + uint8_t smart_carrier_app_fw_version; + uint8_t smart_carrier_bootloader_fw_version; + uint8_t encryption_key_name[64]; + uint32_t misc_drive_flags; + uint16_t dek_index; + uint8_t padding[112]; +}OS_ATTRIBUTE_PACKED bmic_ident_physdev_t; + +typedef struct pqisrc_bmic_flush_cache { + uint8_t disable_cache; + uint8_t power_action; + uint8_t ndu_flush_cache; + uint8_t halt_event; + uint8_t reserved[28]; +} OS_ATTRIBUTE_PACKED pqisrc_bmic_flush_cache_t; + +/* for halt_event member of pqisrc_bmic_flush_cache_t */ +enum pqisrc_flush_cache_event_type { + PQISRC_NONE_CACHE_FLUSH_ONLY = 0, + PQISRC_SHUTDOWN = 1, + PQISRC_HIBERNATE = 2, + PQISRC_SUSPEND = 3, + PQISRC_RESTART = 4 +}; + +struct pqisrc_softstate; +struct request_container_block; +typedef void (*success_callback)(struct pqisrc_softstate *, struct request_container_block *); +typedef void (*error_callback)(struct pqisrc_softstate *, struct request_container_block *, uint16_t); + +/* Request container block */ +typedef struct request_container_block { + void *req; + void *error_info; + REQUEST_STATUS_T status; + uint32_t tag; + sgt_t *sg_chain_virt; + dma_addr_t sg_chain_dma; + uint32_t data_dir; + pqi_scsi_dev_t *dvp; + struct pqisrc_softstate *softs; + success_callback success_cmp_callback; + error_callback error_cmp_callback; + uint8_t *cdbp; + int cmdlen; + uint32_t bcount; /* buffer size in byte */ + uint32_t ioaccel_handle; + boolean_t encrypt_enable; + struct pqi_enc_info enc_info; + int cm_flags; + void *cm_data; /* pointer to data in kernel space */ + bus_dmamap_t cm_datamap; + uint32_t nseg; + union ccb *cm_ccb; + sgt_t *sgt; /* sg table */ + int resp_qid; + boolean_t req_pending; +}rcb_t; + +typedef struct pqisrc_softstate { + OS_SPECIFIC_T os_specific; + struct ioa_registers *ioa_reg; + struct pqi_registers *pqi_reg; + char *pci_mem_base_vaddr; + PCI_ACC_HANDLE_T pci_mem_handle; + struct pqi_cap pqi_cap; + struct pqi_pref_settings pref_settings; + char fw_version[11]; + uint16_t fw_build_number; + uint32_t card; /* index to aac_cards */ + uint16_t vendid; /* vendor id */ + uint16_t subvendid; /* sub vendor id */ + uint16_t devid; /* device id */ + uint16_t subsysid; /* sub system id */ + controller_state_t ctlr_state; + struct dma_mem err_buf_dma_mem; + struct dma_mem admin_queue_dma_mem; + struct dma_mem op_ibq_dma_mem; + struct dma_mem op_obq_dma_mem; + struct dma_mem event_q_dma_mem; + struct dma_mem sg_dma_desc[PQISRC_MAX_OUTSTANDING_REQ]; + ib_queue_t admin_ib_queue; + ob_queue_t admin_ob_queue; + ob_queue_t event_q; + ob_queue_t op_ob_q[PQISRC_MAX_SUPPORTED_OP_OB_Q - 1];/* 1 event queue */ + ib_queue_t op_raid_ib_q[PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q]; + ib_queue_t op_aio_ib_q[PQISRC_MAX_SUPPORTED_OP_AIO_IB_Q]; + uint32_t max_outstanding_io; + uint32_t max_io_for_scsi_ml; + uint32_t num_op_raid_ibq; + uint32_t num_op_aio_ibq; + uint32_t num_op_obq; + uint32_t num_elem_per_op_ibq; + uint32_t num_elem_per_op_obq; + uint32_t ibq_elem_size; + uint32_t obq_elem_size; + pqi_dev_cap_t pqi_dev_cap; + uint16_t max_ib_iu_length_per_fw; + uint16_t max_ib_iu_length; + unsigned max_sg_per_iu; + uint8_t ib_spanning_supported : 1; + uint8_t ob_spanning_supported : 1; + pqi_event_config_t event_config; + struct pqi_event pending_events[PQI_NUM_SUPPORTED_EVENTS]; + int intr_type; + int intr_count; + int num_cpus_online; + boolean_t share_opq_and_eventq; + rcb_t *rcb; +#ifndef LOCKFREE_STACK + pqi_taglist_t taglist; +#else + lockless_stack_t taglist; +#endif /* LOCKFREE_STACK */ + boolean_t devlist_lockcreated; + OS_LOCK_T devlist_lock OS_ATTRIBUTE_ALIGNED(8); + char devlist_lock_name[LOCKNAME_SIZE]; + pqi_scsi_dev_t *device_list[PQI_MAX_DEVICES][PQI_MAX_MULTILUN]; + OS_SEMA_LOCK_T scan_lock; + uint8_t lun_count[PQI_MAX_DEVICES]; + OS_ATOMIC64_T num_intrs; + uint64_t prev_num_intrs; + uint64_t prev_heartbeat_count; + uint64_t *heartbeat_counter_abs_addr; + uint64_t heartbeat_counter_off; + uint64_t num_heartbeats_requested; + uint32_t bus_id; + uint32_t device_id; + uint32_t func_id; + char *os_name; + boolean_t ctrl_online; + uint8_t pqi_reset_quiesce_allowed : 1; + boolean_t ctrl_in_pqi_mode; +}pqisrc_softstate_t; + +#endif Property changes on: head/sys/dev/smartpqi/smartpqi_structures.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/smartpqi/smartpqi_tag.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_tag.c (nonexistent) +++ head/sys/dev/smartpqi/smartpqi_tag.c (revision 333019) @@ -0,0 +1,265 @@ +/*- + * Copyright (c) 2018 Microsemi Corporation. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +/* $FreeBSD$ */ + +#include "smartpqi_includes.h" + +#ifndef LOCKFREE_STACK + +/* + * Function used to release the tag from taglist. + */ +void pqisrc_put_tag(pqi_taglist_t *taglist, uint32_t elem) +{ + + OS_ACQUIRE_SPINLOCK(&(taglist->lock)); + /*DBG_FUNC("IN\n");*/ + + ASSERT(taglist->num_elem < taglist->max_elem); + + if (taglist->num_elem < taglist->max_elem) { + taglist->elem_array[taglist->tail] = elem; + taglist->num_elem++; + taglist->tail = (taglist->tail + 1) % taglist->max_elem; + } + + OS_RELEASE_SPINLOCK(&taglist->lock); + + /*DBG_FUNC("OUT\n");*/ +} + +/* + * Function used to get an unoccupied tag from the tag list. + */ +uint32_t pqisrc_get_tag(pqi_taglist_t *taglist) +{ + uint32_t elem = INVALID_ELEM; + + /*DBG_FUNC("IN\n");*/ + + OS_ACQUIRE_SPINLOCK(&taglist->lock); + + ASSERT(taglist->num_elem > 0); + + if (taglist->num_elem > 0) { + elem = taglist->elem_array[taglist->head]; + taglist->num_elem--; + taglist->head = (taglist->head + 1) % taglist->max_elem; + } + + OS_RELEASE_SPINLOCK(&taglist->lock); + + /*DBG_FUNC("OUT got %d\n", elem);*/ + return elem; +} + +/* + * Initialize circular queue implementation of tag list. + */ +int pqisrc_init_taglist(pqisrc_softstate_t *softs, pqi_taglist_t *taglist, + uint32_t max_elem) +{ + int ret = PQI_STATUS_SUCCESS; + int i = 0; + + DBG_FUNC("IN\n"); + + taglist->max_elem = max_elem; + taglist->num_elem = 0; + taglist->head = 0; + taglist->tail = 0; + taglist->elem_array = os_mem_alloc(softs, + (max_elem * sizeof(uint32_t))); + if (!(taglist->elem_array)) { + DBG_FUNC("Unable to allocate memory for taglist\n"); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + + os_strlcpy(taglist->lockname, "tag_lock", LOCKNAME_SIZE); + ret = os_init_spinlock(softs, &taglist->lock, taglist->lockname); + if(ret){ + DBG_ERR("tag lock initialization failed\n"); + taglist->lockcreated=false; + goto err_lock; + } + taglist->lockcreated = true; + + /* indices 1 to max_elem are considered as valid tags */ + for (i=1; i <= max_elem; i++) { + softs->rcb[i].tag = INVALID_ELEM; + pqisrc_put_tag(taglist, i); + } + + DBG_FUNC("OUT\n"); + return ret; + +err_lock: + os_mem_free(softs, (char *)taglist->elem_array, + (taglist->max_elem * sizeof(uint32_t))); + taglist->elem_array = NULL; +err_out: + DBG_FUNC("OUT failed\n"); + return ret; +} + +/* + * Destroy circular queue implementation of tag list. + */ +void pqisrc_destroy_taglist(pqisrc_softstate_t *softs, pqi_taglist_t *taglist) +{ + DBG_FUNC("IN\n"); + os_mem_free(softs, (char *)taglist->elem_array, + (taglist->max_elem * sizeof(uint32_t))); + taglist->elem_array = NULL; + + if(taglist->lockcreated==true){ + os_uninit_spinlock(&taglist->lock); + taglist->lockcreated = false; + } + + DBG_FUNC("OUT\n"); +} + +#else /* LOCKFREE_STACK */ + +/* + * Initialize circular queue implementation of tag list. + */ +int pqisrc_init_taglist(pqisrc_softstate_t *softs, lockless_stack_t *stack, + uint32_t max_elem) +{ + int ret = PQI_STATUS_SUCCESS; + int index = 0; + + DBG_FUNC("IN\n"); + + /* indices 1 to max_elem are considered as valid tags */ + stack->num_elements = max_elem + 1; + stack->head.data = 0; + DBG_INFO("Stack head address :%p\n",&stack->head); + + /*Allocate memory for stack*/ + stack->next_index_array = (uint32_t*)os_mem_alloc(softs, + (stack->num_elements * sizeof(uint32_t))); + if (!(stack->next_index_array)) { + DBG_ERR("Unable to allocate memory for stack\n"); + ret = PQI_STATUS_FAILURE; + goto err_out; + } + + /* push all the entries to the stack */ + for (index = 1; index < stack->num_elements ; index++) { + softs->rcb[index].tag = INVALID_ELEM; + pqisrc_put_tag(stack, index); + } + + DBG_FUNC("OUT\n"); + return ret; +err_out: + DBG_FUNC("Failed OUT\n"); + return ret; +} + +/* + * Destroy circular queue implementation of tag list. + */ +void pqisrc_destroy_taglist(pqisrc_softstate_t *softs, lockless_stack_t *stack) +{ + DBG_FUNC("IN\n"); + + /* de-allocate stack memory */ + if (stack->next_index_array) { + os_mem_free(softs,(char*)stack->next_index_array, + (stack->num_elements * sizeof(uint32_t))); + stack->next_index_array = NULL; + } + + DBG_FUNC("OUT\n"); +} + +/* + * Function used to release the tag from taglist. + */ +void pqisrc_put_tag(lockless_stack_t *stack, uint32_t index) +{ + union head_list cur_head, new_head; + + DBG_FUNC("IN\n"); + DBG_INFO("push tag :%d\n",index); + + if ( index >= stack->num_elements ) { + ASSERT(false); + DBG_ERR("Pushed Invalid index\n"); /* stack full */ + return; + } + + if ( stack->next_index_array[index] != 0) { + ASSERT(false); + DBG_ERR("Index already present as tag in the stack\n"); + return; + } + + do { + cur_head = stack->head; + /* increment seq_no */ + new_head.top.seq_no = cur_head.top.seq_no + 1; + /* update the index at the top of the stack with the new index */ + new_head.top.index = index; + /* Create a link to the previous index */ + stack->next_index_array[index] = cur_head.top.index; + }while(OS_ATOMIC64_CAS(&stack->head.data,cur_head.data,new_head.data) + != cur_head.data); + DBG_FUNC("OUT\n"); + return; +} + +/* + * Function used to get an unoccupied tag from the tag list. + */ +uint32_t pqisrc_get_tag(lockless_stack_t *stack) +{ + union head_list cur_head, new_head; + + DBG_FUNC("IN\n"); + do { + cur_head = stack->head; + if (cur_head.top.index == 0) /* stack empty */ + return INVALID_ELEM; + /* increment seq_no field */ + new_head.top.seq_no = cur_head.top.seq_no + 1; + /* update the index at the top of the stack with the next index */ + new_head.top.index = stack->next_index_array[cur_head.top.index]; + }while(OS_ATOMIC64_CAS(&stack->head.data,cur_head.data,new_head.data) + != cur_head.data); + stack->next_index_array[cur_head.top.index] = 0; + + DBG_INFO("pop tag: %d\n",cur_head.top.index); + DBG_FUNC("OUT\n"); + return cur_head.top.index; /*tag*/ +} +#endif /* LOCKFREE_STACK */ Property changes on: head/sys/dev/smartpqi/smartpqi_tag.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/modules/Makefile =================================================================== --- head/sys/modules/Makefile (revision 333018) +++ head/sys/modules/Makefile (revision 333019) @@ -1,839 +1,841 @@ # $FreeBSD$ SYSDIR?=${SRCTOP}/sys .include "${SYSDIR}/conf/kern.opts.mk" SUBDIR_PARALLEL= # Modules that include binary-only blobs of microcode should be selectable by # MK_SOURCELESS_UCODE option (see below). .if defined(MODULES_OVERRIDE) && !defined(ALL_MODULES) SUBDIR=${MODULES_OVERRIDE} .else SUBDIR= \ ${_3dfx} \ ${_3dfx_linux} \ ${_aac} \ ${_aacraid} \ accf_data \ accf_dns \ accf_http \ acl_nfs4 \ acl_posix1e \ ${_acpi} \ ae \ ${_aesni} \ age \ ${_agp} \ aha \ ahci \ ${_aic} \ aic7xxx \ alc \ ale \ alq \ ${_amd_ecc_inject} \ ${_amdsbwd} \ ${_amdsmn} \ ${_amdtemp} \ amr \ ${_an} \ ${_aout} \ ${_apm} \ ${_arcmsr} \ ${_armv8crypto} \ ${_asmc} \ ata \ ath \ ath_dfs \ ath_hal \ ath_hal_ar5210 \ ath_hal_ar5211 \ ath_hal_ar5212 \ ath_hal_ar5416 \ ath_hal_ar9300 \ ath_main \ ath_rate \ ath_pci \ ${_autofs} \ ${_auxio} \ ${_bce} \ ${_bcm283x_clkman} \ ${_bcm283x_pwm} \ bfe \ bge \ bhnd \ ${_bxe} \ ${_bios} \ ${_bktr} \ ${_blake2} \ ${_bm} \ bnxt \ bridgestp \ bwi \ bwn \ ${_bytgpio} \ ${_chvgpio} \ cam \ ${_cardbus} \ ${_carp} \ cas \ ${_cbb} \ cc \ ${_ccp} \ cd9660 \ cd9660_iconv \ ${_ce} \ ${_cfi} \ ${_chromebook_platform} \ ${_ciss} \ cloudabi \ ${_cloudabi32} \ ${_cloudabi64} \ ${_cmx} \ ${_coff} \ ${_coretemp} \ ${_cp} \ ${_cpsw} \ ${_cpuctl} \ ${_cpufreq} \ ${_crypto} \ ${_cryptodev} \ ${_cs} \ ${_ctau} \ ctl \ ${_cxgb} \ ${_cxgbe} \ dc \ dcons \ dcons_crom \ de \ ${_dpms} \ ${_dpt} \ ${_drm} \ ${_drm2} \ dummynet \ ${_ed} \ ${_efirt} \ ${_em} \ ${_ena} \ ${_ep} \ ${_epic} \ esp \ ${_et} \ evdev \ ${_ex} \ ${_exca} \ ext2fs \ fdc \ fdescfs \ ${_fe} \ ${_ffec} \ filemon \ firewire \ firmware \ fuse \ ${_fxp} \ gem \ geom \ ${_glxiic} \ ${_glxsb} \ gpio \ hifn \ hme \ ${_hpt27xx} \ ${_hptiop} \ ${_hptmv} \ ${_hptnr} \ ${_hptrr} \ hwpmc \ ${_hwpmc_mips24k} \ ${_hwpmc_mips74k} \ ${_hyperv} \ i2c \ ${_ibcore} \ ${_ibcs2} \ ${_ichwd} \ ${_ida} \ if_bridge \ if_disc \ if_edsc \ ${_if_enc} \ if_epair \ ${_if_gif} \ ${_if_gre} \ ${_if_me} \ if_lagg \ ${_if_ndis} \ ${_if_stf} \ if_tap \ if_tun \ if_vlan \ if_vxlan \ ${_iir} \ imgact_binmisc \ ${_intelspi} \ ${_io} \ ${_ioat} \ ${_ipoib} \ ${_ipdivert} \ ${_ipfilter} \ ${_ipfw} \ ipfw_nat \ ${_ipfw_nat64} \ ${_ipfw_nptv6} \ ${_ipfw_pmod} \ ${_ipmi} \ ip6_mroute_mod \ ip_mroute_mod \ ${_ips} \ ${_ipsec} \ ${_ipw} \ ${_ipwfw} \ ${_isci} \ ${_iser} \ isp \ ${_ispfw} \ ${_iwi} \ ${_iwifw} \ ${_iwm} \ ${_iwmfw} \ ${_iwn} \ ${_iwnfw} \ ${_ix} \ ${_ixv} \ ${_ixgb} \ ${_ixl} \ ${_ixlv} \ jme \ joy \ kbdmux \ kgssapi \ kgssapi_krb5 \ khelp \ krpc \ ksyms \ le \ lge \ libalias \ libiconv \ libmchain \ ${_linprocfs} \ ${_linsysfs} \ ${_linux} \ ${_linux_common} \ ${_linux64} \ linuxkpi \ ${_lio} \ lmc \ lpt \ mac_biba \ mac_bsdextended \ mac_ifoff \ mac_lomac \ mac_mls \ mac_none \ mac_partition \ mac_portacl \ mac_seeotheruids \ mac_stub \ mac_test \ malo \ md \ mdio \ mem \ mfi \ mii \ mlx \ ${_mlx4} \ ${_mlx4ib} \ ${_mlx4en} \ ${_mlx5} \ ${_mlx5en} \ ${_mlx5ib} \ ${_mly} \ mmc \ mmcsd \ mpr \ mps \ mpt \ mqueue \ mrsas \ msdosfs \ msdosfs_iconv \ ${_mse} \ msk \ ${_mthca} \ mvs \ mwl \ ${_mwlfw} \ mxge \ my \ ${_nandfs} \ ${_nandsim} \ ${_ncr} \ ${_nctgpio} \ ${_ncv} \ ${_ndis} \ ${_netgraph} \ ${_nfe} \ nfscl \ nfscommon \ nfsd \ nfslock \ nfslockd \ nfssvc \ nge \ nmdm \ ${_nsp} \ nullfs \ ${_ntb} \ ${_nvd} \ ${_nvme} \ ${_nvram} \ ${_nxge} \ oce \ ${_ocs_fc} \ otus \ ${_otusfw} \ ow \ ${_padlock} \ ${_padlock_rng} \ ${_pccard} \ ${_pcfclock} \ pcn \ ${_pf} \ ${_pflog} \ ${_pfsync} \ plip \ ${_pms} \ ppbus \ ppc \ ppi \ pps \ procfs \ proto \ pseudofs \ ${_pst} \ pty \ puc \ ${_qlxge} \ ${_qlxgb} \ ${_qlxgbe} \ ${_qlnx} \ ral \ ${_ralfw} \ ${_random_fortuna} \ ${_random_yarrow} \ ${_random_other} \ rc4 \ ${_rdma} \ ${_rdrand_rng} \ re \ rl \ rtwn \ rtwn_pci \ rtwn_usb \ ${_rtwnfw} \ ${_s3} \ ${_safe} \ ${_sbni} \ scc \ ${_scsi_low} \ sdhci \ ${_sdhci_acpi} \ sdhci_pci \ sem \ send \ ${_sf} \ ${_sfxge} \ sge \ ${_sgx} \ ${_sgx_linux} \ siftr \ siis \ sis \ sk \ + ${_smartpqi} \ smbfs \ sn \ snp \ sound \ ${_speaker} \ spi \ ${_splash} \ ${_sppp} \ ste \ ${_stg} \ stge \ ${_sym} \ ${_syscons} \ sysvipc \ tcp \ ${_ti} \ tl \ tmpfs \ ${_toecore} \ ${_tpm} \ trm \ ${_twa} \ twe \ tws \ tx \ ${_txp} \ uart \ ubsec \ udf \ udf_iconv \ ufs \ uinput \ unionfs \ usb \ ${_vesa} \ ${_virtio} \ vge \ ${_viawd} \ videomode \ vkbd \ ${_vmm} \ ${_vmware} \ ${_vpo} \ vr \ vte \ vx \ ${_vxge} \ wb \ ${_wbwd} \ ${_wi} \ wlan \ wlan_acl \ wlan_amrr \ wlan_ccmp \ wlan_rssadapt \ wlan_tkip \ wlan_wep \ wlan_xauth \ ${_wpi} \ ${_wpifw} \ ${_x86bios} \ ${_xe} \ xl \ zlib .if ${MK_AUTOFS} != "no" || defined(ALL_MODULES) _autofs= autofs .endif .if ${MK_CDDL} != "no" || defined(ALL_MODULES) .if (${MACHINE_CPUARCH} != "arm" || ${MACHINE_ARCH:Marmv[67]*} != "") && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_CPUARCH} != "sparc64" SUBDIR+= dtrace .endif SUBDIR+= opensolaris .endif .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) .if exists(${SRCTOP}/sys/opencrypto) _crypto= crypto _cryptodev= cryptodev _random_fortuna=random_fortuna _random_yarrow= random_yarrow _random_other= random_other .endif .endif .if ${MK_CUSE} != "no" || defined(ALL_MODULES) SUBDIR+= cuse .endif .if (${MK_INET_SUPPORT} != "no" || ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _carp= carp _toecore= toecore _if_enc= if_enc _if_gif= if_gif _if_gre= if_gre _ipfw_pmod= ipfw_pmod .if ${MK_IPSEC_SUPPORT} != "no" _ipsec= ipsec .endif .endif .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _if_stf= if_stf .endif .if ${MK_INET_SUPPORT} != "no" || defined(ALL_MODULES) _if_me= if_me _ipdivert= ipdivert _ipfw= ipfw .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nat64= ipfw_nat64 .endif .endif .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nptv6= ipfw_nptv6 .endif .if ${MK_IPFILTER} != "no" || defined(ALL_MODULES) _ipfilter= ipfilter .endif .if ${MK_ISCSI} != "no" || defined(ALL_MODULES) SUBDIR+= cfiscsi SUBDIR+= iscsi SUBDIR+= iscsi_initiator .endif .if ${MK_NAND} != "no" || defined(ALL_MODULES) _nandfs= nandfs _nandsim= nandsim .endif .if ${MK_NETGRAPH} != "no" || defined(ALL_MODULES) _netgraph= netgraph .endif .if (${MK_PF} != "no" && (${MK_INET_SUPPORT} != "no" || \ ${MK_INET6_SUPPORT} != "no")) || defined(ALL_MODULES) _pf= pf _pflog= pflog .if ${MK_INET_SUPPORT} != "no" _pfsync= pfsync .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" _bce= bce _fxp= fxp _ispfw= ispfw _sf= sf _ti= ti _txp= txp .if ${MACHINE_CPUARCH} != "mips" _mwlfw= mwlfw _otusfw= otusfw _ralfw= ralfw _rtwnfw= rtwnfw .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \ ${MACHINE_CPUARCH} != "riscv" _cxgbe= cxgbe .endif .if ${MK_TESTS} != "no" || defined(ALL_MODULES) SUBDIR+= tests .endif .if ${MK_ZFS} != "no" || defined(ALL_MODULES) SUBDIR+= zfs .endif .if (${MACHINE_CPUARCH} == "mips" && ${MACHINE_ARCH:Mmips64} == "") _hwpmc_mips24k= hwpmc_mips24k _hwpmc_mips74k= hwpmc_mips74k .endif .if ${MACHINE_CPUARCH} != "aarch64" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && ${MACHINE_CPUARCH} != "powerpc" && \ ${MACHINE_CPUARCH} != "riscv" _syscons= syscons _vpo= vpo .endif .if ${MACHINE_CPUARCH} != "mips" # no BUS_SPACE_UNSPECIFIED # No barrier instruction support (specific to this driver) _sym= sym # intr_disable() is a macro, causes problems .if ${MK_SOURCELESS_UCODE} != "no" _cxgb= cxgb .endif .endif .if ${MACHINE_CPUARCH} == "aarch64" _armv8crypto= armv8crypto _efirt= efirt _em= em .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _agp= agp _an= an _aout= aout _bios= bios _bktr= bktr .if ${MK_SOURCELESS_UCODE} != "no" _bxe= bxe .endif _cardbus= cardbus _cbb= cbb _cpuctl= cpuctl _cpufreq= cpufreq _cs= cs _dpms= dpms _drm= drm _drm2= drm2 _ed= ed _em= em _ena= ena _ep= ep _et= et _exca= exca _fe= fe .if ${MK_OFED} != "no" || defined(ALL_MODULES) _ibcore= ibcore .endif _if_ndis= if_ndis _io= io .if ${MK_OFED} != "no" || defined(ALL_MODULES) _ipoib= ipoib _iser= iser .endif _ix= ix _ixv= ixv _linprocfs= linprocfs _linsysfs= linsysfs _linux= linux .if ${MK_SOURCELESS_UCODE} != "no" _lio= lio .endif _nctgpio= nctgpio _ndis= ndis _ocs_fc= ocs_fc _pccard= pccard .if ${MK_OFED} != "no" || defined(ALL_MODULES) _rdma= rdma .endif _safe= safe _scsi_low= scsi_low _speaker= speaker _splash= splash _sppp= sppp _vmware= vmware _vxge= vxge _wbwd= wbwd _wi= wi _xe= xe _aac= aac _aacraid= aacraid _acpi= acpi .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _aesni= aesni .endif _amd_ecc_inject=amd_ecc_inject _amdsbwd= amdsbwd _amdsmn= amdsmn _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _blake2= blake2 .endif _bytgpio= bytgpio _chvgpio= chvgpio _ciss= ciss _chromebook_platform= chromebook_platform _cmx= cmx _coretemp= coretemp .if ${MK_SOURCELESS_HOST} != "no" _hpt27xx= hpt27xx .endif _hptiop= hptiop .if ${MK_SOURCELESS_HOST} != "no" _hptmv= hptmv _hptnr= hptnr _hptrr= hptrr .endif _hyperv= hyperv _ichwd= ichwd _ida= ida _iir= iir _intelspi= intelspi _ipmi= ipmi _ips= ips _isci= isci _ipw= ipw _iwi= iwi _iwm= iwm _iwn= iwn _ixgb= ixgb .if ${MK_SOURCELESS_UCODE} != "no" _ipwfw= ipwfw _iwifw= iwifw _iwmfw= iwmfw _iwnfw= iwnfw .endif _mlx4= mlx4 _mlx5= mlx5 .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _mlx4en= mlx4en _mlx5en= mlx5en .endif .if ${MK_OFED} != "no" || defined(ALL_MODULES) _mthca= mthca _mlx4ib= mlx4ib _mlx5ib= mlx5ib .endif _mly= mly _nfe= nfe _nvd= nvd _nvme= nvme _nvram= nvram _nxge= nxge .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _padlock= padlock _padlock_rng= padlock_rng _rdrand_rng= rdrand_rng .endif _s3= s3 _sdhci_acpi= sdhci_acpi _tpm= tpm _twa= twa _vesa= vesa _viawd= viawd _virtio= virtio _wpi= wpi .if ${MK_SOURCELESS_UCODE} != "no" _wpifw= wpifw .endif _x86bios= x86bios .endif .if ${MACHINE_CPUARCH} == "amd64" _ccp= ccp _efirt= efirt _ioat= ioat _ixl= ixl _ixlv= ixlv _linux64= linux64 _linux_common= linux_common _ntb= ntb _pms= pms _qlxge= qlxge _qlxgb= qlxgb .if ${MK_SOURCELESS_UCODE} != "no" _qlxgbe= qlxgbe _qlnx= qlnx .endif _sfxge= sfxge _sgx= sgx _sgx_linux= sgx_linux +_smartpqi= smartpqi .if ${MK_BHYVE} != "no" || defined(ALL_MODULES) _vmm= vmm .endif .endif .if ${MACHINE_CPUARCH} == "i386" # XXX some of these can move to the general case when de-i386'ed # XXX some of these can move now, but are untested on other architectures. _3dfx= 3dfx _3dfx_linux= 3dfx_linux _aic= aic _apm= apm .if ${MK_SOURCELESS_UCODE} != "no" _ce= ce .endif _coff= coff .if ${MK_SOURCELESS_UCODE} != "no" _cp= cp .endif _glxiic= glxiic _glxsb= glxsb #_ibcs2= ibcs2 _mse= mse _ncr= ncr _ncv= ncv _nsp= nsp _pcfclock= pcfclock _pst= pst _sbni= sbni _stg= stg .if ${MK_SOURCELESS_UCODE} != "no" _ctau= ctau .endif _dpt= dpt _ex= ex .endif .if ${MACHINE_CPUARCH} == "arm" _cfi= cfi _cpsw= cpsw .endif .if ${MACHINE_CPUARCH} == "powerpc" _agp= agp _an= an _bm= bm _cardbus= cardbus _cbb= cbb _cfi= cfi _cpufreq= cpufreq _drm= drm _exca= exca _ffec= ffec _pccard= pccard _wi= wi .endif .if ${MACHINE_ARCH} == "powerpc64" _drm2= drm2 .endif .if ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "powerpc" # Don't build powermac_nvram for powerpcspe, it's never supported. _nvram= powermac_nvram .endif .if ${MACHINE_CPUARCH} == "sparc64" _auxio= auxio _em= em _epic= epic .endif .if (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "i386") _cloudabi32= cloudabi32 .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" _cloudabi64= cloudabi64 .endif .endif .if ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "aarch64" _bcm283x_clkman= bcm283x_clkman _bcm283x_pwm= bcm283x_pwm .endif SUBDIR+=${MODULES_EXTRA} .for reject in ${WITHOUT_MODULES} SUBDIR:= ${SUBDIR:N${reject}} .endfor # Calling kldxref(8) for each module is expensive. .if !defined(NO_XREF) .MAKEFLAGS+= -DNO_XREF afterinstall: .PHONY @if type kldxref >/dev/null 2>&1; then \ ${ECHO} kldxref ${DESTDIR}${KMODDIR}; \ kldxref ${DESTDIR}${KMODDIR}; \ fi .endif .include "${SYSDIR}/conf/config.mk" SUBDIR:= ${SUBDIR:u:O} .include Index: head/sys/modules/smartpqi/Makefile =================================================================== --- head/sys/modules/smartpqi/Makefile (nonexistent) +++ head/sys/modules/smartpqi/Makefile (revision 333019) @@ -0,0 +1,12 @@ +# 5/10/2017 +# $FreeBSD$ + +KMOD = smartpqi + +.PATH: ${.CURDIR}/../../dev/${KMOD} + +SRCS=smartpqi_mem.c smartpqi_intr.c smartpqi_main.c smartpqi_cam.c smartpqi_ioctl.c smartpqi_misc.c smartpqi_sis.c smartpqi_init.c smartpqi_queue.c smartpqi_tag.c smartpqi_cmd.c smartpqi_request.c smartpqi_response.c smartpqi_event.c smartpqi_helper.c smartpqi_discovery.c + +SRCS+= device_if.h bus_if.h pci_if.h opt_scsi.h opt_cam.h + +.include Property changes on: head/sys/modules/smartpqi/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property