PERFORCE change 115634 for review
John Baldwin
jhb at FreeBSD.org
Fri Mar 9 22:52:20 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=115634
Change 115634 by jhb at 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) <<<
More information about the p4-projects
mailing list