summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/atacontrol/atacontrol.c23
-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
45 files changed, 1612 insertions, 1190 deletions
diff --git a/sbin/atacontrol/atacontrol.c b/sbin/atacontrol/atacontrol.c
index 49e4fa2..29599eb 100644
--- a/sbin/atacontrol/atacontrol.c
+++ b/sbin/atacontrol/atacontrol.c
@@ -42,7 +42,7 @@
static const char *
mode2str(int mode)
{
- switch (mode) {
+ switch (mode & 0xff) {
case ATA_PIO: return "BIOSPIO";
case ATA_PIO0: return "PIO0";
case ATA_PIO1: return "PIO1";
@@ -59,13 +59,23 @@ mode2str(int mode)
case ATA_UDMA4: return "UDMA66";
case ATA_UDMA5: return "UDMA100";
case ATA_UDMA6: return "UDMA133";
- case ATA_SA150: return "SATA150";
- case ATA_SA300: return "SATA300";
case ATA_DMA: return "BIOSDMA";
default: return "???";
}
}
+static const char *
+satarev2str(int mode)
+{
+ switch ((mode & 0xff00) >> 8) {
+ case 0: return "";
+ case 1: return "SATA 1.5Gb/s";
+ case 2: return "SATA 3Gb/s";
+ case 3: return "SATA 6Gb/s";
+ default: return "???";
+ }
+}
+
static int
str2mode(char *str)
{
@@ -79,7 +89,9 @@ str2mode(char *str)
if (!strcasecmp(str, "WDMA1")) return ATA_WDMA1;
if (!strcasecmp(str, "WDMA2")) return ATA_WDMA2;
if (!strcasecmp(str, "UDMA0")) return ATA_UDMA0;
+ if (!strcasecmp(str, "UDMA16")) return ATA_UDMA0;
if (!strcasecmp(str, "UDMA1")) return ATA_UDMA1;
+ if (!strcasecmp(str, "UDMA25")) return ATA_UDMA1;
if (!strcasecmp(str, "UDMA2")) return ATA_UDMA2;
if (!strcasecmp(str, "UDMA33")) return ATA_UDMA2;
if (!strcasecmp(str, "UDMA3")) return ATA_UDMA3;
@@ -90,8 +102,6 @@ str2mode(char *str)
if (!strcasecmp(str, "UDMA100")) return ATA_UDMA5;
if (!strcasecmp(str, "UDMA6")) return ATA_UDMA6;
if (!strcasecmp(str, "UDMA133")) return ATA_UDMA6;
- if (!strcasecmp(str, "SATA150")) return ATA_SA150;
- if (!strcasecmp(str, "SATA300")) return ATA_SA300;
if (!strcasecmp(str, "BIOSDMA")) return ATA_DMA;
return -1;
}
@@ -382,7 +392,8 @@ main(int argc, char **argv)
if (argc == 3 || argc == 4) {
if (ioctl(fd, IOCATAGMODE, &mode) < 0)
err(1, "ioctl(IOCATAGMODE)");
- printf("current mode = %s\n", mode2str(mode));
+ printf("current mode = %s %s\n",
+ mode2str(mode), satarev2str(mode));
}
exit(EX_OK);
}
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