507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CDDL HEADER START
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The contents of this file are subject to the terms of the
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * Common Development and Distribution License (the "License").
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * You may not use this file except in compliance with the License.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * See the License for the specific language governing permissions
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and limitations under the License.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * When distributing Covered Code, include this CDDL HEADER in each
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If applicable, add the following below this CDDL HEADER, with the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * fields enclosed by brackets "[]" replaced with your own identifying
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * information: Portions Copyright [yyyy] [name of copyright owner]
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CDDL HEADER END
0f1b305ee9e700c825d9e9ad1ea1e4311d212eb2Seth Goldberg * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Use is subject to license terms.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Solaris Entry Points.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_bus_ctl(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t o,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf void *a, void *v);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD Entry points
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_get_status(void *hba_handle, void *intr_status);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void ata_process_intr(void *hba_handle, void *intr_status);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void ata_hba_complete(void *handle, gcmd_t *gcmdp, int do_callback);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_timeout_func(void *hba_handle, gcmd_t *gcmdp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Local Function Prototypes
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_prop_lookup_int(dev_t match_dev, dev_info_t *dip,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_ctlr_fsm(uchar_t fsm_func, ata_ctl_t *ata_ctlp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_init_drive_pcidma(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_flush_cache(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void ata_init_pciide(dev_info_t *dip, ata_ctl_t *ata_ctlp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_start_arq(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_check_pciide_blacklist(dev_info_t *dip, uint_t flags);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_check_revert_to_defaults(ata_drv_t *ata_drvp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void ata_show_transfer_mode(ata_ctl_t *, ata_drv_t *);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Local static data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic tmr_t ata_timer_conf; /* single timeout list for all instances */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic int ata_watchdog_usec = 100000; /* check timeouts every 100 ms */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Use local or framework power management
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#define ATA_BUSY_COMPONENT(d, c) ((void)pm_busy_component(d, c))
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#define ATA_IDLE_COMPONENT(d, c) ((void)pm_idle_component(d, c))
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#define ATA_RAISE_POWER(d, c, l) pm_raise_power(d, c, l)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#define ATA_LOWER_POWER(d, c, l) pm_lower_power(d, c, l)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * number of seconds to wait during various operations
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfuint_t ata_flush_cache_wait = 60 * 1000000; /* may take a long time */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Change this for SFF-8070i support. Currently SFF-8070i is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * using a field in the IDENTIFY PACKET DEVICE response which
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * already seems to be in use by some vendor's drives. I suspect
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SFF will either move their laslun field or provide a reliable
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * way to validate it.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * set this to disable all DMA requests
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * set this to TRUE to enable storing the IDENTIFY DEVICE result in the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * "ata" or "atapi" property.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * set this to TRUE to enable logging device-capability data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * DMA selection message pointers
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * bus nexus operations
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfata_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ddi_get_soft_state(ata_state, getminor(*devp)) == NULL)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The purpose of this function is to pass the ioaddress of the controller
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * to the caller, specifically used for upgrade from pre-pciide
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * to pciide nodes
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp = ddi_get_soft_state(ata_state, getminor(dev));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (void) sprintf(buf, "%p\n", (void *) ata_ctlp->ac_ioaddr1);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (uiomove((caddr_t)(buf + uio_p->uio_offset), len,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * reset ATA drives and flush the write cache of any drives
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (i = 0; i < ATA_MAXTARG; i++) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Don't revert to defaults for certain IBM drives */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Enable revert to defaults when reset */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * skip flush cache if device type is cdrom
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * notes: the structure definitions for ata_drvp->ad_id are
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * defined for the ATA IDENTIFY_DEVICE, but if AD_ATAPI is set
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the struct holds data for the ATAPI IDENTIFY_PACKET_DEVICE
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Try the ATA/ATAPI flush write cache command
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * do something else if flush cache not supported
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * just busy wait if any drive doesn't support FLUSH CACHE
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (0);
193974072f41a843678abf5f61979c748687e66bSherry Moore * quiesce(9E) entry point.
193974072f41a843678abf5f61979c748687e66bSherry Moore * This function is called when the system is single-threaded at high
193974072f41a843678abf5f61979c748687e66bSherry Moore * PIL with preemption disabled. Therefore, this function must not be
193974072f41a843678abf5f61979c748687e66bSherry Moore * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
193974072f41a843678abf5f61979c748687e66bSherry Moore * DDI_FAILURE indicates an error condition and should almost never happen.
193974072f41a843678abf5f61979c748687e66bSherry Moore * Turn off debugging
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf 0, /* refcnt */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* driver loadable module wrapper */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf &mod_driverops, /* Type of module. This one is a driver */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "ATA AT-bus attachment disk controller Driver", /* module name */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* | ADBG_FLAG_ARQ */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* | ADBG_FLAG_INIT */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* | ADBG_FLAG_TRACE */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* | ADBG_FLAG_TRANSPORT */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* | ADBG_FLAG_WARN */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((err = ddi_soft_state_init(&ata_state, sizeof (ata_ctl_t), 0)) != 0)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* save pointer to SCSA provided bus_ops struct */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* make a copy of SCSA bus_ops */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Modify our bus_ops to call our routines. Our implementation
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * will determine if the device is ATA or ATAPI/SCSA and react
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * accordingly.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* patch our bus_ops into the dev_ops struct */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Initialize the per driver timer info.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_timer_init(&ata_timer_conf, drv_usectohz(ata_watchdog_usec));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * driver attach entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* initialize controller */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* initialize drives */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * LUN support is currently disabled. Check with SFF-8070i
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * before enabling.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Initialize higher LUNs, if there are any */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (lun = 1; lun <= lastlun && lun < ATA_MAXLUN; lun++) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Always make certain that a valid drive is selected so
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * that routines which poll the status register don't get
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * confused by non-existent drives.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * make certain the drive selected
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ata_wait(ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * initialize atapi/ata_dsk modules if we have at least
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * one drive of that type.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * make certain the interrupt and error latches are clear
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ddi_create_minor_node(dip, "control", S_IFCHR, instance,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * enable the interrupt handler and drop the mutex
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* driver detach entry point */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components");
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* destroy ata module */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* destroy atapi module */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* destroy drives */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (i = 0; i < ATA_MAXTARG; i++) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (j = 0; j < ATA_MAXLUN; j++) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* destroy controller */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Nexus driver bus_ctl entry point
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*ARGSUSED*/
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf switch (o) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Since we use PIO, we return a minimum I/O size of
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * one byte. This will need to be updated when we
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * implement DMA support
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *((int *)v) = 1;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* These ops shouldn't be called by a target driver */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ERROR(("ata_bus_ctl: %s%d: invalid op (%d) from %s%d\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* these require special handling below */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ddi_ctlops(d, r, o, a, v));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* get targets dip */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (o == DDI_CTLOPS_INITCHILD || o == DDI_CTLOPS_UNINITCHILD)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * XXX - Get class of target
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Before the "class" entry in a conf file becomes
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * a real property, we use an additional property
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * tentatively called "class_prop". We will require that
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * new classes (ie. direct) export "class_prop".
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * SCSA target drivers will not have this property, so
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * no property implies SCSA.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (ddi_prop_lookup_string(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf target_type = ATA_DEV_ATAPI; /* no class prop, assume SCSI */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctl_t *ata_ctlp = ddi_get_soft_state(ata_state, instance);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("ata_bus_ctl: failed to find ctl struct\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* get (target,lun) of child device */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf targ = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf lun = ddi_prop_get_int(DDI_DEV_T_ANY, tdip, DDI_PROP_DONTPASS,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* get type of device */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check for special handling when child driver is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * cmdk (which morphs to the correct interface)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "create disk prop\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "create class prop\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Check that target class matches the device */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* save pointer to drive struct for ata_disk_bus_ctl */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Determine whether to enable DMA support for this drive. This
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check is deferred to this point so that the various dma
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * properties could reside on the devinfo node should finer
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * grained dma control be required.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD ccc_hba_complete callback
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* GHD ccc_timeout_func callback */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* abort before request was started */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* timeout before request was started */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Reset a device is not supported. Resetting a specific
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * device can't be done at all to an ATA device and if
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * you send a RESET to an ATAPI device you have to
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * reset the whole bus to make certain both devices
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * on the bus stay in sync regarding which device is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the currently selected one.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Issue bus reset and reinitialize both drives.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * But only if this is a timed-out request. Target
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * driver reset requests are ignored because ATA
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and ATAPI devices shouldn't be gratuitously reset.
5fb86bae323519d98a63f5829df4b849f1fe1598ml * Also disable DMA if it is a CF device.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Initialize controller's soft-state structure
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* allocate controller structure */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ddi_soft_state_zalloc(ata_state, instance) != DDI_SUCCESS) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("ata_init_controller: soft_state_zalloc failed\n"));
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "controller struct\n"));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * initialize per-controller data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_arq_pktp = kmem_zalloc(sizeof (ata_pkt_t), KM_SLEEP);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * map the device registers
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ata_setup_ioaddr(dip, &ata_ctlp->ac_iohandle1, &ioaddr1,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_INIT(("ata_init_controller: ioaddr1 = 0x%p, ioaddr2 = 0x%p\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Do ARQ setup
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Do PCI-IDE setup
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * port addresses associated with ioaddr1
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * port addresses associated with ioaddr2
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_altstatus = (uchar_t *)ioaddr2 + AT_ALTSTATUS;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If AC_BSY_WAIT needs to be set for laptops that do
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * suspend/resume but do not correctly wait for the busy bit to
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * drop after a resume.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_timing_flags = ddi_prop_get_int(DDI_DEV_T_ANY,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * get max transfer size, default to 256 sectors
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_max_transfer = ddi_prop_get_int(DDI_DEV_T_ANY,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Get the standby timer value
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_ctlp->ac_standby_time = ddi_prop_get_int(DDI_DEV_T_ANY,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If this is a /pci/pci-ide instance check to see if
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * it's supposed to be attached as an /isa/ata
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Init controller specific stuff */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * initialize GHD
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ghd_register("ata", &ata_ctlp->ac_ccc, dip, 0, ata_ctlp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* destroy a controller */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* destroy ghd */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* free the pciide buffer (if any) */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* destroy controller struct */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * initialize a drive
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("ata_init_drive entered, targ = %d, lun = %d\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* check if device already exists */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* allocate new device structure */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * set up drive struct
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf (ata_drvp->ad_targ == 0 ? ATDH_DRIVE0 : ATDH_DRIVE1);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Add the LUN for SFF-8070i support
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * get drive type, side effect is to collect
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * IDENTIFY DRIVE data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* no drive found */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * swap bytes of all text fields
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ata_strncmp(nec_260, aidp->ai_model, sizeof (aidp->ai_model))) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check if this drive has the Single Sector bug
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_1SECTOR))
8c112d45d87338e20826001e18cb9e22e5187658Colin Yi if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_LBA48))
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Check if this drive has the "revert to defaults" bug */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Dump the drive info */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (void) strncpy(buf, aidp->ai_model, sizeof (aidp->ai_model));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (i = sizeof (aidp->ai_model) - 2; buf[i] == ' '; i--)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ATAPRT(("?\t%s device at targ %d, lun %d lastlun 0x%x\n",
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ata_drvp->ad_targ, ata_drvp->ad_lun, aidp->ai_lastlun));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (aidp->ai_majorversion != 0 && aidp->ai_majorversion != 0xffff) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "?\tATA/ATAPI-%d supported, majver 0x%x minver 0x%x\n",
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_error)));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Be aware that ATA-6 and later drives may not provide valid
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * geometry information and other obsoleted info.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Select what is printed based on supported ATA model (skip
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * anything below ATA/ATAPI-3)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Supported version less then ATA-6
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (valid_version && aidp->ai_majorversion < ATAC_MAJVER_4) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "?\t\tpiomode 0x%x, dmamode 0x%x, advpiomode 0x%x\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (valid_version && aidp->ai_majorversion >= ATAC_MAJVER_4 &&
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * store pointer in controller struct
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * lock the drive's current settings in case I have to
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * reset the drive due to some sort of error
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* destroy a drive */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * DON'T DO THIS. disabling interrupts floats the IRQ line
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * which generates spurious interrupts
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Select the correct drive
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Disable interrupts from the drive
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* interface specific clean-ups */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* free drive struct */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ata_drive_type()
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The timeout values and exact sequence of checking is critical
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * especially for atapi device detection, and should not be changed lightly.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * select the appropriate drive and LUN
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_put8(io_hdl1, (uchar_t *)ioaddr1 + AT_DRVHD, drvhd);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * make certain the drive is selected, and wait for not busy
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (void) ata_wait3(io_hdl2, ioaddr2, 0, ATS_BSY, 0x7f, 0, 0x7f, 0,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf status = ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS);
9f49ae270d37efd5c5270cb8046b4229b5380021mlf ADBG_TRACE(("ata_drive_type 0x%p 0x%x\n", ioaddr1, status));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_disk_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp))
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * No disk, check for atapi unit.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check for old (but prevalent) atapi 1.7B
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * spec device, the only known example is the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * NEC CDR-260 (not 260R which is (mostly) ATAPI 1.2
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * compliant). This device has no signature
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and requires conversion from hex to BCD
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * for some scsi audio commands.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (atapi_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (atapi_id(io_hdl1, ioaddr1, io_hdl2, ioaddr2, ata_id_bufp)) {
9f49ae270d37efd5c5270cb8046b4229b5380021mlf * nsec-granularity time delay function
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Wait for a register of a controller to achieve a specific state.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * To return normally, all the bits in the first sub-mask must be ON,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * all the bits in the second sub-mask must be OFF.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If timeout_usec microseconds pass without the controller achieving
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the desired bit configuration, we return TRUE, else FALSE.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf val = ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_ALTSTATUS);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * This is a slightly more complicated version that checks
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * for error conditions and bails-out rather than looping
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * until the timeout expires
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf val = ddi_get8(io_hdl, (uchar_t *)ioaddr + AT_ALTSTATUS);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check for expected condition
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((val & onbits1) == onbits1 && (val & offbits1) == 0)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check for error conditions
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * low level routine for ata_disk_id() and atapi_id()
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * clear the features register
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * Disable interrupts from the device. When the ata
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * hardware is sharing its interrupt with another
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * device, the shared interrupt might have already been
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * unmasked in the interrupt controller and
9f49ae270d37efd5c5270cb8046b4229b5380021mlf * triggering ata device interrupts will result in an
9f49ae270d37efd5c5270cb8046b4229b5380021mlf * interrupt storm and a hung system.
9f49ae270d37efd5c5270cb8046b4229b5380021mlf ddi_put8(io_hdl2, (uchar_t *)ioaddr2 + AT_DEVCTL, ATDC_D3 | ATDC_NIEN);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * issue IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* wait for the busy bit to settle */
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * read alternate status and check for conditions which
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * may indicate the drive is not present, to prevent getting
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * stuck in ata_wait3() below.
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf status = ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS);
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * 0x0, 0x7f, or ATS_DF can happen when no drive is present
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf /* invalid status, can't be an ATA or ATAPI device */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * According to the ATA specification, some drives may have
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * to read the media to complete this command. We need to
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * make sure we give them enough time to respond.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * read the status byte and clear the pending interrupt
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf status = ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_STATUS);
b3c0e203b148ecc85043c9da9d327d45c6e7c470mlf * this happens if there's no drive present
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* invalid status, can't be an ATA or ATAPI device */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ERROR(("ata_id_common: BUSY status 0x%x error 0x%x\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Give the drive another second to assert DRQ. Some older
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic * drives de-assert BSY before asserting DRQ. Bail out
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic * immediately if the status becomes 0x7f, which is invalid
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic * value. It can happen when no drive is present.
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic if (!ata_wait3(io_hdl2, ioaddr2, ATS_DRQ, ATS_BSY, 0x7f,
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic ATS_BSY, 0x7f, ATS_BSY, 1000000)) {
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic ADBG_WARN(("ata_id_common: "
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic "!DRQ status 0x%x error 0x%x\n",
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic ddi_get8(io_hdl2, (uchar_t *)ioaddr2 +AT_ALTSTATUS),
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic ddi_get8(io_hdl1, (uchar_t *)ioaddr1 + AT_ERROR)));
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic return (FALSE);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * transfer the data
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_rep_get16(io_hdl1, (ushort_t *)aidp, (ushort_t *)ioaddr1 + AT_DATA,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* wait for the busy bit to settle */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Wait for the drive to recognize I've read all the data.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Some drives have been observed to take as much as 3msec to
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic * deassert DRQ after reading the data; allow 1 sec just in case.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Note: some non-compliant ATAPI drives (e.g., NEC Multispin 6V,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CDR-1350A) don't assert DRDY. If we've made it this far we can
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * safely ignore the DRDY bit since the ATAPI Packet command
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * actually doesn't require it to ever be asserted.
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic * Bail out immediately if the status becomes 0x7f, which is invalid
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic * value. It can happen when no drive is present.
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic *
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic if (!ata_wait3(io_hdl2, ioaddr2, (uchar_t)(expect_drdy ? ATS_DRDY : 0),
ab5a7454a6d76e82a121d74c74d5589cc3d37a8fvitezslav batrla - Sun Microsystems - Prague Czech Republic (ATS_BSY | ATS_DRQ), 0x7f, ATS_BSY, 0x7f, ATS_BSY, 1000000)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("ata_id_common: bad status 0x%x error 0x%x\n",
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check to see if the command aborted. This happens if
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * an IDENTIFY DEVICE command is issued to an ATAPI PACKET device,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * or if an IDENTIFY PACKET DEVICE command is issued to an ATA
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * (non-PACKET) device.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ddi_get8(io_hdl2, (uchar_t *)ioaddr2 + AT_ALTSTATUS),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Low level routine to issue a non-data command and busy wait for
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the completion status.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* select the drive */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, ata_drvp->ad_drive_bits);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* make certain the drive selected */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x "
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * set all the regs
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_put8(io_hdl1, ata_ctlp->ac_drvhd, (head | ata_drvp->ad_drive_bits));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* send the command */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* wait for the busy bit to settle */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* wait for not busy */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ata_wait(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY, busy_wait)) {
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x "
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * wait for DRDY before continuing
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* read status to clear IRQ, and check for error */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "DRDY 0x%x CMD 0x%x F 0x%x N 0x%x "
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "S 0x%x H 0x%x CL 0x%x CH 0x%x\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Issue a SET FEATURES command
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ata_command(ata_ctlp, ata_drvp, TRUE, TRUE, ata_set_feature_wait,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /* feature, count, sector, head, cyl_low, cyl_hi */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ERROR(("?ata_set_feature: (0x%x,0x%x) failed\n", feature, value));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Issue a FLUSH CACHE command
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* this command is optional so fail silently */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ATC_FLUSH_CACHE, 0, 0, 0, 0, 0, 0));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ata_setup_ioaddr()
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Map the device registers and return the handles.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If this is a ISA-ATA controller then only two handles are
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * initialized and returned.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If this is a PCI-IDE controller than a third handle (for the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * PCI-IDE Bus Mastering registers) is initialized and returned.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Make certain the controller is enabled and its regs are map-able
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * setup the device attribute structure for little-endian,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * strict ordering access.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Determine whether this is a ISA, PNP-ISA, or PCI-IDE device
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "pnp-csn")) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* it's PNP-ISA, skip over the extra reg tuple */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* else, it's ISA or PCI-IDE, check further */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If it's not a PCI-IDE, there are only two reg tuples
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and the first one contains the I/O base (170 or 1f0)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * rather than the controller instance number.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Map the correct half of the PCI-IDE Bus Master registers.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * There's a single BAR that maps these registers for both
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * controller's in a dual-controller chip and it's upto my
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * parent nexus, pciide, to adjust which (based on my instance
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * number) half this call maps.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ddi_regs_map_setup(dip, 2, bm_addrp, 0, 0, &dev_attr, bm_hdlp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* map failed, try to use in non-pci-ide mode */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_WARN(("ata_setup_ioaddr bus master map failed, rc=0x%x\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * map the lower command block registers
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ddi_regs_map_setup(dip, rnumber, addr1p, 0, 0, &dev_attr,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf cmn_err(CE_WARN, "ata: reg tuple 0 map failed, rc=0x%x\n", rc);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If the controller is being used in compatibility mode
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * via /devices/isa/ata@1,{1f0,1f0}/..., the reg property
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * will specify zeros for the I/O ports for the PCI
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * instance.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (*addr1p == 0) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * map the upper control block registers
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ddi_regs_map_setup(dip, rnumber + 1, addr2p, 0, 0, &dev_attr,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf cmn_err(CE_WARN, "ata: reg tuple 1 map failed, rc=0x%x", rc);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Currently, the only supported controllers are ones which
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * support the SFF-8038 Bus Mastering spec.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check the parent node's IEEE 1275 class-code property to
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * determine if it's an PCI-IDE instance which supports SFF-8038
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Bus Mastering. It's perfectly valid to have a PCI-IDE controller
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * that doesn't do Bus Mastering. In that case, my interrupt handler
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * only uses the interrupt latch bit in PCI-IDE status register.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The assumption is that the programming interface byte of the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * class-code property reflects the bus master DMA capability of
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the controller.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Whether the drive support supports the DMA option still needs
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * to be checked later. Each individual request also has to be
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * checked for alignment and size to decide whether to use the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * DMA transfer mode.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_cntrl_DMA_sel_msg = "cntrl not Bus Master DMA capable";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check if it's a known bogus PCI-IDE chip
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_check_pciide_blacklist(dip, ATA_BL_BMSTATREG_PIO_BROKEN)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check for a PCI-IDE chip with a broken DMA engine
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "cntrl blacklisted/DMA engine broken";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check the Programming Interface register to determine
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * if this device supports PCI-IDE Bus Mastering. Some PCI-IDE
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * devices don't support Bus Mastering or DMA.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Since we are dealing with pre-qualified pci-ide controller,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * check programming interface byte only.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf class_code = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((class_code & PCIIDE_BM_CAP_MASK) != PCIIDE_BM_CAP_MASK) {
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "cntrl not Bus Master DMA capable";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Avoid doing DMA on "simplex" chips which share hardware
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * between channels
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Some motherboards have CSB5's that are wired "to emulate CSB4 mode".
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * In such a mode, the simplex bit is asserted, but in fact testing
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * on such a motherboard has shown that the devices are not simplex
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * -- DMA can be used on both channels concurrently with no special
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * considerations. For chips like this, we have the ATA_BL_NO_SIMPLEX
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * flag set to indicate that the value of the simplex bit can be
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ignored.
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf if (ata_check_pciide_blacklist(dip, ATA_BL_NO_SIMPLEX)) {
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * By default,use DMA on channel 0 and PIO on channel
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * 1. This can be switched by setting
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * ata-simplex-dma-channel to:
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * 0 DMA on channel 0 (default without this
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * property)
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * 1 DMA on channel 1
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf * any other value: DMA off on both channels.
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf simplex_dma_channel = ata_prop_lookup_int(DDI_DEV_T_ANY,
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf "controller. DMA on channel"
ab4f33c9d90dd2fe40a830e0db03f337b4b65b21ml " %d PIO on channel %d",
d39757aa11b7b514615ceb1ec0388a6d0521a202mlf "simplex controller";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * It's a compatible PCI-IDE Bus Mastering controller,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * allocate and map the DMA Scatter/Gather list (PRDE table).
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Determine whether to enable DMA support for this drive.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The controller and the drive both have to support DMA.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The controller's capabilities were already checked in
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ata_init_pciide(), now just check the drive's capabilities.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "controller is not Bus Master capable";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_options = ddi_prop_get_int(DDI_DEV_T_ANY, ata_ctlp->ac_dip,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf 0, "ata-options", 0);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Either the ata-options property was not found or
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * DMA is not enabled by this property
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "disabled by \"ata-options\" property";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (ata_check_drive_blacklist(&ata_drvp->ad_id, ATA_BL_NODMA)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_dev_DMA_sel_msg = "device not DMA capable; blacklisted";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * DMA mode is mandatory on ATA-3 (or newer) drives but is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * optional on ATA-2 (or older) drives.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * On ATA-2 drives the ai_majorversion word will probably
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * be 0xffff or 0x0000, check the (now obsolete) DMA bit in
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the capabilities word instead. The order of these tests
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * is important since an ATA-3 drive doesn't have to set
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the DMA bit in the capabilities word.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!((ata_drvp->ad_id.ai_majorversion & 0x8000) == 0 &&
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China * Disable DMA for ATAPI devices on controllers known to
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China * have trouble with ATAPI DMA
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China if (ATAPIDRV(ata_drvp)) {
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China if (ata_check_pciide_blacklist(ata_ctlp->ac_dip,
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China ATA_BL_ATAPI_NODMA)) {
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China ata_dev_DMA_sel_msg =
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China "controller incapable of DMA for ATAPI device";
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China return (ATA_DMA_OFF);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "DMA disabled by \"ata-dma-enabled\" property");
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_dev_DMA_sel_msg = "disabled by prop ata-dma-enabled";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "disabled. Control with \"atapi-cd-dma-enabled\""
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf " property";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "disabled by \"ata-disk-dma-enabled\" property";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "disabled by \"atapi-other-dma-enabled\" property";
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * this compare routine squeezes out extra blanks and
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * returns TRUE if p1 matches the leftmost substring of p2
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (;;) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * skip over any extra blanks in both strings
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * compare the two strings
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* return TRUE if both strings ended at same point */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Per PSARC/1997/281 create variant="atapi" property (if necessary)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * on the target's dev_info node. Currently, the sd target driver
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * is the only driver which refers to this property.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If the flag ata_id_debug is set also create the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the "ata" or "atapi" property on the target's dev_info node
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("ata_prop_create 0x%p 0x%p %s\n", tgt_dip, ata_drvp, name));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ndi_prop_update_byte_array(DDI_DEV_T_NONE, tgt_dip, name,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf (uchar_t *)&ata_drvp->ad_id, sizeof (ata_drvp->ad_id));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* *********************************************************************** */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* *********************************************************************** */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* *********************************************************************** */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * This state machine doesn't implement the ATAPI Optional Overlap
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * feature. You need that feature to efficiently support ATAPI
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * tape drives. See the 1394-ATA Tailgate spec (D97107), Figure 24,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * for an example of how to add the necessary additional NextActions
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and NextStates to this FSM and the atapi_fsm, in order to support
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the Overlap Feature.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfuchar_t ata_ctlr_fsm_NextAction[ATA_CTLR_NSTATES][ATA_CTLR_NFUNCS] = {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* --------------------- next action --------------------- | - current - */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* start0 --- start1 ---- intr ------ fini --- reset --- */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{ AC_START, AC_START, AC_NADA, AC_NADA, AC_RESET_I }, /* idle */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{ AC_BUSY, AC_BUSY, AC_INTR, AC_FINI, AC_RESET_A }, /* active0 */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{ AC_BUSY, AC_BUSY, AC_INTR, AC_FINI, AC_RESET_A }, /* active1 */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfuchar_t ata_ctlr_fsm_NextState[ATA_CTLR_NSTATES][ATA_CTLR_NFUNCS] = {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* --------------------- next state --------------------- | - current - */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* start0 --- start1 ---- intr ------ fini --- reset --- */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{ AS_ACTIVE0, AS_ACTIVE1, AS_IDLE, AS_IDLE, AS_IDLE }, /* idle */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{ AS_ACTIVE0, AS_ACTIVE0, AS_ACTIVE0, AS_IDLE, AS_ACTIVE0 }, /* active0 */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{ AS_ACTIVE1, AS_ACTIVE1, AS_ACTIVE1, AS_IDLE, AS_ACTIVE1 }, /* active1 */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf action = ata_ctlr_fsm_NextAction[current_state][fsm_func];
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf next_state = ata_ctlr_fsm_NextState[current_state][fsm_func];
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Set the controller's new state
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = (*ata_pktp->ap_start)(ata_ctlp, ata_drvp, ata_pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* the request didn't start, GHD will requeue it */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return ((*ata_pktp->ap_intr)(ata_ctlp, ata_drvp, ata_pktp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* clean up the active request */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* halt the DMA engine */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Do a Software Reset to unwedge the bus */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Then send a DEVICE RESET cmd to each ATAPI device */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Do a Software Reset to unwedge the bus */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Then send a DEVICE RESET cmd to each ATAPI device */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * AC_FINI, check ARQ needs to be started or finished
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The active request is done now.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Disconnect the request from the controller and
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * add it to the done queue.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If ARQ pkt is done, get ptr to original pkt and wrap it up.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#define AP_ARQ_NEEDED (AP_ARQ_ON_ERROR | AP_GOT_STATUS | AP_ERROR)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Start ARQ pkt if necessary
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if ((ata_pktp->ap_flags & AP_ARQ_NEEDED) == AP_ARQ_NEEDED &&
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* set controller state back to active */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* try to start the ARQ pkt */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* let the target driver handle the problem */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ARQ(("ata_ctlr_fsm 0x%p ARQ started\n", ata_ctlp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Normal completion, no error status, and not an ARQ pkt,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * just fall through.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * wrap everything up and tie a ribbon around it
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_ARQ(("ata_start_arq 0x%p ARQ needed\n", ata_ctlp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Determine just the size of the Request Sense Data buffer within
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the scsi_arq_status structure.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#define SIZEOF_ARQ_HEADER (sizeof (struct scsi_arq_status) \
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf - sizeof (struct scsi_extended_sense))
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* save ptr to original pkt */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* switch the controller's active pkt to the ARQ pkt */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* finish initializing the ARQ CDB */
f304523c1c8b168f5db72cb0e24ee8318a974f8dzhongyan gu - Sun Microsystems - Beijing China ata_ctlp->ac_arq_cdb[4] = (uchar_t)senselen;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* finish initializing the ARQ pkt */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf arq_pktp->ap_v_addr = (caddr_t)&ata_pktp->ap_scbp->sts_sensedata;
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ((unsigned)(ata_drvp->ad_cdb_len - arq_pktp->ap_cdb_len)) >> 1;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * This packet is shared by all drives on this controller
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * therefore we need to init the drive number on every ARQ.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* start it up */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return ((*arq_pktp->ap_start)(ata_ctlp, ata_drvp, arq_pktp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * reset the bus
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Do a Software Reset to unwedge the bus, and send
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ATAPI DEVICE RESET to each ATAPI drive.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (watchdog = ata_reset_bus_watchdog; watchdog > 0; watchdog--) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Reinitialize the ATA drives
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Reprogram the Read/Write Multiple block factor
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and current geometry into the drive.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* If DoneFlg is TRUE, it means that ghd_complete() function */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* has been already called. In this case ignore any errors and */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* return TRUE to the caller, otherwise return the value of rc */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* to the caller */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Low level routine to toggle the Software Reset bit
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* disable interrupts and turn the software reset bit on */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_SRST));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* why 30 milliseconds, the ATA/ATAPI-4 spec says 5 usec. */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* turn the software reset bit back off */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Wait for the controller to assert BUSY status.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * I don't think 300 msecs is correct. The ATA/ATAPI-4
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * spec says 400 nsecs, (and 2 msecs if device
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * was in sleep mode; but we don't put drives to sleep
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * so it probably doesn't matter).
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If drive 0 exists the test for completion is simple
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * This must be a single device configuration, with drive 1
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * only. This complicates the test for completion because
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * issuing the software reset just caused drive 1 to
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * deselect. With drive 1 deselected, if I just read the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * status register to test the BSY bit I get garbage, but
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * I can't re-select drive 1 until I'm certain the BSY bit
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * is de-asserted. Catch-22.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * In ATA/ATAPI-4, rev 15, section 9.16.2, it says to handle
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * this situation like this:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* give up if the drive doesn't settle within 31 seconds */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * delay 10msec each time around the loop
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * try to select drive 1
9f49ae270d37efd5c5270cb8046b4229b5380021mlf * Now wait up to 31 seconds for BUSY to clear.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (void) ata_wait3(io_hdl2, ata_ctlp->ac_ioaddr2, 0, ATS_BSY,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * DDI interrupt handler
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (ghd_intr(&ata_ctlp->ac_ccc, (void *)&one_shot));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD ccc_get_status callback
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ignore interrupts before ata_attach completes
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * can't be interrupt pending if nothing active
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If this is a PCI-IDE controller, check the PCI-IDE controller's
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * interrupt status latch. But don't clear it yet.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * AC_BMSTATREG_PIO_BROKEN flag is used currently for
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CMD chips with device id 0x646. Since the interrupt bit on
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Bus master IDE register is not usable when in PIO mode,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * this chip is treated as a legacy device for interrupt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * indication. The following code for CMD
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * chips may need to be revisited when we enable support for dma.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CHANGE: DMA is not disabled for these devices. BM intr bit is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * checked only if there was DMA used or BM intr is useable on PIO,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * else treat it as before - as legacy device.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Interrupts from legacy ATA/IDE controllers are
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * edge-triggered but the dumb legacy ATA/IDE controllers
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and drives don't have an interrupt status bit.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Use a one_shot variable to make sure we only return
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * one status per interrupt.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* check if device is still busy */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf status = ddi_get8(ata_ctlp->ac_iohandle2, ata_ctlp->ac_altstatus);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * get the current status and clear the IRQ
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Here's where we clear the PCI-IDE interrupt latch. If this
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * request used DMA mode then we also have to check and clear
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the DMA error latch at the same time.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Some requests don't use DMA mode and therefore won't
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * set the DMA error latch, but we still have to clear
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the interrupt latch.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Controllers with broken BM intr in PIO mode do not go
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * through this path.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * this clears the drive's interrupt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf status = ddi_get8(ata_ctlp->ac_iohandle1, ata_ctlp->ac_status);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ADBG_TRACE(("ata_get_status_clear_intr: 0x%x\n", status));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD interrupt handler
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* ARGSUSED */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic void
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * process the ATA or ATAPI interrupt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (watchdog = ata_process_intr_watchdog; watchdog > 0; watchdog--) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ata_ctlr_fsm(fsm_func, ata_ctlp, NULL, NULL, NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf switch (rc) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * GHD ccc_hba_start callback
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * which drive?
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * start the request
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (watchdog = ata_hba_start_watchdog; watchdog > 0; watchdog--) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf switch (ata_ctlr_fsm(fsm_func, ata_ctlp, ata_drvp, ata_pktp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* if first time, tell GHD to requeue the request */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The start function polled for the next
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * bus phase, now fake an interrupt to process
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the next action.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf case ATA_FSM_RC_FINI: /* move request to the done queue */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf vendorid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf deviceid = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * first check for a match in the "pci-ide-blacklist" property
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf while (count--) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* check for matching ID */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* got a match */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * then check the built-in blacklist
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (blp = ata_pciide_blacklist; blp->b_vendorid; blp++) {
744a060193833d1e3b4db51fd9a2ecd996659613Ling Albert Ke for (blp = ata_drive_blacklist; blp->b_model != NULL; blp++) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Queue a request to perform some sort of internally
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * generated command. When this request packet reaches
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the front of the queue (*func)() is invoked.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!(gcmdp = ghd_gcmd_alloc(gtgtp, sizeof (*ata_pktp), TRUE))) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* set the back ptr from the ata_pkt to the gcmd_t */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ata_pktp->ap_bytes_per_block = ata_drvp->ad_bytes_per_block;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * over-ride the default start function
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * add it to the queue, when it gets to the front the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ap_start function is called.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ghd_transport(&ata_ctlp->ac_ccc, gcmdp, gcmdp->cmd_gtgtp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* this should never, ever happen */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Check if this drive has the "revert to defaults" bug
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * PSARC 2001/500 and 2001/xxx - check for the properties
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * ata-revert-to-defaults and atarvrt-<diskmodel> before
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * examining the blacklist.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * <diskmodel> is made from the model number reported by Identify Drive
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * with uppercase letters converted to lowercase and all characters
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * except letters, digits, ".", "_", and "-" deleted.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Return value:
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * TRUE: enable revert to defaults
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * FALSE: disable revert to defaults
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * NOTE: revert to power on defaults that includes reverting to MDMA
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * mode is allowed by ATA-6 & ATA-7 specs.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Therefore drives exhibiting this behaviour are not violating the spec.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Furthermore, the spec explicitly says that after the soft reset
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * host should check the current setting of the device features.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Correctly working BIOS would therefore reprogram either the drive
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and/or the host controller to match transfer modes.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Devices with ATA_BL_NORVRT flag will be removed from
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * the ata_blacklist.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The default behaviour will be - no revert to power-on defaults
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * for all devices. The property is retained in case the user
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * explicitly requests revert-to-defaults before reboot.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* room for prefix + model number + terminating NUL character */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#define PROP_BUF_SIZE (sizeof (ATA_REVERT_PROP_PREFIX) + \
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* put prefix into the buffer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* append the model number, leaving out invalid characters */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (c == '\0')
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* make sure there's a terminating NUL character */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* look for a disk-specific "revert" property" */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* look for a global "revert" property" */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfata_show_transfer_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Using DMA */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Rely on the fact that either dwdma or udma is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * selected, not both.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf for (i = 0; i <= 6; i++) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "?\tUltraDMA mode %d selected\n",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Controller-specific operation pointers.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Should be extended as needed - init only for now
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf uint_t (*cs_init)(dev_info_t *, ushort_t, ushort_t); /* ctlr init */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/* Sil3XXX-specific functions (init only for now) */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf &sil3xxx_init_controller /* Sil3XXX cntrl initialization */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf {0, 0, NULL} /* List must end with cs_ops set to NULL */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Do controller specific initialization if necessary.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Pick-up controller specific functions.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf device_id = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Locate controller specific ops, if they exist */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* Initialize controller */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "pci%4x,%4x cntrl specific "
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf "initialization failed",
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * this routine works like ddi_prop_get_int, except that it works on
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * a string property that contains ascii representations
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * of an integer.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If the property is not found, the default value is returned.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * see if property is encoded as an int instead of string.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf rc = ddi_prop_get_int(match_dev, dip, flags, name, defvalue);
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Initialize the power management components
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "0=Sleep (PCI D3 State)",
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf "3=PowerOn (PCI D0 State)",
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /* check PCI capabilities */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components");
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * resume the hard drive
62c8caf3fac65817982e780c1efa988846153bf0Ada /* Reset Ultra DMA mode */
62c8caf3fac65817982e780c1efa988846153bf0Ada (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_DIS_REVPOD, 0);
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * resume routine, it will be run when get the command
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * DDI_RESUME at attach(9E) from system power management
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf if (ATA_RAISE_POWER(dip, 0, PM_LEVEL_D0) == DDI_FAILURE)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /* enable interrupts from the device */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ddi_put8(io_hdl2, (uchar_t *)ioaddr2 + AT_DEVCTL, ATDC_D3);
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * suspend routine, it will be run when get the command
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * DDI_SUSPEND at detach(9E) from system power management
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /* disable interrupts and turn the software reset bit on */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ddi_put8(io_hdl2, ata_ctlp->ac_devctl, (ATDC_D3 | ATDC_SRST));
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * ata specific power management entry point, it was
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * used to change the power management component
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ADBG_TRACE(("ata_power entered, component = %d, level = %d\n",
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * sent commands to ata controller to change the power level
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ADBG_TRACE(("ata_change_power entered, cmd = %d\n", cmd));
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Issue command on each disk device on the bus.
62c8caf3fac65817982e780c1efa988846153bf0Ada "put drive %d in to power mode %u",
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf for (lun = 1; lun <= lastlun && lun < ATA_MAXLUN; lun++) {
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * return 1 when ata controller is a pci device,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * otherwise return 0
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf rc = ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip),
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf return (0);
5fb86bae323519d98a63f5829df4b849f1fe1598ml * Disable DMA for this drive
5fb86bae323519d98a63f5829df4b849f1fe1598mlstatic void
5fb86bae323519d98a63f5829df4b849f1fe1598ml /* Print the message */
5fb86bae323519d98a63f5829df4b849f1fe1598ml (void) strncpy(buf, aidp->ai_model, sizeof (aidp->ai_model));
5fb86bae323519d98a63f5829df4b849f1fe1598ml for (i = sizeof (aidp->ai_model) - 2; buf[i] == ' '; i--)
5fb86bae323519d98a63f5829df4b849f1fe1598ml "?DMA disabled on %s target=%d, lun=%d due to DMA errors,",
5fb86bae323519d98a63f5829df4b849f1fe1598ml cmn_err(CE_CONT, "?most likely due to the CF-to-IDE adapter.");
c8531848467a8747b65b91ab83c4b57f4c000848yt * Check and select DMA mode
c8531848467a8747b65b91ab83c4b57f4c000848yt * TRUE is returned when set feature is called successfully,
c8531848467a8747b65b91ab83c4b57f4c000848yt * otherwise return FALSE
c8531848467a8747b65b91ab83c4b57f4c000848ytata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp)
c8531848467a8747b65b91ab83c4b57f4c000848yt /* Return directly if DMA is not supported */
8c97a06b88a7f040b7d72941ca32323bb75cfec7Ada /* Return if DMA mode is already selected */
c8531848467a8747b65b91ab83c4b57f4c000848yt /* First check Ultra DMA mode if no DMA is selected */
c8531848467a8747b65b91ab83c4b57f4c000848yt /* Then check multi-word DMA mode */
c8531848467a8747b65b91ab83c4b57f4c000848yt rval = ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD,
0f1b305ee9e700c825d9e9ad1ea1e4311d212eb2Seth Goldberg * Reset Ultra DMA mode / MWDMA mode
0f1b305ee9e700c825d9e9ad1ea1e4311d212eb2Seth Goldberg if (ata_drvp->ad_dma_mode & (1 << (mode + 8)))
0f1b305ee9e700c825d9e9ad1ea1e4311d212eb2Seth Goldberg mode = ((ata_drvp->ad_dma_mode & ATAC_MDMA_2_SEL) ==
0f1b305ee9e700c825d9e9ad1ea1e4311d212eb2Seth Goldberg (void) ata_set_feature(ata_ctlp, ata_drvp, ATSF_SET_XFRMOD,
fe072f421ec51952432306add7d50852ad1921b2Ada * Check DMA mode is the same with saved info
fe072f421ec51952432306add7d50852ad1921b2Ada * return value: 0 - not same
fe072f421ec51952432306add7d50852ad1921b2Ada * 1 - same
fe072f421ec51952432306add7d50852ad1921b2Ada return (0);
fe072f421ec51952432306add7d50852ad1921b2Ada return (0);
fe072f421ec51952432306add7d50852ad1921b2Ada return (0);
fe072f421ec51952432306add7d50852ad1921b2Ada return (1);