summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-12-06 00:10:13 +0000
committermav <mav@FreeBSD.org>2009-12-06 00:10:13 +0000
commit6a3018e7cff16ab166672e276b4b39154ad09739 (patch)
tree8def18d183a8f2ec2847c5ef06fe2fac081d798e /sys
parent9bb92ae41af45cc801f28a880e08648aad72e241 (diff)
downloadFreeBSD-src-6a3018e7cff16ab166672e276b4b39154ad09739.zip
FreeBSD-src-6a3018e7cff16ab166672e276b4b39154ad09739.tar.gz
MFp4:
Introduce ATA_CAM kernel option, turning ata(4) controller drivers into cam(4) interface modules. When enabled, this options deprecates all ata(4) peripheral drivers (ad, acd, ...) and interfaces and allows cam(4) drivers (ada, cd, ...) and interfaces to be natively used instead. As side effect of this, ata(4) mode setting code was completely rewritten to make controller API more strict and permit above change. While doing this, SATA revision was separated from PATA mode. It allows DMA-incapable SATA devices to operate and makes hw.ata.atapi_dma tunable work again. Also allow ata(4) controller drivers (except some specific or broken ones) to handle larger data transfers. Previous constraint of 64K was artificial and is not really required by PCI ATA BM specification or hardware. Submitted by: nwitehorn (powerpc part)
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/mv/mv_sata.c14
-rw-r--r--sys/cam/ata/ata_xpt.c76
-rw-r--r--sys/cam/scsi/scsi_cd.c8
-rw-r--r--sys/conf/NOTES6
-rw-r--r--sys/conf/options1
-rw-r--r--sys/dev/ata/ata-all.c571
-rw-r--r--sys/dev/ata/ata-all.h33
-rw-r--r--sys/dev/ata/ata-disk.c7
-rw-r--r--sys/dev/ata/ata-dma.c2
-rw-r--r--sys/dev/ata/ata-lowlevel.c9
-rw-r--r--sys/dev/ata/ata-pci.c68
-rw-r--r--sys/dev/ata/ata-pci.h7
-rw-r--r--sys/dev/ata/ata-queue.c11
-rw-r--r--sys/dev/ata/ata-sata.c45
-rw-r--r--sys/dev/ata/ata_if.m19
-rw-r--r--sys/dev/ata/atapi-cd.c12
-rw-r--r--sys/dev/ata/atapi-fd.c9
-rw-r--r--sys/dev/ata/atapi-tape.c12
-rw-r--r--sys/dev/ata/chipsets/ata-acard.c94
-rw-r--r--sys/dev/ata/chipsets/ata-acerlabs.c98
-rw-r--r--sys/dev/ata/chipsets/ata-ahci.c3
-rw-r--r--sys/dev/ata/chipsets/ata-amd.c69
-rw-r--r--sys/dev/ata/chipsets/ata-ati.c93
-rw-r--r--sys/dev/ata/chipsets/ata-cenatek.c30
-rw-r--r--sys/dev/ata/chipsets/ata-cypress.c31
-rw-r--r--sys/dev/ata/chipsets/ata-cyrix.c79
-rw-r--r--sys/dev/ata/chipsets/ata-highpoint.c91
-rw-r--r--sys/dev/ata/chipsets/ata-intel.c181
-rw-r--r--sys/dev/ata/chipsets/ata-ite.c209
-rw-r--r--sys/dev/ata/chipsets/ata-jmicron.c46
-rw-r--r--sys/dev/ata/chipsets/ata-marvell.c30
-rw-r--r--sys/dev/ata/chipsets/ata-micron.c33
-rw-r--r--sys/dev/ata/chipsets/ata-national.c74
-rw-r--r--sys/dev/ata/chipsets/ata-netcell.c17
-rw-r--r--sys/dev/ata/chipsets/ata-nvidia.c56
-rw-r--r--sys/dev/ata/chipsets/ata-promise.c68
-rw-r--r--sys/dev/ata/chipsets/ata-serverworks.c99
-rw-r--r--sys/dev/ata/chipsets/ata-siliconimage.c180
-rw-r--r--sys/dev/ata/chipsets/ata-sis.c71
-rw-r--r--sys/dev/ata/chipsets/ata-via.c123
-rw-r--r--sys/powerpc/powermac/ata_dbdma.c3
-rw-r--r--sys/powerpc/powermac/ata_kauai.c41
-rw-r--r--sys/powerpc/powermac/ata_macio.c40
-rw-r--r--sys/powerpc/psim/ata_iobus.c10
44 files changed, 1595 insertions, 1184 deletions
diff --git a/sys/arm/mv/mv_sata.c b/sys/arm/mv/mv_sata.c
index 3593956..7d0649b 100644
--- a/sys/arm/mv/mv_sata.c
+++ b/sys/arm/mv/mv_sata.c
@@ -136,7 +136,7 @@ static int sata_channel_detach(device_t dev);
static int sata_channel_begin_transaction(struct ata_request *request);
static int sata_channel_end_transaction(struct ata_request *request);
static int sata_channel_status(device_t dev);
-static void sata_channel_setmode(device_t parent, device_t dev);
+static int sata_channel_setmode(device_t dev, int target, int mode);
static void sata_channel_reset(device_t dev);
static void sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs,
int nsegs, int error);
@@ -748,19 +748,13 @@ sata_channel_reset(device_t dev)
SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
}
-static void
-sata_channel_setmode(device_t parent, device_t dev)
+static int
+sata_channel_setmode(device_t parent, int target, int mode)
{
- struct ata_device *atadev;
-
- atadev = device_get_softc(dev);
/* Disable EDMA before using legacy registers */
sata_edma_ctrl(parent, 0);
-
- ata_sata_setmode(dev, ATA_PIO_MAX);
- if (atadev->mode >= ATA_DMA)
- ata_sata_setmode(dev, atadev->mode);
+ return (ata_sata_setmode(dev, mode));
}
static void
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 89f5153..a1626235 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -366,7 +366,7 @@ negotiate:
cts.xport_specific.sata.valid = CTS_SATA_VALID_MODE;
}
xpt_action((union ccb *)&cts);
- /* Fetch user modes from SIM. */
+ /* Fetch current modes from SIM. */
bzero(&cts, sizeof(cts));
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
@@ -395,10 +395,25 @@ negotiate:
}
case PROBE_SET_MULTI:
{
- u_int sectors;
-
- sectors = max(1, min(ident_buf->sectors_intr & 0xff, 16));
+ u_int sectors, bytecount;
+ bytecount = 8192; /* SATA maximum */
+ /* Fetch user bytecount from SIM. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+ cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_USER_SETTINGS;
+ xpt_action((union ccb *)&cts);
+ if (path->device->transport == XPORT_ATA) {
+ if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
+ bytecount = cts.xport_specific.ata.bytecount;
+ } else {
+ if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
+ bytecount = cts.xport_specific.sata.bytecount;
+ }
+ /* Honor device capabilities. */
+ sectors = max(1, min(ident_buf->sectors_intr & 0xff,
+ bytecount / ata_logical_sector_size(ident_buf)));
/* Report bytecount to SIM. */
bzero(&cts, sizeof(cts));
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
@@ -414,6 +429,20 @@ negotiate:
cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
}
xpt_action((union ccb *)&cts);
+ /* Fetch current bytecount from SIM. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+ cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_CURRENT_SETTINGS;
+ xpt_action((union ccb *)&cts);
+ if (path->device->transport == XPORT_ATA) {
+ if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
+ bytecount = cts.xport_specific.ata.bytecount;
+ } else {
+ if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
+ bytecount = cts.xport_specific.sata.bytecount;
+ }
+ sectors = bytecount / ata_logical_sector_size(ident_buf);
cam_fill_ataio(ataio,
1,
@@ -427,6 +456,45 @@ negotiate:
break;
}
case PROBE_INQUIRY:
+ {
+ u_int bytecount;
+
+ bytecount = 8192; /* SATA maximum */
+ /* Fetch user bytecount from SIM. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+ cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_USER_SETTINGS;
+ xpt_action((union ccb *)&cts);
+ if (path->device->transport == XPORT_ATA) {
+ if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
+ bytecount = cts.xport_specific.ata.bytecount;
+ } else {
+ if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
+ bytecount = cts.xport_specific.sata.bytecount;
+ }
+ /* Honor device capabilities. */
+ bytecount &= ~1;
+ bytecount = max(2, min(65534, bytecount));
+ if (ident_buf->satacapabilities != 0x0000 &&
+ ident_buf->satacapabilities != 0xffff) {
+ bytecount = min(8192, bytecount);
+ }
+ /* Report bytecount to SIM. */
+ bzero(&cts, sizeof(cts));
+ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+ cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+ cts.type = CTS_TYPE_CURRENT_SETTINGS;
+ if (path->device->transport == XPORT_ATA) {
+ cts.xport_specific.ata.bytecount = bytecount;
+ cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT;
+ } else {
+ cts.xport_specific.sata.bytecount = bytecount;
+ cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
+ }
+ xpt_action((union ccb *)&cts);
+ /* FALLTHROUGH */
+ }
case PROBE_FULL_INQUIRY:
{
u_int inquiry_len;
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 2640de6..b740953 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -726,6 +726,12 @@ cdregister(struct cam_periph *periph, void *arg)
softc->disk->d_name = "cd";
softc->disk->d_unit = periph->unit_number;
softc->disk->d_drv1 = periph;
+ if (cpi.maxio == 0)
+ softc->disk->d_maxsize = DFLTPHYS; /* traditional default */
+ else if (cpi.maxio > MAXPHYS)
+ softc->disk->d_maxsize = MAXPHYS; /* for safety */
+ else
+ softc->disk->d_maxsize = cpi.maxio;
softc->disk->d_flags = 0;
disk_create(softc->disk, DISK_VERSION);
cam_periph_lock(periph);
@@ -2764,7 +2770,6 @@ cdcheckmedia(struct cam_periph *periph)
softc = (struct cd_softc *)periph->softc;
cdprevent(periph, PR_PREVENT);
- softc->disk->d_maxsize = DFLTPHYS;
softc->disk->d_sectorsize = 2048;
softc->disk->d_mediasize = 0;
@@ -2866,7 +2871,6 @@ cdcheckmedia(struct cam_periph *periph)
}
softc->flags |= CD_FLAG_VALID_TOC;
- softc->disk->d_maxsize = DFLTPHYS;
softc->disk->d_sectorsize = softc->params.blksize;
softc->disk->d_mediasize =
(off_t)softc->params.blksize * softc->params.disksize;
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 91091b0..54126fc 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1718,9 +1718,15 @@ hint.ata.1.irq="15"
# else the device numbers are dynamically allocated.
# ATA_REQUEST_TIMEOUT: the number of seconds to wait for an ATA request
# before timing out.
+# ATA_CAM: Turn ata(4) subsystem controller drivers into cam(4)
+# interface modules. This deprecates all ata(4)
+# peripheral device drivers (atadisk, ataraid, atapicd,
+# atapifd. atapist, atapicam) and all user-level APIs.
+# cam(4) drivers and APIs will be connected instead.
options ATA_STATIC_ID
#options ATA_REQUEST_TIMEOUT=10
+#options ATA_CAM
#
# Standard floppy disk controllers and floppy tapes, supports
diff --git a/sys/conf/options b/sys/conf/options
index 756d75d..75f69c2 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -351,6 +351,7 @@ ISCSI_INITIATOR_DEBUG opt_iscsi_initiator.h
ATA_STATIC_ID opt_ata.h
ATA_NOPCI opt_ata.h
ATA_REQUEST_TIMEOUT opt_ata.h
+ATA_CAM opt_ata.h
# Net stuff.
ACCEPT_FILTER_DATA
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index a1a6f27..fcedc2f 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -50,6 +50,16 @@ __FBSDID("$FreeBSD$");
#include <dev/ata/ata-all.h>
#include <ata_if.h>
+#ifdef ATA_CAM
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_sim.h>
+#include <cam/cam_xpt_sim.h>
+#include <cam/cam_xpt_periph.h>
+#include <cam/cam_debug.h>
+#endif
+
+#ifndef ATA_CAM
/* device structure */
static d_ioctl_t ata_ioctl;
static struct cdevsw ata_cdevsw = {
@@ -58,14 +68,21 @@ static struct cdevsw ata_cdevsw = {
.d_ioctl = ata_ioctl,
.d_name = "ata",
};
+#endif
/* prototypes */
+#ifndef ATA_CAM
static void ata_boot_attach(void);
static device_t ata_add_child(device_t, struct ata_device *, int);
+#else
+static void ataaction(struct cam_sim *sim, union ccb *ccb);
+static void atapoll(struct cam_sim *sim);
+#endif
static void ata_conn_event(void *, int);
static void bswap(int8_t *, int);
static void btrim(int8_t *, int);
static void bpack(int8_t *, int8_t *, int);
+static void ata_interrupt_locked(void *data);
/* global vars */
MALLOC_DEFINE(M_ATA, "ata_generic", "ATA driver generic layer");
@@ -115,6 +132,10 @@ ata_attach(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
int error, rid;
+#ifdef ATA_CAM
+ struct cam_devq *devq;
+ int i;
+#endif
/* check that we have a virgin channel to attach */
if (ch->r_irq)
@@ -129,11 +150,23 @@ ata_attach(device_t dev)
mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF);
TAILQ_INIT(&ch->ata_queue);
TASK_INIT(&ch->conntask, 0, ata_conn_event, dev);
+#ifdef ATA_CAM
+ for (i = 0; i < 16; i++) {
+ ch->user[i].mode = 0;
+ if (ch->flags & ATA_SATA)
+ ch->user[i].bytecount = 8192;
+ else
+ ch->user[i].bytecount = MAXPHYS;
+ ch->curr[i] = ch->user[i];
+ }
+#endif
/* reset the controller HW, the channel and device(s) */
while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
pause("ataatch", 1);
+#ifndef ATA_CAM
ATA_RESET(dev);
+#endif
ATA_LOCKING(dev, ATA_LF_UNLOCK);
/* allocate DMA resources if DMA HW present*/
@@ -154,18 +187,61 @@ ata_attach(device_t dev)
return error;
}
+#ifndef ATA_CAM
/* probe and attach devices on this channel unless we are in early boot */
if (!ata_delayed_attach)
ata_identify(dev);
- return 0;
+ return (0);
+#else
+ mtx_lock(&ch->state_mtx);
+ /* Create the device queue for our SIM. */
+ devq = cam_simq_alloc(1);
+ if (devq == NULL) {
+ device_printf(dev, "Unable to allocate simq\n");
+ error = ENOMEM;
+ goto err1;
+ }
+ /* Construct SIM entry */
+ ch->sim = cam_sim_alloc(ataaction, atapoll, "ata", ch,
+ device_get_unit(dev), &ch->state_mtx, 1, 0, devq);
+ if (ch->sim == NULL) {
+ device_printf(dev, "unable to allocate sim\n");
+ error = ENOMEM;
+ goto err2;
+ }
+ if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) {
+ device_printf(dev, "unable to register xpt bus\n");
+ error = ENXIO;
+ goto err2;
+ }
+ if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim),
+ CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+ device_printf(dev, "unable to create path\n");
+ error = ENXIO;
+ goto err3;
+ }
+ mtx_unlock(&ch->state_mtx);
+ return (0);
+
+err3:
+ xpt_bus_deregister(cam_sim_path(ch->sim));
+err2:
+ cam_sim_free(ch->sim, /*free_devq*/TRUE);
+err1:
+ bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
+ mtx_unlock(&ch->state_mtx);
+ return (error);
+#endif
}
int
ata_detach(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
+#ifndef ATA_CAM
device_t *children;
int nchildren, i;
+#endif
/* check that we have a valid channel to detach */
if (!ch->r_irq)
@@ -176,6 +252,7 @@ ata_detach(device_t dev)
ch->state |= ATA_STALL_QUEUE;
mtx_unlock(&ch->state_mtx);
+#ifndef ATA_CAM
/* detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) {
for (i = 0; i < nchildren; i++)
@@ -183,8 +260,18 @@ ata_detach(device_t dev)
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
+#endif
taskqueue_drain(taskqueue_thread, &ch->conntask);
+#ifdef ATA_CAM
+ mtx_lock(&ch->state_mtx);
+ xpt_async(AC_LOST_DEVICE, ch->path, NULL);
+ xpt_free_path(ch->path);
+ xpt_bus_deregister(cam_sim_path(ch->sim));
+ cam_sim_free(ch->sim, /*free_devq*/TRUE);
+ mtx_unlock(&ch->state_mtx);
+#endif
+
/* release resources */
bus_teardown_intr(dev, ch->r_irq, ch->ih);
bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
@@ -203,8 +290,11 @@ static void
ata_conn_event(void *context, int dummy)
{
device_t dev = (device_t)context;
+ struct ata_channel *ch = device_get_softc(dev);
+ mtx_lock(&ch->state_mtx);
ata_reinit(dev);
+ mtx_unlock(&ch->state_mtx);
}
int
@@ -212,6 +302,7 @@ ata_reinit(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
struct ata_request *request;
+#ifndef ATA_CAM
device_t *children;
int nchildren, i;
@@ -298,7 +389,23 @@ ata_reinit(device_t dev)
/* kick off requests on the queue */
ata_start(dev);
- return 0;
+#else
+ if ((request = ch->running)) {
+ ch->running = NULL;
+ if (ch->state == ATA_ACTIVE)
+ ch->state = ATA_IDLE;
+ callout_stop(&request->callout);
+ if (ch->dma.unload)
+ ch->dma.unload(request);
+ request->result = ERESTART;
+ ata_cam_end_transaction(dev, request);
+ }
+ /* reset the controller HW, the channel and device(s) */
+ ATA_RESET(dev);
+ /* Tell the XPT about the event */
+ xpt_async(AC_BUS_RESET, ch->path, NULL);
+#endif
+ return(0);
}
int
@@ -310,6 +417,7 @@ ata_suspend(device_t dev)
if (!dev || !(ch = device_get_softc(dev)))
return ENXIO;
+#ifndef ATA_CAM
/* wait for the channel to be IDLE or detached before suspending */
while (ch->r_irq) {
mtx_lock(&ch->state_mtx);
@@ -322,7 +430,8 @@ ata_suspend(device_t dev)
tsleep(ch, PRIBIO, "atasusp", hz/10);
}
ATA_LOCKING(dev, ATA_LF_UNLOCK);
- return 0;
+#endif
+ return(0);
}
int
@@ -337,18 +446,36 @@ ata_resume(device_t dev)
/* reinit the devices, we dont know what mode/state they are in */
error = ata_reinit(dev);
+#ifndef ATA_CAM
/* kick off requests on the queue */
ata_start(dev);
+#endif
return error;
}
void
ata_interrupt(void *data)
{
+#ifdef ATA_CAM
+ struct ata_channel *ch = (struct ata_channel *)data;
+
+ mtx_lock(&ch->state_mtx);
+#endif
+ ata_interrupt_locked(data);
+#ifdef ATA_CAM
+ mtx_unlock(&ch->state_mtx);
+#endif
+}
+
+static void
+ata_interrupt_locked(void *data)
+{
struct ata_channel *ch = (struct ata_channel *)data;
struct ata_request *request;
+#ifndef ATA_CAM
mtx_lock(&ch->state_mtx);
+#endif
do {
/* ignore interrupt if its not for us */
if (ch->hw.status && !ch->hw.status(ch->dev))
@@ -374,18 +501,71 @@ ata_interrupt(void *data)
ch->running = NULL;
if (ch->state == ATA_ACTIVE)
ch->state = ATA_IDLE;
+#ifdef ATA_CAM
+ ata_cam_end_transaction(ch->dev, request);
+#else
mtx_unlock(&ch->state_mtx);
ATA_LOCKING(ch->dev, ATA_LF_UNLOCK);
ata_finish(request);
+#endif
return;
}
} while (0);
+#ifndef ATA_CAM
mtx_unlock(&ch->state_mtx);
+#endif
+}
+
+void
+ata_print_cable(device_t dev, u_int8_t *who)
+{
+ device_printf(dev,
+ "DMA limited to UDMA33, %s found non-ATA66 cable\n", who);
+}
+
+int
+ata_check_80pin(device_t dev, int mode)
+{
+ struct ata_device *atadev = device_get_softc(dev);
+
+ if (!ata_dma_check_80pin) {
+ if (bootverbose)
+ device_printf(dev, "Skipping 80pin cable check\n");
+ return mode;
+ }
+
+ if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) {
+ ata_print_cable(dev, "device");
+ mode = ATA_UDMA2;
+ }
+ return mode;
+}
+
+void
+ata_setmode(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+ struct ata_device *atadev = device_get_softc(dev);
+ int error, mode, pmode;
+
+ mode = atadev->mode;
+ do {
+ pmode = mode = ata_limit_mode(dev, mode, ATA_DMA_MAX);
+ mode = ATA_SETMODE(device_get_parent(dev), atadev->unit, mode);
+ if ((ch->flags & (ATA_CHECKS_CABLE | ATA_SATA)) == 0)
+ mode = ata_check_80pin(dev, mode);
+ } while (pmode != mode); /* Interate till successfull negotiation. */
+ error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+ if (bootverbose)
+ device_printf(dev, "%ssetting %s\n",
+ (error) ? "FAILURE " : "", ata_mode2str(mode));
+ atadev->mode = mode;
}
/*
* device related interfaces
*/
+#ifndef ATA_CAM
static int
ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
int32_t flag, struct thread *td)
@@ -467,6 +647,7 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
}
return error;
}
+#endif
int
ata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
@@ -549,11 +730,12 @@ ata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
case IOCATASMODE:
atadev->mode = *mode;
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
return 0;
case IOCATAGMODE:
- *mode = atadev->mode;
+ *mode = atadev->mode |
+ (ATA_GETREV(device_get_parent(dev), atadev->unit) << 8);
return 0;
case IOCATASSPINDOWN:
atadev->spindown = *mode;
@@ -566,6 +748,7 @@ ata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
}
}
+#ifndef ATA_CAM
static void
ata_boot_attach(void)
{
@@ -590,11 +773,12 @@ ata_boot_attach(void)
mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */
}
-
+#endif
/*
* misc support functions
*/
+#ifndef ATA_CAM
static device_t
ata_add_child(device_t parent, struct ata_device *atadev, int unit)
{
@@ -609,6 +793,7 @@ ata_add_child(device_t parent, struct ata_device *atadev, int unit)
}
return child;
}
+#endif
int
ata_getparam(struct ata_device *atadev, int init)
@@ -705,6 +890,7 @@ ata_getparam(struct ata_device *atadev, int init)
return error;
}
+#ifndef ATA_CAM
int
ata_identify(device_t dev)
{
@@ -778,6 +964,7 @@ ata_identify(device_t dev)
mtx_unlock(&Giant);
return 0;
}
+#endif
void
ata_default_registers(device_t dev)
@@ -920,7 +1107,7 @@ ata_unit2str(struct ata_device *atadev)
return str;
}
-char *
+const char *
ata_mode2str(int mode)
{
switch (mode) {
@@ -950,6 +1137,18 @@ ata_mode2str(int mode)
}
}
+const char *
+ata_satarev2str(int rev)
+{
+ switch (rev) {
+ case 0: return "";
+ case 1: return "SATA 1.5Gb/s";
+ case 2: return "SATA 3Gb/s";
+ case 3: return "SATA 6Gb/s";
+ default: return "???";
+ }
+}
+
int
ata_atapi(device_t dev)
{
@@ -1081,6 +1280,358 @@ bpack(int8_t *src, int8_t *dst, int len)
dst[j] = 0x00;
}
+#ifdef ATA_CAM
+void
+ata_cam_begin_transaction(device_t dev, union ccb *ccb)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+ struct ata_request *request;
+
+ if (!(request = ata_alloc_request())) {
+ device_printf(dev, "FAILURE - out of memory in start\n");
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ return;
+ }
+ bzero(request, sizeof(*request));
+
+ /* setup request */
+ request->dev = NULL;
+ request->parent = dev;
+ request->unit = ccb->ccb_h.target_id;
+ if (ccb->ccb_h.func_code == XPT_ATA_IO) {
+ request->data = ccb->ataio.data_ptr;
+ request->bytecount = ccb->ataio.dxfer_len;
+ request->u.ata.command = ccb->ataio.cmd.command;
+ request->u.ata.feature = ((uint16_t)ccb->ataio.cmd.features_exp << 8) |
+ (uint16_t)ccb->ataio.cmd.features;
+ request->u.ata.count = ((uint16_t)ccb->ataio.cmd.sector_count_exp << 8) |
+ (uint16_t)ccb->ataio.cmd.sector_count;
+ if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
+ request->flags |= ATA_R_48BIT;
+ request->u.ata.lba =
+ ((uint64_t)ccb->ataio.cmd.lba_high_exp << 40) |
+ ((uint64_t)ccb->ataio.cmd.lba_mid_exp << 32) |
+ ((uint64_t)ccb->ataio.cmd.lba_low_exp << 24);
+ } else {
+ request->u.ata.lba =
+ ((uint64_t)(ccb->ataio.cmd.device & 0x0f) << 24);
+ }
+ request->u.ata.lba |= ((uint64_t)ccb->ataio.cmd.lba_high << 16) |
+ ((uint64_t)ccb->ataio.cmd.lba_mid << 8) |
+ (uint64_t)ccb->ataio.cmd.lba_low;
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
+ ccb->ataio.cmd.flags & CAM_ATAIO_DMA)
+ request->flags |= ATA_R_DMA;
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
+ request->flags |= ATA_R_READ;
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
+ request->flags |= ATA_R_WRITE;
+ } else {
+ request->data = ccb->csio.data_ptr;
+ request->bytecount = ccb->csio.dxfer_len;
+ bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+ ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes,
+ request->u.atapi.ccb, ccb->csio.cdb_len);
+ request->flags |= ATA_R_ATAPI;
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
+ ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA)
+ request->flags |= ATA_R_DMA;
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
+ request->flags |= ATA_R_READ;
+ if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
+ request->flags |= ATA_R_WRITE;
+ }
+ request->transfersize = min(request->bytecount,
+ ch->curr[ccb->ccb_h.target_id].bytecount);
+// request->callback = ad_done;
+ request->retries = 0;
+ request->timeout = (ccb->ccb_h.timeout + 999) / 1000;
+ callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED);
+ request->ccb = ccb;
+
+ ch->running = request;
+ ch->state = ATA_ACTIVE;
+ if (ch->hw.begin_transaction(request) == ATA_OP_FINISHED) {
+ ch->running = NULL;
+ ch->state = ATA_IDLE;
+ ata_cam_end_transaction(dev, request);
+ return;
+ }
+}
+
+void
+ata_cam_end_transaction(device_t dev, struct ata_request *request)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+ union ccb *ccb = request->ccb;
+ int fatalerr = 0;
+
+ ccb->ccb_h.status &= ~CAM_STATUS_MASK;
+ if (request->flags & ATA_R_TIMEOUT) {
+ xpt_freeze_simq(ch->sim, 1);
+ ccb->ccb_h.status &= ~CAM_STATUS_MASK;
+ ccb->ccb_h.status |= CAM_CMD_TIMEOUT | CAM_RELEASE_SIMQ;
+ fatalerr = 1;
+ } else if (request->status & ATA_S_ERROR) {
+ if (ccb->ccb_h.func_code == XPT_ATA_IO) {
+ ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
+ } else {
+ ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
+ ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
+ }
+ } else if (request->result == ERESTART)
+ ccb->ccb_h.status |= CAM_REQUEUE_REQ;
+ else if (request->result != 0)
+ ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
+ else
+ ccb->ccb_h.status |= CAM_REQ_CMP;
+ if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP &&
+ !(ccb->ccb_h.status & CAM_DEV_QFRZN)) {
+ xpt_freeze_devq(ccb->ccb_h.path, 1);
+ ccb->ccb_h.status |= CAM_DEV_QFRZN;
+ }
+ if (ccb->ccb_h.func_code == XPT_ATA_IO &&
+ ((request->status & ATA_S_ERROR) ||
+ (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT))) {
+ struct ata_res *res = &ccb->ataio.res;
+ res->status = request->status;
+ res->error = request->error;
+ res->lba_low = request->u.ata.lba;
+ res->lba_mid = request->u.ata.lba >> 8;
+ res->lba_high = request->u.ata.lba >> 16;
+ res->device = request->u.ata.lba >> 24;
+ res->lba_low_exp = request->u.ata.lba >> 24;
+ res->lba_mid_exp = request->u.ata.lba >> 32;
+ res->lba_high_exp = request->u.ata.lba >> 40;
+ res->sector_count = request->u.ata.count;
+ res->sector_count_exp = request->u.ata.count >> 8;
+ }
+ ata_free_request(request);
+ xpt_done(ccb);
+ /* Do error recovery if needed. */
+ if (fatalerr)
+ ata_reinit(dev);
+}
+
+static void
+ataaction(struct cam_sim *sim, union ccb *ccb)
+{
+ device_t dev;
+ struct ata_channel *ch;
+
+ CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ataaction func_code=%x\n",
+ ccb->ccb_h.func_code));
+
+ ch = (struct ata_channel *)cam_sim_softc(sim);
+ dev = ch->dev;
+ switch (ccb->ccb_h.func_code) {
+ /* Common cases first */
+ case XPT_ATA_IO: /* Execute the requested I/O operation */
+ case XPT_SCSI_IO:
+ if ((ch->devices & ((ATA_ATA_MASTER | ATA_ATAPI_MASTER)
+ << ccb->ccb_h.target_id)) == 0) {
+ ccb->ccb_h.status = CAM_SEL_TIMEOUT;
+ xpt_done(ccb);
+ break;
+ }
+ if (ch->running)
+ device_printf(dev, "already running!\n");
+ if (ccb->ccb_h.func_code == XPT_ATA_IO &&
+ (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
+ (ccb->ataio.cmd.control & ATA_A_RESET)) {
+ struct ata_res *res = &ccb->ataio.res;
+
+ bzero(res, sizeof(*res));
+ if (ch->devices & (ATA_ATA_MASTER << ccb->ccb_h.target_id)) {
+ res->lba_high = 0;
+ res->lba_mid = 0;
+ } else {
+ res->lba_high = 0xeb;
+ res->lba_mid = 0x14;
+ }
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+ }
+ ata_cam_begin_transaction(dev, ccb);
+ break;
+ case XPT_EN_LUN: /* Enable LUN as a target */
+ case XPT_TARGET_IO: /* Execute target I/O request */
+ case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
+ case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
+ case XPT_ABORT: /* Abort the specified CCB */
+ /* XXX Implement */
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ break;
+ case XPT_SET_TRAN_SETTINGS:
+ {
+ struct ccb_trans_settings *cts = &ccb->cts;
+ struct ata_cam_device *d;
+
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
+ d = &ch->curr[ccb->ccb_h.target_id];
+ else
+ d = &ch->user[ccb->ccb_h.target_id];
+ if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE)) {
+ if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION)
+ d->revision = cts->xport_specific.sata.revision;
+ if (cts->xport_specific.ata.valid & CTS_SATA_VALID_MODE) {
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
+ d->mode = ATA_SETMODE(ch->dev,
+ ccb->ccb_h.target_id,
+ cts->xport_specific.sata.mode);
+ } else
+ d->mode = cts->xport_specific.sata.mode;
+ }
+ if (cts->xport_specific.ata.valid & CTS_SATA_VALID_BYTECOUNT)
+ d->bytecount = min(8192, cts->xport_specific.sata.bytecount);
+ } else {
+ if (cts->xport_specific.ata.valid & CTS_ATA_VALID_MODE) {
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
+ d->mode = ATA_SETMODE(ch->dev,
+ ccb->ccb_h.target_id,
+ cts->xport_specific.ata.mode);
+ } else
+ d->mode = cts->xport_specific.ata.mode;
+ }
+ if (cts->xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
+ d->bytecount = cts->xport_specific.ata.bytecount;
+ if (ch->flags & ATA_SATA)
+ d->bytecount = min(8192, d->bytecount);
+ }
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+ }
+ case XPT_GET_TRAN_SETTINGS:
+ {
+ struct ccb_trans_settings *cts = &ccb->cts;
+ struct ata_cam_device *d;
+
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
+ d = &ch->curr[ccb->ccb_h.target_id];
+ else
+ d = &ch->user[ccb->ccb_h.target_id];
+ cts->protocol = PROTO_ATA;
+ cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
+ if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE)) {
+ cts->transport = XPORT_SATA;
+ cts->transport_version = XPORT_VERSION_UNSPECIFIED;
+ cts->xport_specific.sata.mode = d->mode;
+ cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE;
+ cts->xport_specific.sata.bytecount = d->bytecount;
+ cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT;
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
+ cts->xport_specific.sata.revision =
+ ATA_GETREV(dev, ccb->ccb_h.target_id);
+ } else
+ cts->xport_specific.sata.revision = d->revision;
+ cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION;
+ } else {
+ cts->transport = XPORT_ATA;
+ cts->transport_version = XPORT_VERSION_UNSPECIFIED;
+ cts->xport_specific.ata.mode = d->mode;
+ cts->xport_specific.ata.valid |= CTS_ATA_VALID_MODE;
+ cts->xport_specific.ata.bytecount = d->bytecount;
+ cts->xport_specific.ata.valid |= CTS_ATA_VALID_BYTECOUNT;
+ }
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+ }
+#if 0
+ case XPT_CALC_GEOMETRY:
+ {
+ struct ccb_calc_geometry *ccg;
+ uint32_t size_mb;
+ uint32_t secs_per_cylinder;
+
+ ccg = &ccb->ccg;
+ size_mb = ccg->volume_size
+ / ((1024L * 1024L) / ccg->block_size);
+ if (size_mb >= 1024 && (aha->extended_trans != 0)) {
+ if (size_mb >= 2048) {
+ ccg->heads = 255;
+ ccg->secs_per_track = 63;
+ } else {
+ ccg->heads = 128;
+ ccg->secs_per_track = 32;
+ }
+ } else {
+ ccg->heads = 64;
+ ccg->secs_per_track = 32;
+ }
+ secs_per_cylinder = ccg->heads * ccg->secs_per_track;
+ ccg->cylinders = ccg->volume_size / secs_per_cylinder;
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+ }
+#endif
+ case XPT_RESET_BUS: /* Reset the specified SCSI bus */
+ case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
+ ata_reinit(dev);
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+ case XPT_TERM_IO: /* Terminate the I/O process */
+ /* XXX Implement */
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ break;
+ case XPT_PATH_INQ: /* Path routing inquiry */
+ {
+ struct ccb_pathinq *cpi = &ccb->cpi;
+
+ cpi->version_num = 1; /* XXX??? */
+ cpi->hba_inquiry = PI_SDTR_ABLE;
+ cpi->target_sprt = 0;
+ cpi->hba_misc = PIM_SEQSCAN;
+ cpi->hba_eng_cnt = 0;
+ if (ch->flags & ATA_NO_SLAVE)
+ cpi->max_target = 0;
+ else
+ cpi->max_target = 1;
+ cpi->max_lun = 0;
+ cpi->initiator_id = 0;
+ cpi->bus_id = cam_sim_bus(sim);
+ if (ch->flags & ATA_SATA)
+ cpi->base_transfer_speed = 150000;
+ else
+ cpi->base_transfer_speed = 3300;
+ strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
+ strncpy(cpi->hba_vid, "ATA", HBA_IDLEN);
+ strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
+ cpi->unit_number = cam_sim_unit(sim);
+ if ((ch->flags & ATA_SATA) && (ch->flags & ATA_NO_SLAVE))
+ cpi->transport = XPORT_SATA;
+ else
+ cpi->transport = XPORT_ATA;
+ cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
+ cpi->protocol = PROTO_ATA;
+ cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
+ cpi->maxio = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS;
+ cpi->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+ }
+ default:
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ break;
+ }
+}
+
+static void
+atapoll(struct cam_sim *sim)
+{
+ struct ata_channel *ch = (struct ata_channel *)cam_sim_softc(sim);
+
+ ata_interrupt_locked(ch);
+}
+#endif
/*
* module handeling
@@ -1088,10 +1639,13 @@ bpack(int8_t *src, int8_t *dst, int len)
static int
ata_module_event_handler(module_t mod, int what, void *arg)
{
+#ifndef ATA_CAM
static struct cdev *atacdev;
+#endif
switch (what) {
case MOD_LOAD:
+#ifndef ATA_CAM
/* register controlling device */
atacdev = make_dev(&ata_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "ata");
@@ -1109,11 +1663,14 @@ ata_module_event_handler(module_t mod, int what, void *arg)
free(ata_delayed_attach, M_TEMP);
}
}
+#endif
return 0;
case MOD_UNLOAD:
+#ifndef ATA_CAM
/* deregister controlling device */
destroy_dev(atacdev);
+#endif
return 0;
default:
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index f832505..32f095e 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -425,6 +425,9 @@ struct ata_request {
struct ata_composite *composite; /* for composite atomic ops */
void *driver; /* driver specific */
TAILQ_ENTRY(ata_request) chain; /* list management */
+#ifdef ATA_CAM
+ union ccb *ccb;
+#endif
};
/* define this for debugging request processing */
@@ -531,6 +534,14 @@ struct ata_resource {
int offset;
};
+#ifdef ATA_CAM
+struct ata_cam_device {
+ u_int revision;
+ int mode;
+ u_int bytecount;
+};
+#endif
+
/* structure describing an ATA channel */
struct ata_channel {
device_t dev; /* device handle */
@@ -547,6 +558,9 @@ struct ata_channel {
#define ATA_ATAPI_DMA_RO 0x04
#define ATA_NO_48BIT_DMA 0x08
#define ATA_ALWAYS_DMASTAT 0x10
+#define ATA_CHECKS_CABLE 0x20
+#define ATA_NO_ATAPI_DMA 0x40
+#define ATA_SATA 0x80
int pm_level; /* power management level */
int devices; /* what is present */
@@ -567,6 +581,12 @@ struct ata_channel {
struct ata_request *freezepoint; /* composite freezepoint */
struct ata_request *running; /* currently running request */
struct task conntask; /* PHY events handling task */
+#ifdef ATA_CAM
+ struct cam_sim *sim;
+ struct cam_path *path;
+ struct ata_cam_device user[16]; /* User-specified settings */
+ struct ata_cam_device curr[16]; /* Current settings */
+#endif
};
/* disk bay/enclosure related */
@@ -600,12 +620,20 @@ void ata_default_registers(device_t dev);
void ata_modify_if_48bit(struct ata_request *request);
void ata_udelay(int interval);
char *ata_unit2str(struct ata_device *atadev);
-char *ata_mode2str(int mode);
+const char *ata_mode2str(int mode);
+const char *ata_satarev2str(int rev);
int ata_atapi(device_t dev);
int ata_pmode(struct ata_params *ap);
int ata_wmode(struct ata_params *ap);
int ata_umode(struct ata_params *ap);
int ata_limit_mode(device_t dev, int mode, int maxmode);
+void ata_setmode(device_t dev);
+void ata_print_cable(device_t dev, u_int8_t *who);
+int ata_check_80pin(device_t dev, int mode);
+#ifdef ATA_CAM
+void ata_cam_begin_transaction(device_t dev, union ccb *ccb);
+void ata_cam_end_transaction(device_t dev, struct ata_request *request);
+#endif
/* ata-queue.c: */
int ata_controlcmd(device_t dev, u_int8_t command, u_int16_t feature, u_int64_t lba, u_int16_t count);
@@ -635,7 +663,8 @@ void ata_sata_phy_check_events(device_t dev);
int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val);
int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val);
int ata_sata_phy_reset(device_t dev, int port, int quick);
-void ata_sata_setmode(device_t dev, int mode);
+int ata_sata_setmode(device_t dev, int target, int mode);
+int ata_sata_getrev(device_t dev, int target);
int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis);
void ata_pm_identify(device_t dev);
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 03b1065..df753c5 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -381,7 +381,7 @@ ad_init(device_t dev)
{
struct ata_device *atadev = device_get_softc(dev);
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
/* enable readahead caching */
if (atadev->param.support.command1 & ATA_SUPPORT_LOOKAHEAD)
@@ -533,12 +533,13 @@ ad_describe(device_t dev)
strncpy(product, atadev->param.model, 40);
}
- device_printf(dev, "%juMB <%s%s %.8s> at ata%d-%s %s%s\n",
+ device_printf(dev, "%juMB <%s%s %.8s> at ata%d-%s %s%s %s\n",
adp->total_secs / (1048576 / DEV_BSIZE),
vendor, product, atadev->param.revision,
device_get_unit(ch->dev), ata_unit2str(atadev),
(adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
- ata_mode2str(atadev->mode));
+ ata_mode2str(atadev->mode),
+ ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit)));
if (bootverbose) {
device_printf(dev, "%ju sectors [%juC/%dH/%dS] "
"%d sectors/interrupt %d depth queue\n", adp->total_secs,
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index eae4348..478693d 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -76,7 +76,7 @@ ata_dmainit(device_t dev)
ch->dma.alignment = 2;
ch->dma.boundary = 65536;
ch->dma.segsize = 65536;
- ch->dma.max_iosize = 128 * DEV_BSIZE;
+ ch->dma.max_iosize = MIN((ATA_DMA_ENTRIES - 1) * PAGE_SIZE, MAXPHYS);
ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
ch->dma.dma_slots = 1;
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c
index 2dbb986..566b8f6 100644
--- a/sys/dev/ata/ata-lowlevel.c
+++ b/sys/dev/ata/ata-lowlevel.c
@@ -82,6 +82,9 @@ ata_begin_transaction(struct ata_request *request)
ATA_DEBUG_RQ(request, "begin transaction");
/* disable ATAPI DMA writes if HW doesn't support it */
+ if ((ch->flags & ATA_NO_ATAPI_DMA) &&
+ (request->flags & ATA_R_ATAPI) == ATA_R_ATAPI)
+ request->flags &= ~ATA_R_DMA;
if ((ch->flags & ATA_ATAPI_DMA_RO) &&
((request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)) ==
(ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)))
@@ -757,7 +760,9 @@ static void
ata_tf_write(struct ata_request *request)
{
struct ata_channel *ch = device_get_softc(request->parent);
+#ifndef ATA_CAM
struct ata_device *atadev = device_get_softc(request->dev);
+#endif
if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8);
@@ -775,6 +780,7 @@ ata_tf_write(struct ata_request *request)
else {
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count);
+#ifndef ATA_CAM
if (atadev->flags & ATA_D_USE_CHS) {
int heads, sectors;
@@ -797,13 +803,16 @@ ata_tf_write(struct ata_request *request)
sectors) & 0xf));
}
else {
+#endif
ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba);
ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTB(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f));
+#ifndef ATA_CAM
}
+#endif
}
}
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index ce21926..cd87728 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -55,10 +55,6 @@ static MALLOC_DEFINE(M_ATAPCI, "ata_pci", "ATA driver PCI");
/* misc defines */
#define IOMASK 0xfffffffc
-/* local prototypes */
-static int ata_generic_chipinit(device_t dev);
-static void ata_generic_setmode(device_t dev, int mode);
-
/*
* generic PCI ATA device probe
*/
@@ -374,18 +370,14 @@ ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
}
}
-static void
-ata_generic_setmode(device_t dev, int mode)
+int
+ata_generic_setmode(device_t dev, int target, int mode)
{
- struct ata_device *atadev = device_get_softc(dev);
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
+ return (min(mode, ATA_UDMA2));
}
-static int
+int
ata_generic_chipinit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
@@ -707,16 +699,26 @@ ata_pcichannel_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_pcichannel_setmode(device_t parent, device_t dev)
+static int
+ata_pcichannel_setmode(device_t dev, int target, int mode)
+{
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+
+ if (ctlr->setmode)
+ return (ctlr->setmode(dev, target, mode));
+ else
+ return (ata_generic_setmode(dev, target, mode));
+}
+
+static int
+ata_pcichannel_getrev(device_t dev, int target)
{
- struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int mode = atadev->mode;
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
- ctlr->setmode(dev, ATA_PIO_MAX);
- if (mode >= ATA_DMA)
- ctlr->setmode(dev, mode);
+ if (ctlr->getrev)
+ return (ctlr->getrev(dev, target));
+ else
+ return (0);
}
static device_method_t ata_pcichannel_methods[] = {
@@ -730,6 +732,7 @@ static device_method_t ata_pcichannel_methods[] = {
/* ATA methods */
DEVMETHOD(ata_setmode, ata_pcichannel_setmode),
+ DEVMETHOD(ata_getrev, ata_pcichannel_getrev),
DEVMETHOD(ata_locking, ata_pcichannel_locking),
DEVMETHOD(ata_reset, ata_pcichannel_reset),
@@ -858,31 +861,6 @@ ata_find_chip(device_t dev, struct ata_chip_id *index, int slot)
return (NULL);
}
-void
-ata_print_cable(device_t dev, u_int8_t *who)
-{
- device_printf(dev,
- "DMA limited to UDMA33, %s found non-ATA66 cable\n", who);
-}
-
-int
-ata_check_80pin(device_t dev, int mode)
-{
- struct ata_device *atadev = device_get_softc(dev);
-
- if (!ata_dma_check_80pin) {
- if (bootverbose)
- device_printf(dev, "Skipping 80pin cable check\n");
- return mode;
- }
-
- if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) {
- ata_print_cable(dev, "device");
- mode = ATA_UDMA2;
- }
- return mode;
-}
-
char *
ata_pcivendor2str(device_t dev)
{
diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index f2a0e13..7bfb7a2 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -63,7 +63,8 @@ struct ata_pci_controller {
int (*ch_resume)(device_t);
int (*locking)(device_t, int);
void (*reset)(device_t);
- void (*setmode)(device_t, int);
+ int (*setmode)(device_t, int, int);
+ int (*getrev)(device_t, int);
struct {
void (*function)(void *);
void *argument;
@@ -506,12 +507,12 @@ void ata_pci_dmafini(device_t dev);
char *ata_pcivendor2str(device_t dev);
int ata_legacy(device_t);
void ata_generic_intr(void *data);
+int ata_generic_chipinit(device_t dev);
+int ata_generic_setmode(device_t dev, int target, int mode);
int ata_setup_interrupt(device_t dev, void *intr_func);
void ata_set_desc(device_t dev);
struct ata_chip_id *ata_match_chip(device_t dev, struct ata_chip_id *index);
struct ata_chip_id *ata_find_chip(device_t dev, struct ata_chip_id *index, int slot);
-void ata_print_cable(device_t dev, u_int8_t *who);
-int ata_check_80pin(device_t dev, int mode);
int ata_mode2idx(int mode);
/* global prototypes from chipsets/ata-*.c */
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index c048778..a3b1c4e 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -511,11 +511,18 @@ ata_timeout(struct ata_request *request)
*/
if (ch->state == ATA_ACTIVE) {
request->flags |= ATA_R_TIMEOUT;
- mtx_unlock(&ch->state_mtx);
- ATA_LOCKING(ch->dev, ATA_LF_UNLOCK);
if (ch->dma.unload)
ch->dma.unload(request);
+#ifdef ATA_CAM
+ ch->running = NULL;
+ ch->state = ATA_IDLE;
+ ata_cam_end_transaction(ch->dev, request);
+#endif
+ mtx_unlock(&ch->state_mtx);
+ ATA_LOCKING(ch->dev, ATA_LF_UNLOCK);
+#ifndef ATA_CAM
ata_finish(request);
+#endif
}
else {
mtx_unlock(&ch->state_mtx);
diff --git a/sys/dev/ata/ata-sata.c b/sys/dev/ata/ata-sata.c
index 5f5daa4..9e3f7e8 100644
--- a/sys/dev/ata/ata-sata.c
+++ b/sys/dev/ata/ata-sata.c
@@ -209,38 +209,21 @@ ata_sata_phy_reset(device_t dev, int port, int quick)
return 0;
}
-void
-ata_sata_setmode(device_t dev, int mode)
+int
+ata_sata_setmode(device_t dev, int target, int mode)
{
- struct ata_device *atadev = device_get_softc(dev);
-
- /*
- * if we detect that the device isn't a real SATA device we limit
- * the transfer mode to UDMA5/ATA100.
- * this works around the problems some devices has with the
- * Marvell 88SX8030 SATA->PATA converters and UDMA6/ATA133.
- */
- if (atadev->param.satacapabilities != 0x0000 &&
- atadev->param.satacapabilities != 0xffff) {
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
-
- /* on some drives we need to set the transfer mode */
- ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
- ata_limit_mode(dev, mode, ATA_UDMA6));
-
- /* query SATA STATUS for the speed */
- if (ch->r_io[ATA_SSTATUS].res &&
- ((ATA_IDX_INL(ch, ATA_SSTATUS) & ATA_SS_CONWELL_MASK) ==
- ATA_SS_CONWELL_GEN2))
- atadev->mode = ATA_SA300;
- else
- atadev->mode = ATA_SA150;
- }
- else {
- mode = ata_limit_mode(dev, mode, ATA_UDMA5);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
- }
+
+ return (min(mode, ATA_UDMA5));
+}
+
+int
+ata_sata_getrev(device_t dev, int target)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if (ch->r_io[ATA_SSTATUS].res)
+ return ((ATA_IDX_INL(ch, ATA_SSTATUS) & 0x0f0) >> 4);
+ return (0);
}
int
diff --git a/sys/dev/ata/ata_if.m b/sys/dev/ata/ata_if.m
index 8fcc3f2..a1775ac 100644
--- a/sys/dev/ata/ata_if.m
+++ b/sys/dev/ata/ata_if.m
@@ -57,17 +57,24 @@ HEADER {
};
CODE {
- static void ata_null_setmode(device_t parent, device_t dev)
+ static int ata_null_setmode(device_t dev, int target, int mode)
{
- struct ata_device *atadev = device_get_softc(dev);
- atadev->mode = ata_limit_mode(dev, atadev->mode, ATA_PIO_MAX);
+ if (mode > ATA_PIO_MAX)
+ return (ATA_PIO_MAX);
+ return (mode);
}
};
-METHOD void setmode {
- device_t channel;
+METHOD int setmode {
+ device_t dev;
+ int target;
+ int mode;
+} DEFAULT ata_null_setmode;
+
+METHOD int getrev {
device_t dev;
-} DEFAULT ata_null_setmode;;
+ int target;
+};
METHOD void reset {
device_t channel;
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index a021e00..5d0c0f7 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -126,7 +126,7 @@ acd_attach(device_t dev)
}
cdp->block_size = 2048;
device_set_ivars(dev, cdp);
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
ata_controlcmd(dev, ATA_DEVICE_RESET, 0, 0, 0);
acd_get_cap(dev);
g_post_event(acd_geom_attach, dev, M_WAITOK, NULL);
@@ -163,7 +163,7 @@ acd_reinit(device_t dev)
if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit)))
return 1;
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
return 0;
}
@@ -1724,7 +1724,8 @@ acd_describe(device_t dev)
printf("%s %dKB buffer", comma ? "," : "", cdp->cap.buf_size);
comma = 1;
}
- printf("%s %s\n", comma ? "," : "", ata_mode2str(atadev->mode));
+ printf("%s %s %s\n", comma ? "," : "", ata_mode2str(atadev->mode),
+ ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit)));
device_printf(dev, "Reads:");
comma = 0;
@@ -1874,10 +1875,11 @@ acd_describe(device_t dev)
"CDROM");
if (cdp->changer_info)
printf("with %d CD changer ", cdp->changer_info->slots);
- printf("<%.40s/%.8s> at ata%d-%s %s\n",
+ printf("<%.40s/%.8s> at ata%d-%s %s %s\n",
atadev->param.model, atadev->param.revision,
device_get_unit(ch->dev), ata_unit2str(atadev),
- ata_mode2str(atadev->mode) );
+ ata_mode2str(atadev->mode),
+ ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit)));
}
}
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index 5baeab9..5572d1c 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.c
@@ -85,7 +85,7 @@ afd_attach(device_t dev)
return ENOMEM;
}
device_set_ivars(dev, fdp);
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
if (afd_sense(dev)) {
device_set_ivars(dev, NULL);
@@ -152,7 +152,7 @@ afd_reinit(device_t dev)
if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit)))
return 1;
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
return 0;
}
@@ -400,10 +400,11 @@ afd_describe(device_t dev)
else
strcpy(sizestring, "(no media)");
- device_printf(dev, "%s <%.40s %.8s> at ata%d-%s %s\n",
+ device_printf(dev, "%s <%.40s %.8s> at ata%d-%s %s %s\n",
sizestring, atadev->param.model, atadev->param.revision,
device_get_unit(ch->dev), ata_unit2str(atadev),
- ata_mode2str(atadev->mode));
+ ata_mode2str(atadev->mode),
+ ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit)));
if (bootverbose) {
device_printf(dev, "%ju sectors [%juC/%dH/%dS]\n",
fdp->mediasize / fdp->sectorsize,
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index 5b4da81..b6ca4ad 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -111,7 +111,7 @@ ast_attach(device_t dev)
return ENOMEM;
}
device_set_ivars(dev, stp);
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
if (ast_sense(dev)) {
device_set_ivars(dev, NULL);
@@ -193,7 +193,7 @@ ast_reinit(device_t dev)
if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit)))
return 1;
- ATA_SETMODE(device_get_parent(dev), dev);
+ ata_setmode(dev);
return 0;
}
@@ -673,7 +673,8 @@ ast_describe(device_t dev)
printf("transfer limit %d blk%s, ",
stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : "");
printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024);
- printf("%s\n", ata_mode2str(atadev->mode));
+ printf("%s %s\n", ata_mode2str(atadev->mode),
+ ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit)));
device_printf(dev, "Medium: ");
switch (stp->cap.medium_type) {
case 0x00:
@@ -704,10 +705,11 @@ ast_describe(device_t dev)
printf("\n");
}
else {
- device_printf(dev, "TAPE <%.40s/%.8s> at ata%d-%s %s\n",
+ device_printf(dev, "TAPE <%.40s/%.8s> at ata%d-%s %s %s\n",
atadev->param.model, atadev->param.revision,
device_get_unit(ch->dev), ata_unit2str(atadev),
- ata_mode2str(atadev->mode));
+ ata_mode2str(atadev->mode),
+ ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit)));
}
}
diff --git a/sys/dev/ata/chipsets/ata-acard.c b/sys/dev/ata/chipsets/ata-acard.c
index c52c2cb..bb81c48 100644
--- a/sys/dev/ata/chipsets/ata-acard.c
+++ b/sys/dev/ata/chipsets/ata-acard.c
@@ -61,8 +61,8 @@ struct ata_serialize {
static int ata_acard_chipinit(device_t dev);
static int ata_acard_ch_attach(device_t dev);
static int ata_acard_status(device_t dev);
-static void ata_acard_850_setmode(device_t dev, int mode);
-static void ata_acard_86X_setmode(device_t dev, int mode);
+static int ata_acard_850_setmode(device_t dev, int target, int mode);
+static int ata_acard_86X_setmode(device_t dev, int target, int mode);
static int ata_serialize(device_t dev, int flags);
static void ata_serialize_init(struct ata_serialize *serial);
@@ -130,6 +130,7 @@ ata_acard_ch_attach(device_t dev)
return ENXIO;
ch->hw.status = ata_acard_status;
+ ch->flags |= ATA_NO_ATAPI_DMA;
return 0;
}
@@ -162,79 +163,52 @@ ata_acard_status(device_t dev)
return 1;
}
-static void
-ata_acard_850_setmode(device_t dev, int mode)
+static int
+ata_acard_850_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode,
- ata_atapi(dev) ? ATA_PIO_MAX : ctlr->chip->max_dma);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ mode = min(mode, ctlr->chip->max_dma);
/* XXX SOS missing WDMA0+1 + PIO modes */
if (mode >= ATA_WDMA2) {
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- u_int8_t reg54 = pci_read_config(gparent, 0x54, 1);
+ u_int8_t reg54 = pci_read_config(parent, 0x54, 1);
reg54 &= ~(0x03 << (devno << 1));
if (mode >= ATA_UDMA0)
reg54 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 1));
- pci_write_config(gparent, 0x54, reg54, 1);
- pci_write_config(gparent, 0x4a, 0xa6, 1);
- pci_write_config(gparent, 0x40 + (devno << 1), 0x0301, 2);
- atadev->mode = mode;
- return;
- }
+ pci_write_config(parent, 0x54, reg54, 1);
+ pci_write_config(parent, 0x4a, 0xa6, 1);
+ pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2);
}
/* we could set PIO mode timings, but we assume the BIOS did that */
+ return (mode);
}
-static void
-ata_acard_86X_setmode(device_t dev, int mode)
+static int
+ata_acard_86X_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
-
- mode = ata_limit_mode(dev, mode,
- ata_atapi(dev) ? ATA_PIO_MAX : ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- /* XXX SOS missing WDMA0+1 + PIO modes */
- if (mode >= ATA_WDMA2) {
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- u_int16_t reg44 = pci_read_config(gparent, 0x44, 2);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+
+ mode = min(mode, ctlr->chip->max_dma);
+ /* XXX SOS missing WDMA0+1 + PIO modes */
+ if (mode >= ATA_WDMA2) {
+ u_int16_t reg44 = pci_read_config(parent, 0x44, 2);
- reg44 &= ~(0x000f << (devno << 2));
- if (mode >= ATA_UDMA0)
- reg44 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 2));
- pci_write_config(gparent, 0x44, reg44, 2);
- pci_write_config(gparent, 0x4a, 0xa6, 1);
- pci_write_config(gparent, 0x40 + devno, 0x31, 1);
- atadev->mode = mode;
- return;
+ reg44 &= ~(0x000f << (devno << 2));
+ if (mode >= ATA_UDMA0)
+ reg44 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 2));
+ pci_write_config(parent, 0x44, reg44, 2);
+ pci_write_config(parent, 0x4a, 0xa6, 1);
+ pci_write_config(parent, 0x40 + devno, 0x31, 1);
}
- }
- /* we could set PIO mode timings, but we assume the BIOS did that */
+ /* we could set PIO mode timings, but we assume the BIOS did that */
+ return (mode);
}
static void
diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c
index cf503c5..e74b210 100644
--- a/sys/dev/ata/chipsets/ata-acerlabs.c
+++ b/sys/dev/ata/chipsets/ata-acerlabs.c
@@ -56,7 +56,7 @@ static int ata_ali_chipinit(device_t dev);
static int ata_ali_ch_attach(device_t dev);
static int ata_ali_sata_ch_attach(device_t dev);
static void ata_ali_reset(device_t dev);
-static void ata_ali_setmode(device_t dev, int mode);
+static int ata_ali_setmode(device_t dev, int target, int mode);
/* misc defines */
#define ALI_OLD 0x01
@@ -113,6 +113,7 @@ ata_ali_chipinit(device_t dev)
ctlr->ch_attach = ata_ali_sata_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
/* AHCI mode is correctly supported only on the ALi 5288. */
if ((ctlr->chip->chipid == ATA_ALI_5288) &&
@@ -176,6 +177,7 @@ ata_ali_ch_attach(device_t dev)
if (ata_pci_ch_attach(dev))
return ENXIO;
+ ch->flags |= ATA_CHECKS_CABLE;
/* older chips can't do 48bit DMA transfers */
if (ctlr->chip->chiprev <= 0xc4)
ch->flags |= ATA_NO_48BIT_DMA;
@@ -218,6 +220,7 @@ ata_ali_sata_ch_attach(device_t dev)
}
}
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* XXX SOS PHY handling awkward in ALI chip not supported yet */
ata_pci_hw(dev);
@@ -257,67 +260,56 @@ ata_ali_reset(device_t dev)
}
}
-static void
-ata_ali_setmode(device_t dev, int mode)
+static int
+ata_ali_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg2 & ALI_NEW) {
- if (mode > ATA_UDMA2 &&
- pci_read_config(gparent, 0x4a, 1) & (1 << ch->unit)) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
- else
- mode = ata_check_80pin(dev, mode);
-
- if (ctlr->chip->cfg2 & ALI_OLD) {
- /* doesn't support ATAPI DMA on write */
- ch->flags |= ATA_ATAPI_DMA_RO;
- if (ch->devices & ATA_ATAPI_MASTER && ch->devices & ATA_ATAPI_SLAVE) {
- /* doesn't support ATAPI DMA on two ATAPI devices */
- device_printf(dev, "two atapi devices on this channel, no DMA\n");
- mode = ata_limit_mode(dev, mode, ATA_PIO_MAX);
- }
- }
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t piotimings[] =
+ { 0x006d0003, 0x00580002, 0x00440001, 0x00330001,
+ 0x00310001, 0x006d0003, 0x00330001, 0x00310001 };
+ u_int8_t udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0d};
+ u_int32_t word54;
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+ mode = min(mode, ctlr->chip->max_dma);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ if (ctlr->chip->cfg2 & ALI_NEW) {
+ if (mode > ATA_UDMA2 &&
+ pci_read_config(parent, 0x4a, 1) & (1 << ch->unit)) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
+ if (ctlr->chip->cfg2 & ALI_OLD) {
+ /* doesn't support ATAPI DMA on write */
+ ch->flags |= ATA_ATAPI_DMA_RO;
+ if (ch->devices & ATA_ATAPI_MASTER &&
+ ch->devices & ATA_ATAPI_SLAVE) {
+ /* doesn't support ATAPI DMA on two ATAPI devices */
+ device_printf(dev, "two atapi devices on this channel,"
+ " no DMA\n");
+ mode = min(mode, ATA_PIO_MAX);
+ }
+ }
+ /* Set UDMA mode */
+ word54 = pci_read_config(parent, 0x54, 4);
if (mode >= ATA_UDMA0) {
- u_int8_t udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0d};
- u_int32_t word54 = pci_read_config(gparent, 0x54, 4);
-
word54 &= ~(0x000f000f << (devno << 2));
word54 |= (((udma[mode&ATA_MODE_MASK]<<16)|0x05)<<(devno<<2));
- pci_write_config(gparent, 0x54, word54, 4);
- pci_write_config(gparent, 0x58 + (ch->unit << 2),
- 0x00310001, 4);
+ piomode = ATA_PIO4;
}
else {
- u_int32_t piotimings[] =
- { 0x006d0003, 0x00580002, 0x00440001, 0x00330001,
- 0x00310001, 0x00440001, 0x00330001, 0x00310001};
-
- pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 4) &
- ~(0x0008000f << (devno << 2)), 4);
- pci_write_config(gparent, 0x58 + (ch->unit << 2),
- piotimings[ata_mode2idx(mode)], 4);
+ word54 &= ~(0x0008000f << (devno << 2));
+ piomode = mode;
}
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x54, word54, 4);
+ /* Set PIO/WDMA mode */
+ pci_write_config(parent, 0x58 + (ch->unit << 2),
+ piotimings[ata_mode2idx(piomode)], 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_ali);
diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c
index e4a7cd1..39c5152 100644
--- a/sys/dev/ata/chipsets/ata-ahci.c
+++ b/sys/dev/ata/chipsets/ata-ahci.c
@@ -194,6 +194,7 @@ ata_ahci_chipinit(device_t dev)
ctlr->ch_suspend = ata_ahci_ch_suspend;
ctlr->ch_resume = ata_ahci_ch_resume;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
ctlr->suspend = ata_ahci_suspend;
ctlr->resume = ata_ahci_ctlr_reset;
@@ -309,6 +310,8 @@ ata_ahci_ch_attach(device_t dev)
ch->hw.softreset = ata_ahci_softreset;
ch->hw.pm_read = ata_ahci_pm_read;
ch->hw.pm_write = ata_ahci_pm_write;
+ ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
ata_ahci_ch_resume(dev);
return 0;
diff --git a/sys/dev/ata/chipsets/ata-amd.c b/sys/dev/ata/chipsets/ata-amd.c
index 9c14e99..1cf9ac0 100644
--- a/sys/dev/ata/chipsets/ata-amd.c
+++ b/sys/dev/ata/chipsets/ata-amd.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_amd_chipinit(device_t dev);
-static void ata_amd_setmode(device_t dev, int mode);
+static int ata_amd_setmode(device_t dev, int target, int mode);
/* misc defines */
#define AMD_BUG 0x01
@@ -104,46 +104,37 @@ ata_amd_chipinit(device_t dev)
return 0;
}
-static void
-ata_amd_setmode(device_t dev, int mode)
+static int
+ata_amd_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
- int devno = (ch->unit << 1) + atadev->unit;
- int reg = 0x53 - devno;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg1 & AMD_CABLE) {
- if (mode > ATA_UDMA2 &&
- !(pci_read_config(gparent, 0x42, 1) & (1 << devno))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
+ int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
+ int reg = 0x53 - devno;
+
+ mode = min(mode, ctlr->chip->max_dma);
+ if (ctlr->chip->cfg1 & AMD_CABLE) {
+ if (mode > ATA_UDMA2 &&
+ !(pci_read_config(parent, 0x42, 1) & (1 << devno))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
+ /* Set UDMA timings. */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, reg, modes[mode & ATA_MODE_MASK], 1);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, reg, 0x8b, 1);
+ piomode = mode;
}
- }
- else
- mode = ata_check_80pin(dev, mode);
-
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1);
- else
- pci_write_config(gparent, reg, 0x8b, 1);
- atadev->mode = mode;
- }
+ /* Set WDMA/PIO timings. */
+ pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_amd);
diff --git a/sys/dev/ata/chipsets/ata-ati.c b/sys/dev/ata/chipsets/ata-ati.c
index 4436c7f..d464897 100644
--- a/sys/dev/ata/chipsets/ata-ati.c
+++ b/sys/dev/ata/chipsets/ata-ati.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_ati_chipinit(device_t dev);
-static void ata_ati_setmode(device_t dev, int mode);
+static int ata_ati_setmode(device_t dev, int target, int mode);
/* misc defines */
#define ATI_PATA 0x01
@@ -160,68 +160,61 @@ ata_ati_chipinit(device_t dev)
return 0;
}
-static void
-ata_ati_setmode(device_t dev, int mode)
+static int
+ata_ati_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int offset = (devno ^ 0x01) << 3;
- int error;
- u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int offset = (devno ^ 0x01) << 3;
+ int piomode;
+ u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
+ u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
+
+ mode = min(mode, ctlr->chip->max_dma);
if (mode >= ATA_UDMA0) {
- pci_write_config(gparent, 0x56,
- (pci_read_config(gparent, 0x56, 2) &
+ /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */
+ pci_write_config(parent, 0x56,
+ (pci_read_config(parent, 0x56, 2) &
~(0xf << (devno << 2))) |
((mode & ATA_MODE_MASK) << (devno << 2)), 2);
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) |
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) |
(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[2] << offset), 4);
- }
- else if (mode >= ATA_WDMA0) {
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ /* Disable UDMA, set WDMA mode and timings, calculate PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[mode & ATA_MODE_MASK] << offset), 4);
- }
- else
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else {
+ /* Disable UDMA, set requested PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
-
- pci_write_config(gparent, 0x4a,
- (pci_read_config(gparent, 0x4a, 2) &
+ piomode = mode;
+ }
+ /* Set PIO mode and timings, calculated above. */
+ pci_write_config(parent, 0x4a,
+ (pci_read_config(parent, 0x4a, 2) &
~(0xf << (devno << 2))) |
- (((mode - ATA_PIO0) & ATA_MODE_MASK) << (devno<<2)),2);
- pci_write_config(gparent, 0x40,
- (pci_read_config(gparent, 0x40, 4) &
+ ((piomode - ATA_PIO0) << (devno<<2)),2);
+ pci_write_config(parent, 0x40,
+ (pci_read_config(parent, 0x40, 4) &
~(0xff << offset)) |
- (piotimings[ata_mode2idx(mode)] << offset), 4);
- atadev->mode = mode;
- }
+ (piotimings[ata_mode2idx(piomode)] << offset), 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_ati);
diff --git a/sys/dev/ata/chipsets/ata-cenatek.c b/sys/dev/ata/chipsets/ata-cenatek.c
index 8f6474c..cc54d2b 100644
--- a/sys/dev/ata/chipsets/ata-cenatek.c
+++ b/sys/dev/ata/chipsets/ata-cenatek.c
@@ -51,11 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ata/ata-pci.h>
#include <ata_if.h>
-/* local prototypes */
-static int ata_cenatek_chipinit(device_t dev);
-static void ata_cenatek_setmode(device_t dev, int mode);
-
-
/*
* Cenatek chipset support functions
*/
@@ -67,32 +62,9 @@ ata_cenatek_probe(device_t dev)
if (pci_get_devid(dev) != ATA_CENATEK_ROCKET)
return ENXIO;
- ctlr->chipinit = ata_cenatek_chipinit;
+ ctlr->chipinit = ata_generic_chipinit;
device_set_desc(dev, "Cenatek Rocket Drive controller");
return (BUS_PROBE_DEFAULT);
}
-static int
-ata_cenatek_chipinit(device_t dev)
-{
- struct ata_pci_controller *ctlr = device_get_softc(dev);
-
- if (ata_setup_interrupt(dev, ata_generic_intr))
- return ENXIO;
-
- ctlr->setmode = ata_cenatek_setmode;
- return 0;
-}
-
-static void
-ata_cenatek_setmode(device_t dev, int mode)
-{
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
-}
-
ATA_DECLARE_DRIVER(ata_cenatek);
diff --git a/sys/dev/ata/chipsets/ata-cypress.c b/sys/dev/ata/chipsets/ata-cypress.c
index ffa9782..e4c1a93 100644
--- a/sys/dev/ata/chipsets/ata-cypress.c
+++ b/sys/dev/ata/chipsets/ata-cypress.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_cypress_chipinit(device_t dev);
-static void ata_cypress_setmode(device_t dev, int mode);
+static int ata_cypress_setmode(device_t dev, int target, int mode);
/*
@@ -93,29 +93,20 @@ ata_cypress_chipinit(device_t dev)
return 0;
}
-static void
-ata_cypress_setmode(device_t dev, int mode)
+static int
+ata_cypress_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int error;
+ device_t parent = device_get_parent(dev);
+ struct ata_channel *ch = device_get_softc(dev);
- mode = ata_limit_mode(dev, mode, ATA_WDMA2);
+ mode = min(mode, ATA_WDMA2);
- /* XXX SOS missing WDMA0+1 + PIO modes */
- if (mode == ATA_WDMA2) {
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting WDMA2 on Cypress chip\n",
- error ? "FAILURE " : "");
- if (!error) {
- pci_write_config(gparent, ch->unit ? 0x4e : 0x4c, 0x2020, 2);
- atadev->mode = mode;
- return;
+ /* XXX SOS missing WDMA0+1 + PIO modes */
+ if (mode == ATA_WDMA2) {
+ pci_write_config(parent, ch->unit ? 0x4e : 0x4c, 0x2020, 2);
}
- }
- /* we could set PIO mode timings, but we assume the BIOS did that */
+ /* we could set PIO mode timings, but we assume the BIOS did that */
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_cypress);
diff --git a/sys/dev/ata/chipsets/ata-cyrix.c b/sys/dev/ata/chipsets/ata-cyrix.c
index ddfa562..5a00856 100644
--- a/sys/dev/ata/chipsets/ata-cyrix.c
+++ b/sys/dev/ata/chipsets/ata-cyrix.c
@@ -53,7 +53,8 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_cyrix_chipinit(device_t dev);
-static void ata_cyrix_setmode(device_t dev, int mode);
+static int ata_cyrix_ch_attach(device_t dev);
+static int ata_cyrix_setmode(device_t dev, int target, int mode);
/*
@@ -79,53 +80,57 @@ ata_cyrix_chipinit(device_t dev)
if (ata_setup_interrupt(dev, ata_generic_intr))
return ENXIO;
-
+ ctlr->ch_attach = ata_cyrix_ch_attach;
ctlr->setmode = ata_cyrix_setmode;
return 0;
}
-static void
-ata_cyrix_setmode(device_t dev, int mode)
+static int
+ata_cyrix_ch_attach(device_t dev)
{
- struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev));
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- u_int32_t piotiming[] =
- { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
- u_int32_t dmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
- u_int32_t udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
- int error;
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->dma.alignment = 16;
+ ch->dma.max_iosize = 64 * DEV_BSIZE;
+ return (error);
+}
- if (bootverbose)
- device_printf(dev, "%ssetting %s on Cyrix chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode));
- if (!error) {
+static int
+ata_cyrix_setmode(device_t dev, int target, int mode)
+{
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t piotiming[] =
+ { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
+ u_int32_t dmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
+ u_int32_t udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
+
+ mode = min(mode, ATA_UDMA2);
/* dont try to set the mode if we dont have the resource */
if (ctlr->r_res1) {
- ch->dma.alignment = 16;
- ch->dma.max_iosize = 64 * DEV_BSIZE;
-
- if (mode >= ATA_UDMA0) {
- ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
- 0x24 + (devno << 3), udmatiming[mode & ATA_MODE_MASK]);
- }
- else if (mode >= ATA_WDMA0) {
+ if (mode >= ATA_UDMA0) {
+ /* Set UDMA timings, and PIO4. */
+ ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
+ 0x24 + (devno << 3), udmatiming[mode & ATA_MODE_MASK]);
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ /* Set WDMA timings, and respective PIO mode. */
+ ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
+ 0x24 + (devno << 3), dmatiming[mode & ATA_MODE_MASK]);
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else
+ piomode = mode;
+ /* Set PIO mode calculated above. */
ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
- 0x24 + (devno << 3), dmatiming[mode & ATA_MODE_MASK]);
- }
- else {
- ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
- 0x20 + (devno << 3), piotiming[mode & ATA_MODE_MASK]);
- }
+ 0x20 + (devno << 3), piotiming[ata_mode2idx(piomode)]);
}
- atadev->mode = mode;
- }
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_cyrix);
diff --git a/sys/dev/ata/chipsets/ata-highpoint.c b/sys/dev/ata/chipsets/ata-highpoint.c
index 101b054..511366a 100644
--- a/sys/dev/ata/chipsets/ata-highpoint.c
+++ b/sys/dev/ata/chipsets/ata-highpoint.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_highpoint_chipinit(device_t dev);
static int ata_highpoint_ch_attach(device_t dev);
-static void ata_highpoint_setmode(device_t dev, int mode);
+static int ata_highpoint_setmode(device_t dev, int target, int mode);
static int ata_highpoint_check_80pin(device_t dev, int mode);
/* misc defines */
@@ -143,26 +143,27 @@ ata_highpoint_chipinit(device_t dev)
static int
ata_highpoint_ch_attach(device_t dev)
{
- struct ata_channel *ch = device_get_softc(dev);
-
- /* setup the usual register normal pci style */
- if (ata_pci_ch_attach(dev))
- return ENXIO;
-
- ch->flags |= ATA_ALWAYS_DMASTAT;
- return 0;
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+
+ /* setup the usual register normal pci style */
+ if (ata_pci_ch_attach(dev))
+ return (ENXIO);
+ ch->flags |= ATA_ALWAYS_DMASTAT;
+ ch->flags |= ATA_CHECKS_CABLE;
+ if (ctlr->chip->cfg1 == HPT_366)
+ ch->flags |= ATA_NO_ATAPI_DMA;
+ return (0);
}
-static void
-ata_highpoint_setmode(device_t dev, int mode)
+static int
+ata_highpoint_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
- u_int32_t timings33[][4] = {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ u_int32_t timings33[][4] = {
/* HPT366 HPT370 HPT372 HPT374 mode */
{ 0x40d0a7aa, 0x06914e57, 0x0d029d5e, 0x0ac1f48a }, /* PIO 0 */
{ 0x40d0a7a3, 0x06914e43, 0x0d029d26, 0x0ac1f465 }, /* PIO 1 */
@@ -179,51 +180,41 @@ ata_highpoint_setmode(device_t dev, int mode)
{ 0x10c9a731, 0x16454e31, 0x1c8a9c62, 0x12ac8242 }, /* UDMA 4 */
{ 0, 0x16454e31, 0x1c8a9c62, 0x12848242 }, /* UDMA 5 */
{ 0, 0, 0x1c869c62, 0x12808242 } /* UDMA 6 */
- };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg1 == HPT_366 && ata_atapi(dev))
- mode = ata_limit_mode(dev, mode, ATA_PIO_MAX);
-
- mode = ata_highpoint_check_80pin(dev, mode);
-
- /*
- * most if not all HPT chips cant really handle that the device is
- * running at ATA_UDMA6/ATA133 speed, so we cheat at set the device to
- * a max of ATA_UDMA5/ATA100 to guard against suboptimal performance
- */
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
- ata_limit_mode(dev, mode, ATA_UDMA5));
- if (bootverbose)
- device_printf(dev, "%ssetting %s on HighPoint chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode));
- if (!error)
- pci_write_config(gparent, 0x40 + (devno << 2),
+ };
+
+ mode = min(mode, ctlr->chip->max_dma);
+ mode = ata_highpoint_check_80pin(dev, mode);
+ /*
+ * most if not all HPT chips cant really handle that the device is
+ * running at ATA_UDMA6/ATA133 speed, so we cheat at set the device to
+ * a max of ATA_UDMA5/ATA100 to guard against suboptimal performance
+ */
+ mode = min(mode, ATA_UDMA5);
+ pci_write_config(parent, 0x40 + (devno << 2),
timings33[ata_mode2idx(mode)][ctlr->chip->cfg1], 4);
- atadev->mode = mode;
+ return (mode);
}
static int
ata_highpoint_check_80pin(device_t dev, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
u_int8_t reg, val, res;
- if (ctlr->chip->cfg1 == HPT_374 && pci_get_function(gparent) == 1) {
+ if (ctlr->chip->cfg1 == HPT_374 && pci_get_function(parent) == 1) {
reg = ch->unit ? 0x57 : 0x53;
- val = pci_read_config(gparent, reg, 1);
- pci_write_config(gparent, reg, val | 0x80, 1);
+ val = pci_read_config(parent, reg, 1);
+ pci_write_config(parent, reg, val | 0x80, 1);
}
else {
reg = 0x5b;
- val = pci_read_config(gparent, reg, 1);
- pci_write_config(gparent, reg, val & 0xfe, 1);
+ val = pci_read_config(parent, reg, 1);
+ pci_write_config(parent, reg, val & 0xfe, 1);
}
- res = pci_read_config(gparent, 0x5a, 1) & (ch->unit ? 0x1:0x2);
- pci_write_config(gparent, reg, val, 1);
+ res = pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x1:0x2);
+ pci_write_config(parent, reg, val, 1);
if (mode > ATA_UDMA2 && res) {
ata_print_cable(dev, "controller");
diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
index add18d2..95e40c1 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$");
static int ata_intel_chipinit(device_t dev);
static int ata_intel_ch_attach(device_t dev);
static void ata_intel_reset(device_t dev);
-static void ata_intel_old_setmode(device_t dev, int mode);
-static void ata_intel_new_setmode(device_t dev, int mode);
-static void ata_intel_sata_setmode(device_t dev, int mode);
+static int ata_intel_old_setmode(device_t dev, int target, int mode);
+static int ata_intel_new_setmode(device_t dev, int target, int mode);
+static int ata_intel_sata_getrev(device_t dev, int target);
static int ata_intel_31244_ch_attach(device_t dev);
static int ata_intel_31244_ch_detach(device_t dev);
static int ata_intel_31244_status(device_t dev);
@@ -181,6 +181,7 @@ ata_intel_chipinit(device_t dev)
ctlr->reset = ata_intel_31244_reset;
}
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
}
/* non SATA intel chips goes here */
@@ -214,9 +215,8 @@ ata_intel_chipinit(device_t dev)
ctlr->r_rid2 = PCIR_BAR(5);
if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
&ctlr->r_rid2, RF_ACTIVE)))
- ctlr->setmode = ata_intel_sata_setmode;
- else
- ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_intel_sata_getrev;
+ ctlr->setmode = ata_sata_setmode;
}
return 0;
}
@@ -240,6 +240,13 @@ ata_intel_ch_attach(device_t dev)
}
ch->flags |= ATA_ALWAYS_DMASTAT;
+ if (ctlr->chip->max_dma >= ATA_SA150) {
+ if (ctlr->chip->cfg1 == 0 &&
+ (pci_read_config(device_get_parent(dev), 0x90, 1) & 0x04) == 0)
+ ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
+ } else
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -259,11 +266,8 @@ ata_intel_reset(device_t dev)
/* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
if (pci_read_config(parent, 0x90, 1) & 0x04)
mask = 0x0003;
- else {
+ else
mask = (0x0001 << ch->unit);
- /* XXX SOS should be in intel_ch_attach if we grow it */
- ch->flags |= ATA_NO_SLAVE;
- }
}
pci_write_config(parent, 0x92, pci_read_config(parent, 0x92, 2) & ~mask, 2);
DELAY(10);
@@ -279,80 +283,70 @@ ata_intel_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_intel_old_setmode(device_t dev, int mode)
+static int
+ata_intel_old_setmode(device_t dev, int target, int mode)
{
- /* NOT YET */
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+
+ mode = min(mode, ctlr->chip->max_dma);
+ return (mode);
}
-static void
-ata_intel_new_setmode(device_t dev, int mode)
+static int
+ata_intel_new_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- u_int32_t reg40 = pci_read_config(gparent, 0x40, 4);
- u_int8_t reg44 = pci_read_config(gparent, 0x44, 1);
- u_int8_t reg48 = pci_read_config(gparent, 0x48, 1);
- u_int16_t reg4a = pci_read_config(gparent, 0x4a, 2);
- u_int16_t reg54 = pci_read_config(gparent, 0x54, 2);
- u_int32_t mask40 = 0, new40 = 0;
- u_int8_t mask44 = 0, new44 = 0;
- int error;
- u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if ( mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- if (mode >= ATA_UDMA0) {
- u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
-
- pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a,
- (reg4a & ~(0x3 << (devno << 2))) |
- (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t reg40 = pci_read_config(parent, 0x40, 4);
+ u_int8_t reg44 = pci_read_config(parent, 0x44, 1);
+ u_int8_t reg48 = pci_read_config(parent, 0x48, 1);
+ u_int16_t reg4a = pci_read_config(parent, 0x4a, 2);
+ u_int16_t reg54 = pci_read_config(parent, 0x54, 2);
+ u_int32_t mask40 = 0, new40 = 0;
+ u_int8_t mask44 = 0, new44 = 0;
+ u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 };
+ u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
+
+ mode = min(mode, ctlr->chip->max_dma);
+ if (mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
}
- else {
- pci_write_config(gparent, 0x48, reg48 & ~(0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2);
+ /* Enable/disable UDMA and set timings. */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, 0x48, reg48 | (0x0001 << devno), 2);
+ pci_write_config(parent, 0x4a,
+ (reg4a & ~(0x3 << (devno << 2))) |
+ (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, 0x48, reg48 & ~(0x0001 << devno), 2);
+ pci_write_config(parent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2);
+ piomode = mode;
}
reg54 |= 0x0400;
- if (mode >= ATA_UDMA3)
- reg54 |= (0x1 << devno);
- else
- reg54 &= ~(0x1 << devno);
+ /* Set UDMA reference clock (33/66/133MHz). */
+ reg54 &= ~(0x1001 << devno);
if (mode >= ATA_UDMA5)
reg54 |= (0x1000 << devno);
- else
- reg54 &= ~(0x1000 << devno);
-
- pci_write_config(gparent, 0x54, reg54, 2);
-
+ else if (mode >= ATA_UDMA3)
+ reg54 |= (0x1 << devno);
+ pci_write_config(parent, 0x54, reg54, 2);
+ /* Allow PIO/WDMA timing controls. */
reg40 &= ~0x00ff00ff;
reg40 |= 0x40774077;
-
- if (atadev->unit == ATA_MASTER) {
+ /* Set PIO/WDMA timings. */
+ if (target == 0) {
mask40 = 0x3300;
- new40 = timings[ata_mode2idx(mode)] << 8;
- }
- else {
+ new40 = timings[ata_mode2idx(piomode)] << 8;
+ } else {
mask44 = 0x0f;
- new44 = ((timings[ata_mode2idx(mode)] & 0x30) >> 2) |
- (timings[ata_mode2idx(mode)] & 0x03);
+ new44 = ((timings[ata_mode2idx(piomode)] & 0x30) >> 2) |
+ (timings[ata_mode2idx(piomode)] & 0x03);
}
if (ch->unit) {
mask40 <<= 16;
@@ -360,43 +354,21 @@ ata_intel_new_setmode(device_t dev, int mode)
mask44 <<= 4;
new44 <<= 4;
}
- pci_write_config(gparent, 0x40, (reg40 & ~mask40) | new40, 4);
- pci_write_config(gparent, 0x44, (reg44 & ~mask44) | new44, 1);
-
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x40, (reg40 & ~mask40) | new40, 4);
+ pci_write_config(parent, 0x44, (reg44 & ~mask44) | new44, 1);
+ return (mode);
}
-static void
-ata_intel_sata_setmode(device_t dev, int mode)
+static int
+ata_intel_sata_getrev(device_t dev, int target)
{
- struct ata_device *atadev = device_get_softc(dev);
-
- if (atadev->param.satacapabilities != 0x0000 &&
- atadev->param.satacapabilities != 0xffff) {
-
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- int devno = (ch->unit << 1) + atadev->unit;
-
- /* on some drives we need to set the transfer mode */
- ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
- ata_limit_mode(dev, mode, ATA_UDMA6));
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
/* set ATA_SSTATUS register offset */
ATA_IDX_OUTL(ch, ATA_IDX_ADDR, devno * 0x100);
-
/* query SATA STATUS for the speed */
- if ((ATA_IDX_INL(ch, ATA_IDX_DATA) & ATA_SS_CONWELL_MASK) ==
- ATA_SS_CONWELL_GEN2)
- atadev->mode = ATA_SA300;
- else
- atadev->mode = ATA_SA150;
- }
- else {
- mode = ata_limit_mode(dev, mode, ATA_UDMA5);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
- }
+ return ((ATA_IDX_INL(ch, ATA_IDX_DATA) & 0x0f0) >> 4);
}
static int
@@ -439,6 +411,7 @@ ata_intel_31244_ch_attach(device_t dev)
ch->r_io[ATA_BMDTP_PORT].offset = ch_offset + 0x74;
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
ata_pci_hw(dev);
ch->hw.status = ata_intel_31244_status;
ch->hw.tf_write = ata_intel_31244_tf_write;
@@ -471,7 +444,9 @@ static void
ata_intel_31244_tf_write(struct ata_request *request)
{
struct ata_channel *ch = device_get_softc(request->parent);
+#ifndef ATA_CAM
struct ata_device *atadev = device_get_softc(request->dev);
+#endif
if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
@@ -487,6 +462,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
else {
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count);
+#ifndef ATA_CAM
if (atadev->flags & ATA_D_USE_CHS) {
int heads, sectors;
@@ -508,13 +484,16 @@ ata_intel_31244_tf_write(struct ata_request *request)
sectors) & 0xf));
}
else {
+#endif
ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba);
ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTB(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f));
+#ifndef ATA_CAM
}
+#endif
}
}
diff --git a/sys/dev/ata/chipsets/ata-ite.c b/sys/dev/ata/chipsets/ata-ite.c
index 6187917..250ca64 100644
--- a/sys/dev/ata/chipsets/ata-ite.c
+++ b/sys/dev/ata/chipsets/ata-ite.c
@@ -53,8 +53,9 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_ite_chipinit(device_t dev);
-static void ata_ite_821x_setmode(device_t dev, int mode);
-static void ata_ite_8213_setmode(device_t dev, int mode);
+static int ata_ite_ch_attach(device_t dev);
+static int ata_ite_821x_setmode(device_t dev, int target, int mode);
+static int ata_ite_8213_setmode(device_t dev, int target, int mode);
/*
@@ -105,143 +106,125 @@ ata_ite_chipinit(device_t dev)
ctlr->setmode = ata_ite_821x_setmode;
}
-
+ ctlr->ch_attach = ata_ite_ch_attach;
return 0;
}
-
-static void
-ata_ite_821x_setmode(device_t dev, int mode)
+
+static int
+ata_ite_ch_attach(device_t dev)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->flags |= ATA_CHECKS_CABLE;
+ return (error);
+}
- /* correct the mode for what the HW supports */
- mode = ata_limit_mode(dev, mode, ATA_UDMA6);
+static int
+ata_ite_821x_setmode(device_t dev, int target, int mode)
+{
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int8_t udmatiming[] =
+ { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 };
+ u_int8_t chtiming[] =
+ { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 };
- /* check the CBLID bits for 80 conductor cable detection */
- if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x40, 2) &
+ mode = min(mode, ctlr->chip->max_dma);
+ /* check the CBLID bits for 80 conductor cable detection */
+ if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x40, 2) &
(ch->unit ? (1<<3) : (1<<2)))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
-
- /* set the wanted mode on the device */
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%s setting %s on ITE8212F chip\n",
- (error) ? "failed" : "success", ata_mode2str(mode));
-
- /* if the device accepted the mode change, setup the HW accordingly */
- if (!error) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
if (mode >= ATA_UDMA0) {
- u_int8_t udmatiming[] =
- { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 };
-
- /* enable UDMA mode */
- pci_write_config(gparent, 0x50,
- pci_read_config(gparent, 0x50, 1) &
+ /* enable UDMA mode */
+ pci_write_config(parent, 0x50,
+ pci_read_config(parent, 0x50, 1) &
~(1 << (devno + 3)), 1);
-
- /* set UDMA timing */
- pci_write_config(gparent,
- 0x56 + (ch->unit << 2) + atadev->unit,
+ /* set UDMA timing */
+ pci_write_config(parent,
+ 0x56 + (ch->unit << 2) + target,
udmatiming[mode & ATA_MODE_MASK], 1);
- }
- else {
- u_int8_t chtiming[] =
- { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 };
-
- /* disable UDMA mode */
- pci_write_config(gparent, 0x50,
- pci_read_config(gparent, 0x50, 1) |
+ piomode = ATA_PIO4;
+ } else {
+ /* disable UDMA mode */
+ pci_write_config(parent, 0x50,
+ pci_read_config(parent, 0x50, 1) |
(1 << (devno + 3)), 1);
-
- /* set active and recover timing (shared between master & slave) */
- if (pci_read_config(gparent, 0x54 + (ch->unit << 2), 1) <
- chtiming[ata_mode2idx(mode)])
- pci_write_config(gparent, 0x54 + (ch->unit << 2),
- chtiming[ata_mode2idx(mode)], 1);
+ piomode = mode;
}
- atadev->mode = mode;
- }
+ /* set active and recover timing (shared between master & slave) */
+ if (pci_read_config(parent, 0x54 + (ch->unit << 2), 1) <
+ chtiming[ata_mode2idx(piomode)])
+ pci_write_config(parent, 0x54 + (ch->unit << 2),
+ chtiming[ata_mode2idx(piomode)], 1);
+ return (mode);
}
-static void
-ata_ite_8213_setmode(device_t dev, int mode)
+static int
+ata_ite_8213_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_device *atadev = device_get_softc(dev);
- u_int16_t reg40 = pci_read_config(gparent, 0x40, 2);
- u_int8_t reg44 = pci_read_config(gparent, 0x44, 1);
- u_int8_t reg48 = pci_read_config(gparent, 0x48, 1);
- u_int16_t reg4a = pci_read_config(gparent, 0x4a, 2);
- u_int16_t reg54 = pci_read_config(gparent, 0x54, 2);
- u_int16_t mask40 = 0, new40 = 0;
- u_int8_t mask44 = 0, new44 = 0;
- int devno = atadev->unit;
- int error;
- u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- if (mode >= ATA_UDMA0) {
- u_int8_t utimings[] = { 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10 };
-
- pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a,
- (reg4a & ~(0x3 << (devno << 2))) |
- (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ int piomode;
+ u_int16_t reg40 = pci_read_config(parent, 0x40, 2);
+ u_int8_t reg44 = pci_read_config(parent, 0x44, 1);
+ u_int8_t reg48 = pci_read_config(parent, 0x48, 1);
+ u_int16_t reg4a = pci_read_config(parent, 0x4a, 2);
+ u_int16_t reg54 = pci_read_config(parent, 0x54, 2);
+ u_int16_t mask40 = 0, new40 = 0;
+ u_int8_t mask44 = 0, new44 = 0;
+ u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 };
+ u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
+
+ mode = min(mode, ctlr->chip->max_dma);
+
+ if (mode > ATA_UDMA2 && !(reg54 & (0x10 << target))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
}
- else {
- pci_write_config(gparent, 0x48, reg48 & ~(0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2);
+ /* Enable/disable UDMA and set timings. */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, 0x48, reg48 | (0x0001 << target), 2);
+ pci_write_config(parent, 0x4a,
+ (reg4a & ~(0x3 << (target << 2))) |
+ (utimings[mode & ATA_MODE_MASK] << (target<<2)), 2);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, 0x48, reg48 & ~(0x0001 << target), 2);
+ pci_write_config(parent, 0x4a, (reg4a & ~(0x3 << (target << 2))),2);
+ piomode = mode;
}
- if (mode >= ATA_UDMA2)
- reg54 |= (0x1 << devno);
- else
- reg54 &= ~(0x1 << devno);
+ /* Set UDMA reference clock (33/66/133MHz). */
+ reg54 &= ~(0x1001 << target);
if (mode >= ATA_UDMA5)
- reg54 |= (0x1000 << devno);
- else
- reg54 &= ~(0x1000 << devno);
- pci_write_config(gparent, 0x54, reg54, 2);
-
+ reg54 |= (0x1000 << target);
+ else if (mode >= ATA_UDMA3)
+ reg54 |= (0x1 << target);
+ pci_write_config(parent, 0x54, reg54, 2);
+ /* Allow PIO/WDMA timing controls. */
reg40 &= 0xff00;
reg40 |= 0x4033;
- if (atadev->unit == ATA_MASTER) {
+ /* Set PIO/WDMA timings. */
+ if (target == 0) {
reg40 |= (ata_atapi(dev) ? 0x04 : 0x00);
mask40 = 0x3300;
- new40 = timings[ata_mode2idx(mode)] << 8;
+ new40 = timings[ata_mode2idx(piomode)] << 8;
}
else {
reg40 |= (ata_atapi(dev) ? 0x40 : 0x00);
mask44 = 0x0f;
- new44 = ((timings[ata_mode2idx(mode)] & 0x30) >> 2) |
- (timings[ata_mode2idx(mode)] & 0x03);
+ new44 = ((timings[ata_mode2idx(piomode)] & 0x30) >> 2) |
+ (timings[ata_mode2idx(piomode)] & 0x03);
}
- pci_write_config(gparent, 0x40, (reg40 & ~mask40) | new40, 4);
- pci_write_config(gparent, 0x44, (reg44 & ~mask44) | new44, 1);
-
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x40, (reg40 & ~mask40) | new40, 4);
+ pci_write_config(parent, 0x44, (reg44 & ~mask44) | new44, 1);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_ite);
diff --git a/sys/dev/ata/chipsets/ata-jmicron.c b/sys/dev/ata/chipsets/ata-jmicron.c
index 2531070..13524f1 100644
--- a/sys/dev/ata/chipsets/ata-jmicron.c
+++ b/sys/dev/ata/chipsets/ata-jmicron.c
@@ -53,7 +53,8 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_jmicron_chipinit(device_t dev);
-static void ata_jmicron_setmode(device_t dev, int mode);
+static int ata_jmicron_ch_attach(device_t dev);
+static int ata_jmicron_setmode(device_t dev, int target, int mode);
/*
* JMicron chipset support functions
@@ -79,13 +80,8 @@ ata_jmicron_probe(device_t dev)
if (!(idx = ata_match_chip(dev, ids)))
return ENXIO;
- if ((pci_read_config(dev, 0xdf, 1) & 0x40) &&
- (pci_get_function(dev) == (pci_read_config(dev, 0x40, 1) & 0x02 >> 1)))
- sprintf(buffer, "JMicron %s %s controller",
- idx->text, ata_mode2str(ATA_UDMA6));
- else
- sprintf(buffer, "JMicron %s %s controller",
- idx->text, ata_mode2str(idx->max_dma));
+ sprintf(buffer, "JMicron %s %s controller",
+ idx->text, ata_mode2str(idx->max_dma));
device_set_desc_copy(dev, buffer);
ctlr->chip = idx;
ctlr->chipinit = ata_jmicron_chipinit;
@@ -108,7 +104,7 @@ ata_jmicron_chipinit(device_t dev)
return 0;
/* otherwise we are on the PATA part */
- ctlr->ch_attach = ata_pci_ch_attach;
+ ctlr->ch_attach = ata_jmicron_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_generic_reset;
ctlr->setmode = ata_jmicron_setmode;
@@ -126,7 +122,7 @@ ata_jmicron_chipinit(device_t dev)
bus_generic_attach(dev);
}
}
- ctlr->ch_attach = ata_pci_ch_attach;
+ ctlr->ch_attach = ata_jmicron_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_generic_reset;
ctlr->setmode = ata_jmicron_setmode;
@@ -135,18 +131,30 @@ ata_jmicron_chipinit(device_t dev)
return 0;
}
-static void
-ata_jmicron_setmode(device_t dev, int mode)
+static int
+ata_jmicron_ch_attach(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->flags |= ATA_CHECKS_CABLE;
+ return (error);
+}
+
+static int
+ata_jmicron_setmode(device_t dev, int target, int mode)
{
- struct ata_device *atadev = device_get_softc(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ mode = min(mode, ctlr->chip->max_dma);
/* check for 80pin cable present */
- if (pci_read_config(dev, 0x40, 1) & 0x08)
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- else
- mode = ata_limit_mode(dev, mode, ATA_UDMA6);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
+ if (mode > ATA_UDMA2 && pci_read_config(dev, 0x40, 1) & 0x08) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_jmicron);
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index bda1a17..0d11266 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_marvell_chipinit(device_t dev);
static int ata_marvell_ch_attach(device_t dev);
-static void ata_marvell_setmode(device_t dev, int mode);
+static int ata_marvell_setmode(device_t dev, int target, int mode);
static int ata_marvell_edma_ch_attach(device_t dev);
static int ata_marvell_edma_ch_detach(device_t dev);
static int ata_marvell_edma_status(device_t dev);
@@ -170,20 +170,24 @@ ata_marvell_ch_attach(device_t dev)
error = ata_pci_ch_attach(dev);
/* dont use 32 bit PIO transfers */
ch->flags |= ATA_USE_16BIT;
+ ch->flags |= ATA_CHECKS_CABLE;
return (error);
}
-static void
-ata_marvell_setmode(device_t dev, int mode)
+static int
+ata_marvell_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+
+ mode = min(mode, ctlr->chip->max_dma);
+ /* Check for 80pin cable present. */
+ if (mode > ATA_UDMA2 && ATA_IDX_INB(ch, ATA_BMDEVSPEC_0) & 0x01) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */
+ return (mode);
}
int
@@ -210,6 +214,7 @@ ata_marvell_edma_chipinit(device_t dev)
ctlr->ch_detach = ata_marvell_edma_ch_detach;
ctlr->reset = ata_marvell_edma_reset;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
ctlr->channels = ctlr->chip->cfg1;
/* clear host controller interrupts */
@@ -281,6 +286,7 @@ ata_marvell_edma_ch_attach(device_t dev)
ch->flags |= ATA_NO_SLAVE;
ch->flags |= ATA_USE_16BIT; /* XXX SOS needed ? */
+ ch->flags |= ATA_SATA;
ata_generic_hw(dev);
ch->hw.begin_transaction = ata_marvell_edma_begin_transaction;
ch->hw.end_transaction = ata_marvell_edma_end_transaction;
@@ -601,8 +607,6 @@ ata_marvell_edma_dmainit(device_t dev)
/* chip does not reliably do 64K DMA transfers */
if (ctlr->chip->cfg2 == MV_50XX || ctlr->chip->cfg2 == MV_60XX)
ch->dma.max_iosize = 64 * DEV_BSIZE;
- else
- ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
}
ATA_DECLARE_DRIVER(ata_marvell);
diff --git a/sys/dev/ata/chipsets/ata-micron.c b/sys/dev/ata/chipsets/ata-micron.c
index ce75874..2b74a33 100644
--- a/sys/dev/ata/chipsets/ata-micron.c
+++ b/sys/dev/ata/chipsets/ata-micron.c
@@ -51,11 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ata/ata-pci.h>
#include <ata_if.h>
-/* local prototypes */
-static int ata_micron_chipinit(device_t dev);
-static void ata_micron_setmode(device_t dev, int mode);
-
-
/*
* Cenatek chipset support functions
*/
@@ -68,34 +63,10 @@ ata_micron_probe(device_t dev)
pci_get_devid(dev) == ATA_MICRON_RZ1001) {
device_set_desc(dev,
"RZ 100? ATA controller !WARNING! data loss/corruption risk");
- ctlr->chipinit = ata_micron_chipinit;
+ ctlr->chipinit = ata_generic_chipinit;
return (BUS_PROBE_DEFAULT);
}
- else
- return ENXIO;
-}
-
-static int
-ata_micron_chipinit(device_t dev)
-{
- struct ata_pci_controller *ctlr = device_get_softc(dev);
-
- if (ata_setup_interrupt(dev, ata_generic_intr))
- return ENXIO;
-
- ctlr->setmode = ata_micron_setmode;
- return 0;
-}
-
-static void
-ata_micron_setmode(device_t dev, int mode)
-{
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
+ return (ENXIO);
}
ATA_DECLARE_DRIVER(ata_micron);
diff --git a/sys/dev/ata/chipsets/ata-national.c b/sys/dev/ata/chipsets/ata-national.c
index 840360a..20cafa5 100644
--- a/sys/dev/ata/chipsets/ata-national.c
+++ b/sys/dev/ata/chipsets/ata-national.c
@@ -53,8 +53,8 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_national_chipinit(device_t dev);
-static void ata_national_setmode(device_t dev, int mode);
-
+static int ata_national_ch_attach(device_t dev);
+static int ata_national_setmode(device_t dev, int target, int mode);
/*
* National chipset support functions
@@ -81,53 +81,55 @@ ata_national_chipinit(device_t dev)
if (ata_setup_interrupt(dev, ata_generic_intr))
return ENXIO;
+ ctlr->ch_attach = ata_national_ch_attach;
ctlr->setmode = ata_national_setmode;
return 0;
}
-static void
-ata_national_setmode(device_t dev, int mode)
+static int
+ata_national_ch_attach(device_t dev)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- u_int32_t piotiming[] =
- { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
- 0x00803020, 0x20102010, 0x00100010,
- 0x00100010, 0x00100010, 0x00100010 };
- u_int32_t dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
- u_int32_t udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
- int error;
-
- ch->dma.alignment = 16;
- ch->dma.max_iosize = 64 * DEV_BSIZE;
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->dma.alignment = 16;
+ ch->dma.max_iosize = 64 * DEV_BSIZE;
+ return (error);
+}
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
+static int
+ata_national_setmode(device_t dev, int target, int mode)
+{
+ device_t parent = device_get_parent(dev);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t piotiming[] =
+ { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
+ 0x9172d132, 0x20102010, 0x00100010 };
+ u_int32_t dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
+ u_int32_t udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+ mode = min(mode, ATA_UDMA2);
- if (bootverbose)
- device_printf(dev, "%s setting %s on National chip\n",
- (error) ? "failed" : "success", ata_mode2str(mode));
- if (!error) {
if (mode >= ATA_UDMA0) {
- pci_write_config(gparent, 0x44 + (devno << 3),
+ pci_write_config(parent, 0x44 + (devno << 3),
udmatiming[mode & ATA_MODE_MASK], 4);
- }
- else if (mode >= ATA_WDMA0) {
- pci_write_config(gparent, 0x44 + (devno << 3),
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ pci_write_config(parent, 0x44 + (devno << 3),
dmatiming[mode & ATA_MODE_MASK], 4);
- }
- else {
- pci_write_config(gparent, 0x44 + (devno << 3),
- pci_read_config(gparent, 0x44 + (devno << 3), 4) |
+ piomode = mode;
+ } else {
+ pci_write_config(parent, 0x44 + (devno << 3),
+ pci_read_config(parent, 0x44 + (devno << 3), 4) |
0x80000000, 4);
+ piomode = mode;
}
- pci_write_config(gparent, 0x40 + (devno << 3),
- piotiming[ata_mode2idx(mode)], 4);
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x40 + (devno << 3),
+ piotiming[ata_mode2idx(piomode)], 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_national);
diff --git a/sys/dev/ata/chipsets/ata-netcell.c b/sys/dev/ata/chipsets/ata-netcell.c
index c07df0e..f6a7545 100644
--- a/sys/dev/ata/chipsets/ata-netcell.c
+++ b/sys/dev/ata/chipsets/ata-netcell.c
@@ -54,8 +54,6 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_netcell_chipinit(device_t dev);
static int ata_netcell_ch_attach(device_t dev);
-static void ata_netcell_setmode(device_t dev, int mode);
-
/*
* NetCell chipset support functions
@@ -82,8 +80,7 @@ ata_netcell_chipinit(device_t dev)
return ENXIO;
ctlr->ch_attach = ata_netcell_ch_attach;
- ctlr->ch_detach = ata_pci_ch_detach;
- ctlr->setmode = ata_netcell_setmode;
+ ctlr->setmode = ata_generic_setmode;
return 0;
}
@@ -98,19 +95,7 @@ ata_netcell_ch_attach(device_t dev)
/* the NetCell only supports 16 bit PIO transfers */
ch->flags |= ATA_USE_16BIT;
-
return 0;
}
-static void
-ata_netcell_setmode(device_t dev, int mode)
-{
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
-}
-
ATA_DECLARE_DRIVER(ata_netcell);
diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c
index cdff825..79064f8 100644
--- a/sys/dev/ata/chipsets/ata-nvidia.c
+++ b/sys/dev/ata/chipsets/ata-nvidia.c
@@ -56,7 +56,7 @@ static int ata_nvidia_chipinit(device_t dev);
static int ata_nvidia_ch_attach(device_t dev);
static int ata_nvidia_status(device_t dev);
static void ata_nvidia_reset(device_t dev);
-static void ata_nvidia_setmode(device_t dev, int mode);
+static int ata_nvidia_setmode(device_t dev, int target, int mode);
/* misc defines */
#define NV4 0x01
@@ -231,6 +231,7 @@ ata_nvidia_chipinit(device_t dev)
}
}
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
}
else {
/* disable prefetch, postwrite */
@@ -259,7 +260,7 @@ ata_nvidia_ch_attach(device_t dev)
ch->hw.status = ata_nvidia_status;
ch->flags |= ATA_NO_SLAVE;
-
+ ch->flags |= ATA_SATA;
return 0;
}
@@ -299,36 +300,29 @@ ata_nvidia_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_nvidia_setmode(device_t dev, int mode)
+static int
+ata_nvidia_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
- int devno = (ch->unit << 1) + atadev->unit;
- int reg = 0x63 - devno;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1);
- else
- pci_write_config(gparent, reg, 0x8b, 1);
- atadev->mode = mode;
- }
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
+ int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
+ int reg = 0x63 - devno;
+
+ mode = min(mode, ctlr->chip->max_dma);
+
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, reg, modes[mode & ATA_MODE_MASK], 1);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, reg, 0x8b, 1);
+ piomode = mode;
+ }
+ pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_nvidia);
diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c
index ca3243a..2f79a46 100644
--- a/sys/dev/ata/chipsets/ata-promise.c
+++ b/sys/dev/ata/chipsets/ata-promise.c
@@ -58,7 +58,7 @@ static int ata_promise_status(device_t dev);
static int ata_promise_dmastart(struct ata_request *request);
static int ata_promise_dmastop(struct ata_request *request);
static void ata_promise_dmareset(device_t dev);
-static void ata_promise_setmode(device_t dev, int mode);
+static int ata_promise_setmode(device_t dev, int target, int mode);
static int ata_promise_tx2_ch_attach(device_t dev);
static int ata_promise_tx2_status(device_t dev);
static int ata_promise_mio_ch_attach(device_t dev);
@@ -72,7 +72,7 @@ static int ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t r
static u_int32_t ata_promise_mio_softreset(device_t dev, int port);
static void ata_promise_mio_dmainit(device_t dev);
static void ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
-static void ata_promise_mio_setmode(device_t dev, int mode);
+static int ata_promise_mio_setmode(device_t dev, int target, int mode);
static void ata_promise_sx4_intr(void *data);
static int ata_promise_sx4_command(struct ata_request *request);
static int ata_promise_apkt(u_int8_t *bytep, struct ata_request *request);
@@ -369,6 +369,8 @@ ata_promise_ch_attach(device_t dev)
}
ch->hw.status = ata_promise_status;
+ ch->flags |= ATA_NO_ATAPI_DMA;
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -438,15 +440,13 @@ ata_promise_dmareset(device_t dev)
ch->flags &= ~ATA_DMA_ACTIVE;
}
-static void
-ata_promise_setmode(device_t dev, int mode)
+static int
+ata_promise_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
u_int32_t timings[][2] = {
/* PR_OLD PR_NEW mode */
{ 0x004ff329, 0x004fff2f }, /* PIO 0 */
@@ -465,18 +465,16 @@ ata_promise_setmode(device_t dev, int mode)
{ 0, 0x004127f3 } /* UDMA 5 */
};
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
+ mode = min(mode, ctlr->chip->max_dma);
switch (ctlr->chip->cfg1) {
case PR_OLD:
case PR_NEW:
- if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x50, 2) &
+ if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x50, 2) &
(ch->unit ? 1 << 11 : 1 << 10))) {
ata_print_cable(dev, "controller");
mode = ATA_UDMA2;
}
- if (ata_atapi(dev) && mode > ATA_PIO_MAX)
- mode = ata_limit_mode(dev, mode, ATA_PIO_MAX);
break;
case PR_TX:
@@ -499,19 +497,10 @@ ata_promise_setmode(device_t dev, int mode)
break;
}
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
if (ctlr->chip->cfg1 < PR_TX)
- pci_write_config(gparent, 0x60 + (devno << 2),
+ pci_write_config(parent, 0x60 + (devno << 2),
timings[ata_mode2idx(mode)][ctlr->chip->cfg1], 4);
- atadev->mode = mode;
- }
- return;
+ return (mode);
}
static int
@@ -523,6 +512,7 @@ ata_promise_tx2_ch_attach(device_t dev)
return ENXIO;
ch->hw.status = ata_promise_tx2_status;
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -565,8 +555,10 @@ ata_promise_mio_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x408 + (ch->unit << 8);
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
}
ch->flags |= ATA_USE_16BIT;
+ ch->flags |= ATA_CHECKS_CABLE;
ata_generic_hw(dev);
if (ctlr->chip->cfg2 & PR_SX4X) {
@@ -997,20 +989,20 @@ ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
args->nsegs = nsegs;
}
-static void
-ata_promise_mio_setmode(device_t dev, int mode)
+static int
+ata_promise_mio_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
-
- if ( (ctlr->chip->cfg2 == PR_SATA) ||
- ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||
- (ctlr->chip->cfg2 == PR_SATA2) ||
- ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))
- ata_sata_setmode(dev, mode);
- else
- ata_promise_setmode(dev, mode);
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if ( (ctlr->chip->cfg2 == PR_SATA) ||
+ ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||
+ (ctlr->chip->cfg2 == PR_SATA2) ||
+ ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))
+ mode = ata_sata_setmode(dev, target, mode);
+ else
+ mode = ata_promise_setmode(dev, target, mode);
+ return (mode);
}
static void
diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c
index 886282e..b5a3fc2 100644
--- a/sys/dev/ata/chipsets/ata-serverworks.c
+++ b/sys/dev/ata/chipsets/ata-serverworks.c
@@ -60,7 +60,7 @@ static int ata_serverworks_ch_attach(device_t dev);
static int ata_serverworks_ch_detach(device_t dev);
static void ata_serverworks_tf_read(struct ata_request *request);
static void ata_serverworks_tf_write(struct ata_request *request);
-static void ata_serverworks_setmode(device_t dev, int mode);
+static int ata_serverworks_setmode(device_t dev, int target, int mode);
#ifdef __powerpc__
static int ata_serverworks_status(device_t dev);
#endif
@@ -147,6 +147,7 @@ ata_serverworks_chipinit(device_t dev)
ctlr->ch_attach = ata_serverworks_ch_attach;
ctlr->ch_detach = ata_serverworks_ch_detach;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
return 0;
}
else if (ctlr->chip->cfg1 == SWKS_33) {
@@ -213,6 +214,7 @@ ata_serverworks_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].offset = ch_offset + 0x48;
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
ata_pci_hw(dev);
ch->hw.tf_read = ata_serverworks_tf_read;
ch->hw.tf_write = ata_serverworks_tf_write;
@@ -287,7 +289,9 @@ static void
ata_serverworks_tf_write(struct ata_request *request)
{
struct ata_channel *ch = device_get_softc(request->parent);
+#ifndef ATA_CAM
struct ata_device *atadev = device_get_softc(request->dev);
+#endif
if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
@@ -303,6 +307,7 @@ ata_serverworks_tf_write(struct ata_request *request)
else {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count);
+#ifndef ATA_CAM
if (atadev->flags & ATA_D_USE_CHS) {
int heads, sectors;
@@ -324,74 +329,74 @@ ata_serverworks_tf_write(struct ata_request *request)
sectors) & 0xf));
}
else {
+#endif
ATA_IDX_OUTW(ch, ATA_SECTOR, request->u.ata.lba);
ATA_IDX_OUTW(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTW(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTW(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f));
+#ifndef ATA_CAM
}
+#endif
}
}
-static void
-ata_serverworks_setmode(device_t dev, int mode)
+static int
+ata_serverworks_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int offset = (devno ^ 0x01) << 3;
- int error;
- u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int offset = (devno ^ 0x01) << 3;
+ int piomode;
+ u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
+ u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
+
+ mode = min(mode, ctlr->chip->max_dma);
if (mode >= ATA_UDMA0) {
- pci_write_config(gparent, 0x56,
- (pci_read_config(gparent, 0x56, 2) &
+ /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */
+ pci_write_config(parent, 0x56,
+ (pci_read_config(parent, 0x56, 2) &
~(0xf << (devno << 2))) |
((mode & ATA_MODE_MASK) << (devno << 2)), 2);
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) |
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) |
(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[2] << offset), 4);
- }
- else if (mode >= ATA_WDMA0) {
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ /* Disable UDMA, set WDMA mode and timings, calculate PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[mode & ATA_MODE_MASK] << offset), 4);
- }
- else
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else {
+ /* Disable UDMA, set requested PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
-
- pci_write_config(gparent, 0x40,
- (pci_read_config(gparent, 0x40, 4) &
+ piomode = mode;
+ }
+ /* Set PIO mode and timings, calculated above. */
+ pci_write_config(parent, 0x4a,
+ (pci_read_config(parent, 0x4a, 2) &
+ ~(0xf << (devno << 2))) |
+ ((piomode - ATA_PIO0) << (devno<<2)),2);
+ pci_write_config(parent, 0x40,
+ (pci_read_config(parent, 0x40, 4) &
~(0xff << offset)) |
- (piotimings[ata_mode2idx(mode)] << offset), 4);
- atadev->mode = mode;
- }
+ (piotimings[ata_mode2idx(piomode)] << offset), 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_serverworks);
diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c
index 34bd92f..066e9280 100644
--- a/sys/dev/ata/chipsets/ata-siliconimage.c
+++ b/sys/dev/ata/chipsets/ata-siliconimage.c
@@ -54,12 +54,12 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_cmd_ch_attach(device_t dev);
static int ata_cmd_status(device_t dev);
-static void ata_cmd_setmode(device_t dev, int mode);
+static int ata_cmd_setmode(device_t dev, int target, int mode);
static int ata_sii_ch_attach(device_t dev);
static int ata_sii_ch_detach(device_t dev);
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_sii_setmode(device_t dev, int target, int mode);
static int ata_siiprb_ch_attach(device_t dev);
static int ata_siiprb_ch_detach(device_t dev);
static int ata_siiprb_status(device_t dev);
@@ -145,6 +145,7 @@ ata_sii_chipinit(device_t dev)
ctlr->ch_detach = ata_siiprb_ch_detach;
ctlr->reset = ata_siiprb_reset;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
ctlr->channels = (ctlr->chip->cfg2 == SII_4CH) ? 4 : 2;
/* reset controller */
@@ -193,6 +194,7 @@ ata_sii_chipinit(device_t dev)
if (ctlr->chip->max_dma >= ATA_SA150) {
ctlr->reset = ata_sii_reset;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
}
else
ctlr->setmode = ata_sii_setmode;
@@ -246,59 +248,37 @@ ata_cmd_status(device_t dev)
return 0;
}
-static void
-ata_cmd_setmode(device_t dev, int mode)
+static int
+ata_cmd_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
int treg = 0x54 + ((devno < 3) ? (devno << 1) : 7);
int ureg = ch->unit ? 0x7b : 0x73;
-
- if (mode >= ATA_UDMA0) {
- int udmatimings[][2] = { { 0x31, 0xc2 }, { 0x21, 0x82 },
+ int piomode;
+ uint8_t piotimings[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f, 0x87, 0x32, 0x3f };
+ uint8_t udmatimings[][2] = { { 0x31, 0xc2 }, { 0x21, 0x82 },
{ 0x11, 0x42 }, { 0x25, 0x8a },
{ 0x15, 0x4a }, { 0x05, 0x0a } };
- u_int8_t umode = pci_read_config(gparent, ureg, 1);
-
- umode &= ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca);
- umode |= udmatimings[mode & ATA_MODE_MASK][atadev->unit];
- pci_write_config(gparent, ureg, umode, 1);
- }
- else if (mode >= ATA_WDMA0) {
- int dmatimings[] = { 0x87, 0x32, 0x3f };
-
- pci_write_config(gparent, treg, dmatimings[mode & ATA_MODE_MASK],1);
- pci_write_config(gparent, ureg,
- pci_read_config(gparent, ureg, 1) &
- ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca), 1);
- }
- else {
- int piotimings[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f };
- pci_write_config(gparent, treg,
- piotimings[(mode & ATA_MODE_MASK) - ATA_PIO0], 1);
- pci_write_config(gparent, ureg,
- pci_read_config(gparent, ureg, 1) &
- ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca), 1);
+ mode = min(mode, ctlr->chip->max_dma);
+ if (mode >= ATA_UDMA0) {
+ u_int8_t umode = pci_read_config(parent, ureg, 1);
+
+ umode &= ~(target == 0 ? 0x35 : 0xca);
+ umode |= udmatimings[mode & ATA_MODE_MASK][target];
+ pci_write_config(parent, ureg, umode, 1);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, ureg,
+ pci_read_config(parent, ureg, 1) &
+ ~(target == 0 ? 0x35 : 0xca), 1);
+ piomode = mode;
}
- atadev->mode = mode;
- }
+ pci_write_config(parent, treg, piotimings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
static int
@@ -335,12 +315,12 @@ ata_sii_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x100 + (unit01 << 7) + (unit10 << 8);
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* enable PHY state change interrupt */
ATA_OUTL(ctlr->r_res2, 0x148 + (unit01 << 7) + (unit10 << 8),(1 << 16));
}
- ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
if (ctlr->chip->cfg2 & SII_BUG) {
/* work around errata in early chips */
ch->dma.boundary = 8192;
@@ -349,6 +329,8 @@ ata_sii_ch_attach(device_t dev)
ata_pci_hw(dev);
ch->hw.status = ata_sii_status;
+ if (ctlr->chip->cfg2 & SII_SETCLK)
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -386,69 +368,53 @@ ata_sii_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_sii_setmode(device_t dev, int mode)
+static int
+ata_sii_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int rego = (ch->unit << 4) + (atadev->unit << 1);
- int mreg = ch->unit ? 0x84 : 0x80;
- int mask = 0x03 << (atadev->unit << 2);
- int mval = pci_read_config(gparent, mreg, 1) & ~mask;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg2 & SII_SETCLK) {
- if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x79, 1) &
- (ch->unit ? 0x02 : 0x01))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
- else
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (error)
- return;
-
- if (mode >= ATA_UDMA0) {
- u_int8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 };
- u_int8_t ureg = 0xac + rego;
-
- pci_write_config(gparent, mreg,
- mval | (0x03 << (atadev->unit << 2)), 1);
- pci_write_config(gparent, ureg,
- (pci_read_config(gparent, ureg, 1) & ~0x3f) |
- udmatimings[mode & ATA_MODE_MASK], 1);
-
- }
- else if (mode >= ATA_WDMA0) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int rego = (ch->unit << 4) + (target << 1);
+ int mreg = ch->unit ? 0x84 : 0x80;
+ int mask = 0x03 << (target << 2);
+ int mval = pci_read_config(parent, mreg, 1) & ~mask;
+ int piomode;
+ u_int8_t preg = 0xa4 + rego;
u_int8_t dreg = 0xa8 + rego;
+ u_int8_t ureg = 0xac + rego;
+ u_int16_t piotimings[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
u_int16_t dmatimings[] = { 0x2208, 0x10c2, 0x10c1 };
+ u_int8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 };
- pci_write_config(gparent, mreg,
- mval | (0x02 << (atadev->unit << 2)), 1);
- pci_write_config(gparent, dreg, dmatimings[mode & ATA_MODE_MASK], 2);
-
- }
- else {
- u_int8_t preg = 0xa4 + rego;
- u_int16_t piotimings[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
+ mode = min(mode, ctlr->chip->max_dma);
- pci_write_config(gparent, mreg,
- mval | (0x01 << (atadev->unit << 2)), 1);
- pci_write_config(gparent, preg, piotimings[mode & ATA_MODE_MASK], 2);
- }
- atadev->mode = mode;
+ if (ctlr->chip->cfg2 & SII_SETCLK) {
+ if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x79, 1) &
+ (ch->unit ? 0x02 : 0x01))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, mreg,
+ mval | (0x03 << (target << 2)), 1);
+ pci_write_config(parent, ureg,
+ (pci_read_config(parent, ureg, 1) & ~0x3f) |
+ udmatimings[mode & ATA_MODE_MASK], 1);
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ pci_write_config(parent, mreg,
+ mval | (0x02 << (target << 2)), 1);
+ pci_write_config(parent, dreg, dmatimings[mode & ATA_MODE_MASK], 2);
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else {
+ pci_write_config(parent, mreg,
+ mval | (0x01 << (target << 2)), 1);
+ piomode = mode;
+ }
+ pci_write_config(parent, preg, piotimings[ata_mode2idx(piomode)], 2);
+ return (mode);
}
diff --git a/sys/dev/ata/chipsets/ata-sis.c b/sys/dev/ata/chipsets/ata-sis.c
index 5c74e56..8022505 100644
--- a/sys/dev/ata/chipsets/ata-sis.c
+++ b/sys/dev/ata/chipsets/ata-sis.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
static int ata_sis_chipinit(device_t dev);
static int ata_sis_ch_attach(device_t dev);
static void ata_sis_reset(device_t dev);
-static void ata_sis_setmode(device_t dev, int mode);
+static int ata_sis_setmode(device_t dev, int target, int mode);
/* misc defines */
#define SIS_33 1
@@ -191,6 +191,7 @@ ata_sis_chipinit(device_t dev)
ctlr->reset = ata_sis_reset;
}
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
return 0;
default:
return ENXIO;
@@ -217,6 +218,7 @@ ata_sis_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x08 + offset;
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* XXX SOS PHY hotplug handling missing in SiS chip ?? */
/* XXX SOS unknown how to enable PHY state change interrupt */
@@ -230,40 +232,30 @@ ata_sis_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_sis_setmode(device_t dev, int mode)
+static int
+ata_sis_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg1 == SIS_133NEW) {
- if (mode > ATA_UDMA2 &&
- pci_read_config(gparent, ch->unit ? 0x52 : 0x50,2) & 0x8000) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
- else {
- if (mode > ATA_UDMA2 &&
- pci_read_config(gparent, 0x48, 1)&(ch->unit ? 0x20 : 0x10)) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+
+ mode = min(mode, ctlr->chip->max_dma);
+
+ if (ctlr->chip->cfg1 == SIS_133NEW) {
+ if (mode > ATA_UDMA2 &&
+ pci_read_config(parent, ch->unit ? 0x52 : 0x50,2) & 0x8000) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ } else {
+ if (mode > ATA_UDMA2 &&
+ pci_read_config(parent, 0x48, 1)&(ch->unit ? 0x20 : 0x10)) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
switch (ctlr->chip->cfg1) {
case SIS_133NEW: {
u_int32_t timings[] =
@@ -272,8 +264,8 @@ ata_sis_setmode(device_t dev, int mode)
0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c};
u_int32_t reg;
- reg = (pci_read_config(gparent, 0x57, 1)&0x40?0x70:0x40)+(devno<<2);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 4);
+ reg = (pci_read_config(parent, 0x57, 1)&0x40?0x70:0x40)+(devno<<2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 4);
break;
}
case SIS_133OLD: {
@@ -283,7 +275,7 @@ ata_sis_setmode(device_t dev, int mode)
u_int16_t reg = 0x40 + (devno << 1);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2);
break;
}
case SIS_100NEW: {
@@ -292,7 +284,7 @@ ata_sis_setmode(device_t dev, int mode)
0x0031, 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 };
u_int16_t reg = 0x40 + (devno << 1);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2);
break;
}
case SIS_100OLD:
@@ -303,12 +295,11 @@ ata_sis_setmode(device_t dev, int mode)
0x0301, 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301 };
u_int16_t reg = 0x40 + (devno << 1);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2);
break;
}
}
- atadev->mode = mode;
- }
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_sis);
diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c
index 47ebd0a..9aea45d 100644
--- a/sys/dev/ata/chipsets/ata-via.c
+++ b/sys/dev/ata/chipsets/ata-via.c
@@ -56,9 +56,9 @@ static int ata_via_chipinit(device_t dev);
static int ata_via_ch_attach(device_t dev);
static int ata_via_ch_detach(device_t dev);
static void ata_via_reset(device_t dev);
-static void ata_via_old_setmode(device_t dev, int mode);
+static int ata_via_old_setmode(device_t dev, int target, int mode);
static void ata_via_southbridge_fixup(device_t dev);
-static void ata_via_new_setmode(device_t dev, int mode);
+static int ata_via_new_setmode(device_t dev, int target, int mode);
/* misc defines */
#define VIA33 0
@@ -152,9 +152,9 @@ ata_via_chipinit(device_t dev)
if (ctlr->chip->cfg2 & VIABAR) {
ctlr->channels = 3;
ctlr->setmode = ata_via_new_setmode;
- }
- else
+ } else
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
return 0;
}
@@ -233,6 +233,7 @@ ata_via_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x08 + (ch->unit << ctlr->chip->cfg1);
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* XXX SOS PHY hotplug handling missing in VIA chip ?? */
/* XXX SOS unknown how to enable PHY state change interrupt */
@@ -277,75 +278,63 @@ ata_via_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_via_new_setmode(device_t dev, int mode)
+static int
+ata_via_new_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int error;
-
- if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) {
- u_int8_t pio_timings[] = { 0xa8, 0x65, 0x65, 0x32, 0x20,
- 0x65, 0x32, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- u_int8_t dma_timings[] = { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 };
-
- mode = ata_check_80pin(dev, ata_limit_mode(dev, mode, ATA_UDMA6));
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- pci_write_config(gparent, 0xab, pio_timings[ata_mode2idx(mode)], 1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, 0xb3,
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) {
+ int piomode;
+ u_int8_t pio_timings[] = { 0xa8, 0x65, 0x65, 0x32, 0x20 };
+ u_int8_t dma_timings[] = { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 };
+
+ /* This chip can't do WDMA. */
+ if (mode >= ATA_WDMA0 && mode < ATA_UDMA0)
+ mode = ATA_PIO4;
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, 0xb3,
dma_timings[mode & ATA_MODE_MASK], 1);
- atadev->mode = mode;
- }
- }
- else
- ata_sata_setmode(dev, mode);
+ piomode = ATA_PIO4;
+ } else
+ piomode = mode;
+ pci_write_config(parent, 0xab, pio_timings[ata_mode2idx(piomode)], 1);
+ } else
+ mode = ata_sata_setmode(dev, target, mode);
+ return (mode);
}
-static void
-ata_via_old_setmode(device_t dev, int mode)
+static int
+ata_via_old_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- int modes[][7] = {
- { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */
- { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */
- { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */
- { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */
- int devno = (ch->unit << 1) + atadev->unit;
- int reg = 0x53 - devno;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- if (ctlr->chip->cfg1 != VIA133)
- pci_write_config(gparent, reg - 0x08,timings[ata_mode2idx(mode)],1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, reg,
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int reg = 0x53 - devno;
+ int piomode;
+ uint8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
+ uint8_t modes[][7] = {
+ { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */
+ { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */
+ { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */
+ { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */
+
+ mode = min(mode, ctlr->chip->max_dma);
+ /* Set UDMA timings */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, reg,
modes[ctlr->chip->cfg1][mode & ATA_MODE_MASK], 1);
- else
- pci_write_config(gparent, reg, 0x8b, 1);
- atadev->mode = mode;
- }
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, reg, 0x8b, 1);
+ piomode = mode;
+ }
+ /* Set WDMA/PIO timings */
+ if (ctlr->chip->cfg1 != VIA133)
+ pci_write_config(parent, reg - 0x08,timings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
static void
diff --git a/sys/powerpc/powermac/ata_dbdma.c b/sys/powerpc/powermac/ata_dbdma.c
index b08ade6..c8f3758 100644
--- a/sys/powerpc/powermac/ata_dbdma.c
+++ b/sys/powerpc/powermac/ata_dbdma.c
@@ -204,7 +204,6 @@ static int
ata_dbdma_load(struct ata_request *request, void *addr, int *entries)
{
struct ata_channel *ch = device_get_softc(request->parent);
- struct ata_device *atadev = device_get_softc(request->dev);
struct ata_dbdma_dmaload_args args;
int error;
@@ -230,7 +229,7 @@ ata_dbdma_load(struct ata_request *request, void *addr, int *entries)
return EIO;
}
- request->dma = &ch->dma.slot[atadev->unit];
+ request->dma = &ch->dma.slot[0];
if ((error = bus_dmamap_load(request->dma->data_tag,
request->dma->data_map, request->data, request->bytecount,
diff --git a/sys/powerpc/powermac/ata_kauai.c b/sys/powerpc/powermac/ata_kauai.c
index 415d0fb..f7b6daa 100644
--- a/sys/powerpc/powermac/ata_kauai.c
+++ b/sys/powerpc/powermac/ata_kauai.c
@@ -85,7 +85,7 @@ __FBSDID("$FreeBSD$");
*/
static int ata_kauai_probe(device_t dev);
static int ata_kauai_attach(device_t dev);
-static void ata_kauai_setmode(device_t parent, device_t dev);
+static int ata_kauai_setmode(device_t dev, int target, int mode);
static int ata_kauai_begin_transaction(struct ata_request *request);
static device_method_t ata_kauai_methods[] = {
@@ -307,34 +307,26 @@ ata_kauai_attach(device_t dev)
return ata_attach(dev);
}
-static void
-ata_kauai_setmode(device_t parent, device_t dev)
+static int
+ata_kauai_setmode(device_t dev, int target, int mode)
{
- struct ata_device *atadev = device_get_softc(dev);
- struct ata_kauai_softc *sc = device_get_softc(parent);
- uint32_t mode;
-
- mode = ata_limit_mode(dev,atadev->mode,
- (sc->shasta) ? ATA_UDMA6 : ATA_UDMA5);
-
- if (ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- return;
+ struct ata_kauai_softc *sc = device_get_softc(dev);
- atadev->mode = mode;
+ mode = min(mode,sc->shasta ? ATA_UDMA6 : ATA_UDMA5);
if (sc->shasta) {
switch (mode & ATA_DMA_MASK) {
case ATA_UDMA0:
- sc->udmaconf[atadev->unit]
+ sc->udmaconf[target]
= udma_timing_shasta[mode & ATA_MODE_MASK];
break;
case ATA_WDMA0:
- sc->udmaconf[atadev->unit] = 0;
- sc->wdmaconf[atadev->unit]
+ sc->udmaconf[target] = 0;
+ sc->wdmaconf[target]
= dma_timing_shasta[mode & ATA_MODE_MASK];
break;
default:
- sc->pioconf[atadev->unit]
+ sc->pioconf[target]
= pio_timing_shasta[(mode & ATA_MODE_MASK) -
ATA_PIO0];
break;
@@ -342,32 +334,33 @@ ata_kauai_setmode(device_t parent, device_t dev)
} else {
switch (mode & ATA_DMA_MASK) {
case ATA_UDMA0:
- sc->udmaconf[atadev->unit]
+ sc->udmaconf[target]
= udma_timing_kauai[mode & ATA_MODE_MASK];
break;
case ATA_WDMA0:
- sc->udmaconf[atadev->unit] = 0;
- sc->wdmaconf[atadev->unit]
+ sc->udmaconf[target] = 0;
+ sc->wdmaconf[target]
= dma_timing_kauai[mode & ATA_MODE_MASK];
break;
default:
- sc->pioconf[atadev->unit]
+ sc->pioconf[target]
= pio_timing_kauai[(mode & ATA_MODE_MASK)
- ATA_PIO0];
break;
}
}
+
+ return (mode);
}
static int
ata_kauai_begin_transaction(struct ata_request *request)
{
- struct ata_device *atadev = device_get_softc(request->dev);
struct ata_kauai_softc *sc = device_get_softc(request->parent);
- bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[atadev->unit]);
+ bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[request->unit]);
bus_write_4(sc->sc_memr, PIO_CONFIG_REG,
- sc->wdmaconf[atadev->unit] | sc->pioconf[atadev->unit]);
+ sc->wdmaconf[request->unit] | sc->pioconf[request->unit]);
return ata_begin_transaction(request);
}
diff --git a/sys/powerpc/powermac/ata_macio.c b/sys/powerpc/powermac/ata_macio.c
index 320e86e..447009d 100644
--- a/sys/powerpc/powermac/ata_macio.c
+++ b/sys/powerpc/powermac/ata_macio.c
@@ -111,7 +111,7 @@ static const struct ide_timings udma_timings[5] = {
* Define the macio ata bus attachment.
*/
static int ata_macio_probe(device_t dev);
-static void ata_macio_setmode(device_t parent, device_t dev);
+static int ata_macio_setmode(device_t dev, int target, int mode);
static int ata_macio_attach(device_t dev);
static int ata_macio_begin_transaction(struct ata_request *request);
@@ -193,7 +193,7 @@ ata_macio_probe(device_t dev)
ata_default_registers(dev);
ch->unit = 0;
- ch->flags |= ATA_USE_16BIT;
+ ch->flags |= ATA_USE_16BIT | ATA_NO_ATAPI_DMA;
ata_generic_hw(dev);
return (ata_probe(dev));
@@ -247,26 +247,15 @@ ata_macio_attach(device_t dev)
return ata_attach(dev);
}
-static void
-ata_macio_setmode(device_t parent, device_t dev)
+static int
+ata_macio_setmode(device_t dev, int target, int mode)
{
- struct ata_device *atadev = device_get_softc(dev);
- struct ata_macio_softc *sc = device_get_softc(parent);
- int mode = atadev->mode;
+ struct ata_macio_softc *sc = device_get_softc(dev);
int min_cycle = 0, min_active = 0;
int cycle_tick = 0, act_tick = 0, inact_tick = 0, half_tick;
- mode = ata_limit_mode(dev, mode, sc->max_mode);
-
- /* XXX Some controllers don't work correctly with ATAPI DMA */
- if (atadev->param.config & ATA_PROTO_ATAPI)
- mode = ata_limit_mode(dev, mode, ATA_PIO_MAX);
-
- if (ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- return;
-
- atadev->mode = mode;
+ mode = min(mode, sc->max_mode);
if ((mode & ATA_DMA_MASK) == ATA_UDMA0) {
min_cycle = udma_timings[mode & ATA_MODE_MASK].cycle;
@@ -276,7 +265,7 @@ ata_macio_setmode(device_t parent, device_t dev)
act_tick = ATA_TIME_TO_TICK(sc->rev,min_active);
/* mask: 0x1ff00000 */
- sc->udmaconf[atadev->unit] =
+ sc->udmaconf[target] =
(cycle_tick << 21) | (act_tick << 25) | 0x100000;
} else if ((mode & ATA_DMA_MASK) == ATA_WDMA0) {
min_cycle = dma_timings[mode & ATA_MODE_MASK].cycle;
@@ -288,7 +277,7 @@ ata_macio_setmode(device_t parent, device_t dev)
if (sc->rev == 4) {
inact_tick = cycle_tick - act_tick;
/* mask: 0x001ffc00 */
- sc->wdmaconf[atadev->unit] =
+ sc->wdmaconf[target] =
(act_tick << 10) | (inact_tick << 15);
} else {
inact_tick = cycle_tick - act_tick - DMA_REC_OFFSET;
@@ -297,7 +286,7 @@ ata_macio_setmode(device_t parent, device_t dev)
half_tick = 0; /* XXX */
/* mask: 0xfffff800 */
- sc->wdmaconf[atadev->unit] = (half_tick << 21)
+ sc->wdmaconf[target] = (half_tick << 21)
| (inact_tick << 16) | (act_tick << 11);
}
} else {
@@ -313,7 +302,7 @@ ata_macio_setmode(device_t parent, device_t dev)
inact_tick = cycle_tick - act_tick;
/* mask: 0x000003ff */
- sc->pioconf[atadev->unit] =
+ sc->pioconf[target] =
(inact_tick << 5) | act_tick;
} else {
if (act_tick < PIO_ACT_MIN)
@@ -324,21 +313,22 @@ ata_macio_setmode(device_t parent, device_t dev)
inact_tick = PIO_REC_MIN;
/* mask: 0x000007ff */
- sc->pioconf[atadev->unit] =
+ sc->pioconf[target] =
(inact_tick << 5) | act_tick;
}
}
+
+ return (mode);
}
static int
ata_macio_begin_transaction(struct ata_request *request)
{
- struct ata_device *atadev = device_get_softc(request->dev);
struct ata_macio_softc *sc = device_get_softc(request->parent);
bus_write_4(sc->sc_mem, ATA_MACIO_TIMINGREG,
- sc->udmaconf[atadev->unit] | sc->wdmaconf[atadev->unit]
- | sc->pioconf[atadev->unit]);
+ sc->udmaconf[request->unit] | sc->wdmaconf[request->unit]
+ | sc->pioconf[request->unit]);
return ata_begin_transaction(request);
}
diff --git a/sys/powerpc/psim/ata_iobus.c b/sys/powerpc/psim/ata_iobus.c
index a70d008..149437f 100644
--- a/sys/powerpc/psim/ata_iobus.c
+++ b/sys/powerpc/psim/ata_iobus.c
@@ -210,7 +210,7 @@ ata_iobus_release_resource(device_t dev, device_t child, int type, int rid,
*/
static int ata_iobus_sub_probe(device_t dev);
-static void ata_iobus_sub_setmode(device_t parent, device_t dev);
+static int ata_iobus_sub_setmode(device_t dev, int target, int mode);
static device_method_t ata_iobus_sub_methods[] = {
/* Device interface */
@@ -245,11 +245,9 @@ ata_iobus_sub_probe(device_t dev)
return ata_probe(dev);
}
-static void
-ata_iobus_sub_setmode(device_t parent, device_t dev)
+static int
+ata_iobus_sub_setmode(device_t parent, int target, int mode);
{
- struct ata_device *atadev = device_get_softc(dev);
-
/* Only ever PIO mode here... */
- atadev->mode = ATA_PIO;
+ return (ATA_PIO);
}
OpenPOWER on IntegriCloud