Date: Fri, 9 Mar 2007 22:52:18 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 115634 for review Message-ID: <200703092252.l29MqIL3065028@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=115634 Change 115634 by jhb@jhb_zion on 2007/03/09 22:52:10 IFC @115633. Affected files ... .. //depot/projects/smpng/sys/amd64/amd64/mptable.c#11 integrate .. //depot/projects/smpng/sys/amd64/amd64/trap.c#58 integrate .. //depot/projects/smpng/sys/conf/files.sparc64#62 integrate .. //depot/projects/smpng/sys/dev/ata/ata-all.h#51 integrate .. //depot/projects/smpng/sys/dev/ata/ata-chipset.c#79 integrate .. //depot/projects/smpng/sys/dev/ata/ata-pci.h#51 integrate .. //depot/projects/smpng/sys/dev/bge/if_bge.c#90 integrate .. //depot/projects/smpng/sys/dev/bge/if_bgereg.h#53 integrate .. //depot/projects/smpng/sys/dev/fb/creator.c#12 integrate .. //depot/projects/smpng/sys/dev/mxge/eth_z8e.dat.gz.uu#4 integrate .. //depot/projects/smpng/sys/dev/mxge/ethp_z8e.dat.gz.uu#4 integrate .. //depot/projects/smpng/sys/dev/sound/pci/maestro3.c#24 integrate .. //depot/projects/smpng/sys/i386/i386/mptable.c#19 integrate .. //depot/projects/smpng/sys/i386/i386/trap.c#105 integrate .. //depot/projects/smpng/sys/ia64/ia64/trap.c#92 integrate .. //depot/projects/smpng/sys/kern/kern_clock.c#55 integrate .. //depot/projects/smpng/sys/kern/kern_jail.c#47 integrate .. //depot/projects/smpng/sys/kern/kern_kse.c#36 integrate .. //depot/projects/smpng/sys/kern/kern_lock.c#59 integrate .. //depot/projects/smpng/sys/kern/kern_mutex.c#143 integrate .. //depot/projects/smpng/sys/kern/kern_rwlock.c#11 integrate .. //depot/projects/smpng/sys/kern/kern_sx.c#43 integrate .. //depot/projects/smpng/sys/kern/kern_synch.c#114 integrate .. //depot/projects/smpng/sys/kern/kern_thread.c#99 integrate .. //depot/projects/smpng/sys/kern/sched_core.c#7 integrate .. //depot/projects/smpng/sys/kern/sched_ule.c#75 integrate .. //depot/projects/smpng/sys/kern/subr_prf.c#51 integrate .. //depot/projects/smpng/sys/kern/subr_smp.c#44 integrate .. //depot/projects/smpng/sys/kern/vfs_bio.c#101 integrate .. //depot/projects/smpng/sys/net/bridgestp.c#19 integrate .. //depot/projects/smpng/sys/net/bridgestp.h#8 integrate .. //depot/projects/smpng/sys/net/if_bridge.c#44 integrate .. //depot/projects/smpng/sys/netgraph/ng_base.c#46 integrate .. //depot/projects/smpng/sys/netgraph/ng_eiface.c#26 integrate .. //depot/projects/smpng/sys/netinet/tcp_input.c#97 integrate .. //depot/projects/smpng/sys/netinet/udp_usrreq.c#75 integrate .. //depot/projects/smpng/sys/nfsclient/nfs_socket.c#50 integrate .. //depot/projects/smpng/sys/nfsclient/nfs_subs.c#30 integrate .. //depot/projects/smpng/sys/nfsclient/nfs_vnops.c#65 integrate .. //depot/projects/smpng/sys/nfsclient/nfsnode.h#19 integrate .. //depot/projects/smpng/sys/powerpc/powerpc/trap.c#61 integrate .. //depot/projects/smpng/sys/sparc64/central/central.c#8 integrate .. //depot/projects/smpng/sys/sparc64/fhc/fhc.c#9 integrate .. //depot/projects/smpng/sys/sparc64/fhc/fhc_central.c#8 delete .. //depot/projects/smpng/sys/sparc64/fhc/fhc_nexus.c#8 delete .. //depot/projects/smpng/sys/sparc64/fhc/fhcvar.h#5 delete .. //depot/projects/smpng/sys/sparc64/include/bus_private.h#7 integrate .. //depot/projects/smpng/sys/sparc64/include/iommureg.h#7 integrate .. //depot/projects/smpng/sys/sparc64/include/nexusvar.h#4 delete .. //depot/projects/smpng/sys/sparc64/include/ofw_nexus.h#3 integrate .. //depot/projects/smpng/sys/sparc64/include/ofw_upa.h#5 delete .. //depot/projects/smpng/sys/sparc64/pci/psycho.c#42 integrate .. //depot/projects/smpng/sys/sparc64/pci/psychovar.h#14 integrate .. //depot/projects/smpng/sys/sparc64/sbus/sbus.c#28 integrate .. //depot/projects/smpng/sys/sparc64/sparc64/bus_machdep.c#30 integrate .. //depot/projects/smpng/sys/sparc64/sparc64/iommu.c#30 integrate .. //depot/projects/smpng/sys/sparc64/sparc64/nexus.c#17 integrate .. //depot/projects/smpng/sys/sparc64/sparc64/sc_machdep.c#3 integrate .. //depot/projects/smpng/sys/sparc64/sparc64/trap.c#76 integrate .. //depot/projects/smpng/sys/sys/buf.h#46 integrate .. //depot/projects/smpng/sys/sys/lock.h#43 integrate .. //depot/projects/smpng/sys/sys/mutex.h#70 integrate .. //depot/projects/smpng/sys/sys/param.h#112 integrate .. //depot/projects/smpng/sys/sys/proc.h#178 integrate .. //depot/projects/smpng/sys/sys/rwlock.h#7 integrate .. //depot/projects/smpng/sys/sys/sleepqueue.h#11 integrate .. //depot/projects/smpng/sys/sys/sx.h#23 integrate .. //depot/projects/smpng/sys/sys/systm.h#81 integrate Differences ... ==== //depot/projects/smpng/sys/amd64/amd64/mptable.c#11 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable.c,v 1.238 2007/03/05 20:35:16 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable.c,v 1.239 2007/03/09 15:49:57 jhb Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -316,18 +316,20 @@ static int mptable_setup_local(void) { + vm_paddr_t addr; /* Is this a pre-defined config? */ printf("MPTable: <"); if (mpfps->config_type != 0) { - lapic_init(DEFAULT_APIC_BASE); + addr = DEFAULT_APIC_BASE; printf("Default Configuration %d", mpfps->config_type); } else { - lapic_init(mpct->apic_address); + addr = mpct->apic_address; printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id, (int)sizeof(mpct->product_id), mpct->product_id); } printf(">\n"); + lapic_init(addr); return (0); } ==== //depot/projects/smpng/sys/amd64/amd64/trap.c#58 (text+ko) ==== @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.313 2006/12/17 06:48:39 kmacy Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.314 2007/03/09 04:02:36 mohans Exp $"); /* * AMD64 Trap and System call handling @@ -813,6 +813,8 @@ CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td, td->td_proc->p_pid, td->td_proc->p_comm, code); + td->td_syscalls++; + if (error == 0) { td->td_retval[0] = 0; td->td_retval[1] = frame->tf_rdx; ==== //depot/projects/smpng/sys/conf/files.sparc64#62 (text+ko) ==== @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $FreeBSD: src/sys/conf/files.sparc64,v 1.87 2007/01/20 12:53:30 marius Exp $ +# $FreeBSD: src/sys/conf/files.sparc64,v 1.88 2007/03/07 21:13:49 marius Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -80,8 +80,6 @@ sparc64/ebus/ebus.c optional ebus sparc64/fhc/clkbrd.c optional clkbrd fhc sparc64/fhc/fhc.c optional fhc -sparc64/fhc/fhc_central.c optional fhc central -sparc64/fhc/fhc_nexus.c optional fhc sparc64/isa/isa.c optional isa sparc64/isa/isa_dma.c optional isa sparc64/isa/ofw_isa.c optional ebus | isa ==== //depot/projects/smpng/sys/dev/ata/ata-all.h#51 (text+ko) ==== @@ -23,7 +23,7 @@ * (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: src/sys/dev/ata/ata-all.h,v 1.120 2007/02/21 19:07:18 sos Exp $ + * $FreeBSD: src/sys/dev/ata/ata-all.h,v 1.121 2007/03/08 16:39:25 sos Exp $ */ /* ATA register defines */ @@ -491,6 +491,7 @@ #define ATA_ATA_SLAVE 0x02 #define ATA_ATAPI_MASTER 0x04 #define ATA_ATAPI_SLAVE 0x08 +#define ATA_PORTMULTIPLIER 0x10 struct mtx state_mtx; /* state lock */ int state; /* ATA channel state */ ==== //depot/projects/smpng/sys/dev/ata/ata-chipset.c#79 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-chipset.c,v 1.186 2007/03/01 21:18:27 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-chipset.c,v 1.190 2007/03/09 22:23:39 sos Exp $"); #include "opt_ata.h" #include <sys/param.h> @@ -55,10 +55,12 @@ static int ata_generic_chipinit(device_t dev); static void ata_generic_intr(void *data); static void ata_generic_setmode(device_t dev, int mode); -static void ata_sata_phy_reset(device_t dev); +static void ata_sata_phy_check_events(device_t dev); static void ata_sata_phy_event(void *context, int dummy); +static int ata_sata_phy_reset(device_t dev); static int ata_sata_connect(struct ata_channel *ch); static void ata_sata_setmode(device_t dev, int mode); +static int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis); static int ata_ahci_chipinit(device_t dev); static int ata_ahci_allocate(device_t dev); static int ata_ahci_status(device_t dev); @@ -97,6 +99,7 @@ static int ata_intel_31244_allocate(device_t dev); static int ata_intel_31244_status(device_t dev); static int ata_intel_31244_command(struct ata_request *request); +static void ata_intel_31244_reset(device_t dev); static int ata_ite_chipinit(device_t dev); static void ata_ite_setmode(device_t dev, int mode); static int ata_jmicron_chipinit(device_t dev); @@ -122,6 +125,7 @@ static int ata_nvidia_chipinit(device_t dev); static int ata_nvidia_allocate(device_t dev); static int ata_nvidia_status(device_t dev); +static void ata_nvidia_reset(device_t dev); static int ata_promise_chipinit(device_t dev); static int ata_promise_allocate(device_t dev); static int ata_promise_status(device_t dev); @@ -155,8 +159,16 @@ static int ata_sii_status(device_t dev); static void ata_sii_reset(device_t dev); static void ata_sii_setmode(device_t dev, int mode); +static int ata_siiprb_allocate(device_t dev); +static int ata_siiprb_status(device_t dev); +static int ata_siiprb_begin_transaction(struct ata_request *request); +static int ata_siiprb_end_transaction(struct ata_request *request); +static void ata_siiprb_reset(device_t dev); +static void ata_siiprb_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); +static void ata_siiprb_dmainit(device_t dev); static int ata_sis_chipinit(device_t dev); static int ata_sis_allocate(device_t dev); +static void ata_sis_reset(device_t dev); static void ata_sis_setmode(device_t dev, int mode); static int ata_via_chipinit(device_t dev); static int ata_via_allocate(device_t dev); @@ -227,34 +239,39 @@ * SATA support functions */ static void -ata_sata_phy_reset(device_t dev) +ata_sata_phy_check_events(device_t dev) { struct ata_channel *ch = device_get_softc(dev); - int loop, retry; + u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR); + + /* clear error bits/interrupt */ + ATA_IDX_OUTL(ch, ATA_SERROR, error); + + /* do we have any events flagged ? */ + if (error) { + struct ata_connect_task *tp; + u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS); - if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) { - ata_sata_connect(ch); - return; - } + /* if we have a connection event deal with it */ + if ((error & ATA_SE_PHY_CHANGED) && + (tp = (struct ata_connect_task *) + malloc(sizeof(struct ata_connect_task), + M_ATA, M_NOWAIT | M_ZERO))) { - for (retry = 0; retry < 10; retry++) { - for (loop = 0; loop < 10; loop++) { - ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET); - ata_udelay(100); - if ((ATA_IDX_INL(ch, ATA_SCONTROL) & - ATA_SC_DET_MASK) == ATA_SC_DET_RESET) - break; - } - ata_udelay(5000); - for (loop = 0; loop < 10; loop++) { - ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_IDLE | - ATA_SC_IPM_DIS_PARTIAL | - ATA_SC_IPM_DIS_SLUMBER); - ata_udelay(100); - if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 0) { - ata_sata_connect(ch); - return; + if (((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) || + ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)) { + if (bootverbose) + device_printf(ch->dev, "CONNECT requested\n"); + tp->action = ATA_C_ATTACH; + } + else { + if (bootverbose) + device_printf(ch->dev, "DISCONNECT requested\n"); + tp->action = ATA_C_DETACH; } + tp->dev = ch->dev; + TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); + taskqueue_enqueue(taskqueue_thread, &tp->task); } } } @@ -271,7 +288,7 @@ if (tp->action == ATA_C_ATTACH) { if (bootverbose) device_printf(tp->dev, "CONNECTED\n"); - ata_sata_connect(ch); + ATA_RESET(tp->dev); ata_identify(tp->dev); } if (tp->action == ATA_C_DETACH) { @@ -292,6 +309,36 @@ } static int +ata_sata_phy_reset(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + int loop, retry; + + if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) + return ata_sata_connect(ch); + + for (retry = 0; retry < 10; retry++) { + for (loop = 0; loop < 10; loop++) { + ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET); + ata_udelay(100); + if ((ATA_IDX_INL(ch, ATA_SCONTROL) & + ATA_SC_DET_MASK) == ATA_SC_DET_RESET) + break; + } + ata_udelay(5000); + for (loop = 0; loop < 10; loop++) { + ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_IDLE | + ATA_SC_IPM_DIS_PARTIAL | + ATA_SC_IPM_DIS_SLUMBER); + ata_udelay(100); + if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 0) + return ata_sata_connect(ch); + } + } + return 0; +} + +static int ata_sata_connect(struct ata_channel *ch) { u_int32_t status; @@ -310,37 +357,12 @@ device_printf(ch->dev, "SATA connect status=%08x\n", status); return 0; } + if (bootverbose) + device_printf(ch->dev, "SATA connect time=%dms\n", timeout * 10); /* clear SATA error register */ ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR)); - /* poll 31 seconds for device ready */ - /* XXX SOS 10 secs for now as I have little patience */ - for (timeout = 0; timeout < 1000; timeout++) { - if (ATA_IDX_INB(ch, ATA_STATUS) & ATA_S_BUSY) - DELAY(10000); - else - break; - } - if (bootverbose) - device_printf(ch->dev, "SATA connect ready time=%dms\n", timeout * 10); - - /* if we have legacy resources an old fashioned reset might be needed */ - if (ch->r_io[ATA_DATA].res) - ata_generic_reset(ch->dev); - - /* register device type from signature */ - ch->devices = 0; - if (timeout < 1000) { - if ((ATA_IDX_INB(ch, ATA_CYL_LSB) == ATAPI_MAGIC_LSB) && - (ATA_IDX_INB(ch, ATA_CYL_MSB) == ATAPI_MAGIC_MSB)) - ch->devices = ATA_ATAPI_MASTER; - else - ch->devices = ATA_ATA_MASTER; - } - if (bootverbose) - device_printf(ch->dev, "sata_connect devices=0x%b\n", - ch->devices, "\20\3ATAPI_MASTER\1ATA_MASTER"); return 1; } @@ -378,6 +400,49 @@ } } +static int +ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis) +{ + struct ata_device *atadev = device_get_softc(request->dev); + + if (request->flags & ATA_R_ATAPI) { + fis[0] = 0x27; /* host to device */ + fis[1] = 0x80; /* command FIS (note PM goes here) */ + fis[2] = ATA_PACKET_CMD; + if (request->flags & ATA_R_DMA) + fis[3] = ATA_F_DMA; + else { + fis[5] = request->transfersize; + fis[6] = request->transfersize >> 8; + } + fis[7] = ATA_D_LBA | atadev->unit; + fis[15] = ATA_A_4BIT; + return 20; + } + else { + ata_modify_if_48bit(request); + fis[0] = 0x27; /* host to device */ + fis[1] = 0x80; /* command FIS (note PM goes here) */ + fis[2] = request->u.ata.command; + fis[3] = request->u.ata.feature; + fis[4] = request->u.ata.lba; + fis[5] = request->u.ata.lba >> 8; + fis[6] = request->u.ata.lba >> 16; + fis[7] = ATA_D_LBA | atadev->unit; + if (!(atadev->flags & ATA_D_48BIT_ACTIVE)) + fis[7] |= (request->u.ata.lba >> 24 & 0x0f); + fis[8] = request->u.ata.lba >> 24; + fis[9] = request->u.ata.lba >> 32; + fis[10] = request->u.ata.lba >> 40; + fis[11] = request->u.ata.feature >> 8; + fis[12] = request->u.ata.count; + fis[13] = request->u.ata.count >> 8; + fis[15] = ATA_A_4BIT; + return 20; + } + return 0; +} + /* * AHCI v1.x compliant SATA chipset support functions @@ -440,17 +505,6 @@ struct ata_channel *ch = device_get_softc(dev); int offset = ch->unit << 7; - /* setup legacy cruft we need */ - ch->r_io[ATA_DATA].res = NULL; - ch->r_io[ATA_CYL_LSB].res = ctlr->r_res2; - ch->r_io[ATA_CYL_LSB].offset = ATA_AHCI_P_SIG + 2 + offset; - ch->r_io[ATA_CYL_MSB].res = ctlr->r_res2; - ch->r_io[ATA_CYL_MSB].offset = ATA_AHCI_P_SIG + 3 + offset; - ch->r_io[ATA_STATUS].res = ctlr->r_res2; - ch->r_io[ATA_STATUS].offset = ATA_AHCI_P_TFD + offset; - ch->r_io[ATA_ALTSTAT].res = ctlr->r_res2; - ch->r_io[ATA_ALTSTAT].offset = ATA_AHCI_P_TFD + offset; - /* set the SATA resources */ ch->r_io[ATA_SSTATUS].res = ctlr->r_res2; ch->r_io[ATA_SSTATUS].offset = ATA_AHCI_P_SSTS + offset; @@ -495,62 +549,22 @@ { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); - struct ata_connect_task *tp; - u_int32_t action, istatus, sstatus, error, issued; + u_int32_t action = ATA_INL(ctlr->r_res2, ATA_AHCI_IS); int offset = ch->unit << 7; int tag = 0; - action = ATA_INL(ctlr->r_res2, ATA_AHCI_IS); if (action & (1 << ch->unit)) { - istatus = ATA_INL(ctlr->r_res2, ATA_AHCI_P_IS + offset); - issued = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CI + offset); - sstatus = ATA_INL(ctlr->r_res2, ATA_AHCI_P_SSTS + offset); - error = ATA_INL(ctlr->r_res2, ATA_AHCI_P_SERR + offset); + u_int32_t istatus = ATA_INL(ctlr->r_res2, ATA_AHCI_P_IS + offset); /* clear interrupt(s) */ - ATA_OUTL(ctlr->r_res2, ATA_AHCI_IS, action); + ATA_OUTL(ctlr->r_res2, ATA_AHCI_IS, action & (1 << ch->unit)); ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IS + offset, istatus); - ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_SERR + offset, error); - /* do we have cold connect surprise */ - if (istatus & ATA_AHCI_P_IX_CPD) { - printf("ata_ahci_status status=%08x sstatus=%08x error=%08x\n", - istatus, sstatus, error); - } - - /* check for and handle connect events */ - if ((istatus & ATA_AHCI_P_IX_PC) && - (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { - - if (bootverbose) - device_printf(ch->dev, "CONNECT requested\n"); - tp->action = ATA_C_ATTACH; - tp->dev = ch->dev; - TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); - taskqueue_enqueue(taskqueue_thread, &tp->task); - } - - /* check for and handle disconnect events */ - else if ((istatus & ATA_AHCI_P_IX_PRC) && - !((sstatus & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 || - (sstatus & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2) && - (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { - - if (bootverbose) - device_printf(ch->dev, "DISCONNECT requested\n"); - tp->action = ATA_C_DETACH; - tp->dev = ch->dev; - TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); - taskqueue_enqueue(taskqueue_thread, &tp->task); - } + /* do we have any PHY events ? */ + ata_sata_phy_check_events(dev); /* do we have any device action ? */ - if (!(issued & (1 << tag))) - return 1; + return (!(ATA_INL(ctlr->r_res2, ATA_AHCI_P_CI + offset) & (1 << tag))); } return 0; } @@ -667,8 +681,9 @@ if (!(ATA_INL(ctlr->r_res2, ATA_AHCI_PI) & (1 << ch->unit))) { device_printf(dev, "port not implemented\n"); - ch->devices = 0; + return; } + ch->devices = 0; /* kill off all activity on this channel */ cmd = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset); @@ -704,12 +719,22 @@ ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, ATA_AHCI_P_CMD_SUD); /* enable interface */ - ata_sata_phy_reset(dev); - - /* no ATAPI yet */ - if (ch->devices & ATA_ATAPI_MASTER) { - device_printf(ch->dev, "AHCI SATA ATAPI devices not supported yet\n"); - ch->devices = 0; + if (ata_sata_phy_reset(dev)) { + switch (ATA_INL(ctlr->r_res2, ATA_AHCI_P_SIG + offset)) { + case 0xeb140101: + ch->devices = ATA_ATAPI_MASTER; + device_printf(ch->dev, "SATA ATAPI devices not supported yet\n"); + ch->devices = 0; + break; + case 0x96690101: + ch->devices = ATA_PORTMULTIPLIER; + device_printf(ch->dev, "Portmultipliers not supported yet\n"); + ch->devices = 0; + break; + case 0x00000101: + ch->devices = ATA_ATA_MASTER; + break; + } } /* clear any interrupts pending on this channel */ @@ -754,47 +779,12 @@ static int ata_ahci_setup_fis(struct ata_ahci_cmd_tab *ctp, struct ata_request *request) { - struct ata_device *atadev = device_get_softc(request->dev); - bzero(ctp->cfis, 64); if (request->flags & ATA_R_ATAPI) { - ctp->cfis[0] = 0x27; /* host to device */ - ctp->cfis[1] = 0x80; /* command FIS (note PM goes here) */ - ctp->cfis[2] = ATA_PACKET_CMD; - if (request->flags & ATA_R_DMA) - ctp->cfis[3] = ATA_F_DMA; - else { - ctp->cfis[5] = request->transfersize; - ctp->cfis[6] = request->transfersize >> 8; - } - ctp->cfis[7] = ATA_D_LBA | atadev->unit; - ctp->cfis[15] = ATA_A_4BIT; bzero(ctp->acmd, 32); bcopy(request->u.atapi.ccb, ctp->acmd, 12); - return 20; } - else { - ata_modify_if_48bit(request); - ctp->cfis[0] = 0x27; /* host to device */ - ctp->cfis[1] = 0x80; /* command FIS (note PM goes here) */ - ctp->cfis[2] = request->u.ata.command; - ctp->cfis[3] = request->u.ata.feature; - ctp->cfis[4] = request->u.ata.lba; - ctp->cfis[5] = request->u.ata.lba >> 8; - ctp->cfis[6] = request->u.ata.lba >> 16; - ctp->cfis[7] = ATA_D_LBA | atadev->unit; - if (!(atadev->flags & ATA_D_48BIT_ACTIVE)) - ctp->cfis[7] |= (request->u.ata.lba >> 24 & 0x0f); - ctp->cfis[8] = request->u.ata.lba >> 24; - ctp->cfis[9] = request->u.ata.lba >> 32; - ctp->cfis[10] = request->u.ata.lba >> 40; - ctp->cfis[11] = request->u.ata.feature >> 8; - ctp->cfis[12] = request->u.ata.count; - ctp->cfis[13] = request->u.ata.count >> 8; - ctp->cfis[15] = ATA_A_4BIT; - return 20; - } - return 0; + return ata_request2fis_h2d(request, &ctp->cfis[0]); } @@ -1362,6 +1352,7 @@ } } + /* * Cyrix chipset support functions */ @@ -1751,7 +1742,7 @@ return ENXIO; ctlr->channels = 4; ctlr->allocate = ata_intel_31244_allocate; - ctlr->reset = ata_sata_phy_reset; + ctlr->reset = ata_intel_31244_reset; } ctlr->setmode = ata_sata_setmode; } @@ -1978,37 +1969,8 @@ static int ata_intel_31244_status(device_t dev) { - struct ata_channel *ch = device_get_softc(dev); - u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS); - u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR); - struct ata_connect_task *tp; - - /* check for PHY related interrupts on SATA capable HW */ - if (error) { - /* clear error bits/interrupt */ - ATA_IDX_OUTL(ch, ATA_SERROR, error); - - /* if we have a connection event deal with it */ - if ((error & ATA_SE_PHY_CHANGED) && - (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { - - if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) { - if (bootverbose) - device_printf(ch->dev, "CONNECT requested\n"); - tp->action = ATA_C_ATTACH; - } - else { - if (bootverbose) - device_printf(ch->dev, "DISCONNECT requested\n"); - tp->action = ATA_C_DETACH; - } - tp->dev = ch->dev; - TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); - taskqueue_enqueue(taskqueue_thread, &tp->task); - } - } + /* do we have any PHY events ? */ + ata_sata_phy_check_events(dev); /* any drive action to take care of ? */ return ata_pci_status(dev); @@ -2042,6 +2004,13 @@ return 0; } +static void +ata_intel_31244_reset(device_t dev) +{ + if (ata_sata_phy_reset(dev)) + ata_generic_reset(dev); +} + /* * Integrated Technology Express Inc. (ITE) chipset support functions @@ -2541,45 +2510,13 @@ u_int32_t cause = ATA_INL(ctlr->r_res1, 0x01d60); int shift = (ch->unit << 1) + (ch->unit > 3); - /* do we have any errors flagged ? */ if (cause & (1 << shift)) { - struct ata_connect_task *tp; - u_int32_t error = - ATA_INL(ctlr->r_res1, 0x02008 + ATA_MV_EDMA_BASE(ch)); - /* check for and handle disconnect events */ - if ((error & 0x00000008) && - (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { + /* clear interrupt(s) */ + ATA_OUTL(ctlr->r_res1, 0x02008 + ATA_MV_EDMA_BASE(ch), 0x0); - if (bootverbose) - device_printf(ch->dev, "DISCONNECT requested\n"); - tp->action = ATA_C_DETACH; - tp->dev = ch->dev; - TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); - taskqueue_enqueue(taskqueue_thread, &tp->task); - } - - /* check for and handle connect events */ - if ((error & 0x00000010) && - (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { - - if (bootverbose) - device_printf(ch->dev, "CONNECT requested\n"); - tp->action = ATA_C_ATTACH; - tp->dev = ch->dev; - TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); - taskqueue_enqueue(taskqueue_thread, &tp->task); - } - - /* clear SATA error register */ - ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR)); - - /* clear any outstanding error interrupts */ - ATA_OUTL(ctlr->r_res1, 0x02008 + ATA_MV_EDMA_BASE(ch), 0x0); + /* do we have any PHY events ? */ + ata_sata_phy_check_events(dev); } /* do we have any device action ? */ @@ -2694,9 +2631,6 @@ u_int32_t rsp_in, rsp_out; int slot; - /* unload SG list */ - ch->dma->unload(ch->dev); - /* stop timeout */ callout_stop(&request->callout); @@ -2720,6 +2654,10 @@ if (!(request->status & ATA_S_ERROR) && !(request->flags & ATA_R_TIMEOUT)) request->donecount = request->bytecount; + + /* unload SG list */ + ch->dma->unload(ch->dev); + res = ATA_OP_FINISHED; } @@ -2754,7 +2692,8 @@ ATA_OUTL(ctlr->r_res1, 0x0200c + ATA_MV_EDMA_BASE(ch), ~0x0); /* enable channel and test for devices */ - ata_sata_phy_reset(dev); + if (ata_sata_phy_reset(dev)) + ata_generic_reset(dev); /* enable EDMA machinery */ ATA_OUTL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch), 0x00000001); @@ -2773,8 +2712,8 @@ for (i = 0; i < nsegs; i++) { prd[i].addrlo = htole32(segs[i].ds_addr); - prd[i].addrhi = 0; prd[i].count = htole32(segs[i].ds_len); + prd[i].addrhi = htole32((u_int64_t)segs[i].ds_addr >> 32); } prd[i - 1].count |= htole32(ATA_DMA_EOT); } @@ -2866,6 +2805,7 @@ } } + /* * NetCell chipset support functions */ @@ -2909,6 +2849,7 @@ return 0; } + /* * nVidia chipset support functions */ @@ -2971,7 +2912,7 @@ int offset = ctlr->chip->cfg2 & NV4 ? 0x0440 : 0x0010; ctlr->allocate = ata_nvidia_allocate; - ctlr->reset = ata_sata_phy_reset; + ctlr->reset = ata_nvidia_reset; /* enable control access */ pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 1) | 0x04,1); @@ -3039,51 +2980,26 @@ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); int offset = ctlr->chip->cfg2 & NV4 ? 0x0440 : 0x0010; - struct ata_connect_task *tp; int shift = ch->unit << (ctlr->chip->cfg2 & NVQ ? 4 : 2); - u_int32_t status; + u_int32_t istatus = ATA_INL(ctlr->r_res2, offset); - /* get and clear interrupt status */ - if (ctlr->chip->cfg2 & NVQ) { - status = ATA_INL(ctlr->r_res2, offset); - ATA_OUTL(ctlr->r_res2, offset, (0x0f << shift) | 0x00f000f0); - } - else { - status = ATA_INB(ctlr->r_res2, offset); - ATA_OUTB(ctlr->r_res2, offset, (0x0f << shift)); - } + /* do we have any PHY events ? */ + if (istatus & (0x0c << shift)) + ata_sata_phy_check_events(dev); - /* check for and handle connect events */ - if (((status & (0x0c << shift)) == (0x04 << shift)) && - (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { + /* clear interrupt(s) */ + ATA_OUTB(ctlr->r_res2, offset, + (0x0f << shift) | (ctlr->chip->cfg2 & NVQ ? 0x00f000f0 : 0)); - if (bootverbose) - device_printf(ch->dev, "CONNECT requested\n"); - tp->action = ATA_C_ATTACH; - tp->dev = ch->dev; - TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); - taskqueue_enqueue(taskqueue_thread, &tp->task); - } + /* do we have any device action ? */ + return (istatus & (0x01 << shift)); +} - /* check for and handle disconnect events */ - if ((status & (0x08 << shift)) && - !((status & (0x04 << shift) && ATA_IDX_INL(ch, ATA_SSTATUS))) && - (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { - - if (bootverbose) - device_printf(ch->dev, "DISCONNECT requested\n"); - tp->action = ATA_C_DETACH; - tp->dev = ch->dev; - TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); - taskqueue_enqueue(taskqueue_thread, &tp->task); - } - - /* do we have any device action ? */ - return (status & (0x01 << shift)); +static void +ata_nvidia_reset(device_t dev) +{ + if (ata_sata_phy_reset(dev)) + ata_generic_reset(dev); } @@ -3755,7 +3671,8 @@ if ((ctlr->chip->cfg2 == PRSATA) || ((ctlr->chip->cfg2 == PRCMBO) && (ch->unit < 2))) { - ata_sata_phy_reset(dev); + if (ata_sata_phy_reset(dev)) + ata_generic_reset(dev); /* reset and enable plug/unplug intr */ ATA_OUTL(ctlr->r_res2, 0x06c, (0x00000011 << ch->unit)); @@ -3790,7 +3707,8 @@ (ATA_INL(ctlr->r_res2, 0x414 + (ch->unit << 8)) & ~0x00000003) | 0x00000001); - ata_sata_phy_reset(dev); + if (ata_sata_phy_reset(dev)) + ata_generic_reset(dev); /* reset and enable plug/unplug intr */ ATA_OUTL(ctlr->r_res2, 0x060, (0x00000011 << ch->unit)); @@ -4250,6 +4168,8 @@ { ATA_SII3512, 0x00, SIIMEMIO, SIIBUG, ATA_SA150, "SiI 3512" }, { ATA_SII3112, 0x00, SIIMEMIO, SIIBUG, ATA_SA150, "SiI 3112" }, { ATA_SII3112_1, 0x00, SIIMEMIO, SIIBUG, ATA_SA150, "SiI 3112" }, + { ATA_SII3124, 0x00, SIIPRBIO, SII4CH, ATA_SA300, "SiI 3124" }, + { ATA_SII3132, 0x00, SIIPRBIO, 0, ATA_SA300, "SiI 3132" }, { ATA_SII0680, 0x00, SIIMEMIO, SIISETCLK, ATA_UDMA6, "SiI 0680" }, { ATA_CMD649, 0x00, 0, SIIINTR, ATA_UDMA5, "CMD 649" }, { ATA_CMD648, 0x00, 0, SIIINTR, ATA_UDMA4, "CMD 648" }, @@ -4276,7 +4196,38 @@ if (ata_setup_interrupt(dev)) return ENXIO; - if (ctlr->chip->cfg1 == SIIMEMIO) { + switch (ctlr->chip->cfg1) { + case SIIPRBIO: + ctlr->r_type1 = SYS_RES_MEMORY; + ctlr->r_rid1 = PCIR_BAR(0); + if (!(ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1, + &ctlr->r_rid1, RF_ACTIVE))) + return ENXIO; + + ctlr->r_rid2 = PCIR_BAR(2); + ctlr->r_type2 = SYS_RES_MEMORY; + if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, + &ctlr->r_rid2, RF_ACTIVE))){ + bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1,ctlr->r_res1); + return ENXIO; + } + ctlr->allocate = ata_siiprb_allocate; + ctlr->reset = ata_siiprb_reset; + ctlr->dmainit = ata_siiprb_dmainit; + ctlr->setmode = ata_sata_setmode; + ctlr->channels = (ctlr->chip->cfg2 == SII4CH) ? 4 : 2; + + /* reset controller */ + ATA_OUTL(ctlr->r_res1, 0x0040, 0x80000000); + DELAY(10000); + ATA_OUTL(ctlr->r_res1, 0x0040, 0x0000000f); + + /* enable PCI interrupt */ + pci_write_config(dev, PCIR_COMMAND, + pci_read_config(dev, PCIR_COMMAND, 2) & ~0x0400, 2); + break; + + case SIIMEMIO: ctlr->r_type2 = SYS_RES_MEMORY; ctlr->r_rid2 = PCIR_BAR(5); if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, @@ -4298,13 +4249,13 @@ ctlr->channels = 4; } - /* enable PCI interrupt as BIOS might not */ - pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1); - /* dont block interrupts from any channel */ pci_write_config(dev, 0x48, (pci_read_config(dev, 0x48, 4) & ~0x03c00000), 4); + /* enable PCI interrupt as BIOS might not */ + pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1); + ctlr->allocate = ata_sii_allocate; if (ctlr->chip->max_dma >= ATA_SA150) { ctlr->reset = ata_sii_reset; @@ -4312,8 +4263,9 @@ } else ctlr->setmode = ata_sii_setmode; - } - else { + break; + + default: if ((pci_read_config(dev, 0x51, 1) & 0x08) != 0x08) { device_printf(dev, "HW has secondary channel disabled\n"); ctlr->channels = 1; @@ -4324,6 +4276,7 @@ ctlr->allocate = ata_cmd_allocate; ctlr->setmode = ata_cmd_setmode; + break; } return 0; } @@ -4437,8 +4390,6 @@ ch->r_io[ATA_BMSTAT_PORT].offset = 0x02 + (unit01 << 3) + (unit10 << 8); ch->r_io[ATA_BMDTP_PORT].res = ctlr->r_res2; ch->r_io[ATA_BMDTP_PORT].offset = 0x04 + (unit01 << 3) + (unit10 << 8); - ch->r_io[ATA_BMDEVSPEC_0].res = ctlr->r_res2; - ch->r_io[ATA_BMDEVSPEC_0].offset = 0xa1 + (unit01 << 6) + (unit10 << 8); if (ctlr->chip->max_dma >= ATA_SA150) { ch->r_io[ATA_SSTATUS].res = ctlr->r_res2; @@ -4469,68 +4420,25 @@ { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); + int offset0 = ((ch->unit & 1) << 3) + ((ch->unit & 2) << 8); + int offset1 = ((ch->unit & 1) << 6) + ((ch->unit & 2) << 8); - /* check for PHY related interrupts on SATA capable HW */ - if (ctlr->chip->max_dma >= ATA_SA150) { - u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS); - u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR); - struct ata_connect_task *tp; + /* do we have any PHY events ? */ + if (ctlr->chip->max_dma >= ATA_SA150 && + (ATA_INL(ctlr->r_res2, 0x10 + offset0) & 0x00000010)) + ata_sata_phy_check_events(dev); - if (error) { - /* clear error bits/interrupt */ - ATA_IDX_OUTL(ch, ATA_SERROR, error); - - /* if we have a connection event deal with it */ - if ((error & ATA_SE_PHY_CHANGED) && - (tp = (struct ata_connect_task *) >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703092252.l29MqIL3065028>