Path: blob/main/sys/dev/ata/chipsets/ata-promise.c
39537 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 1998 - 2008 Søren Schmidt <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer,11* without modification, immediately at the beginning of the file.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR17* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES18* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.19* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,20* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT21* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,22* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF25* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.26*/2728#include <sys/param.h>29#include <sys/module.h>30#include <sys/systm.h>31#include <sys/kernel.h>32#include <sys/ata.h>33#include <sys/bus.h>34#include <sys/endian.h>35#include <sys/malloc.h>36#include <sys/lock.h>37#include <sys/mutex.h>38#include <sys/sema.h>39#include <sys/stdarg.h>40#include <sys/taskqueue.h>41#include <vm/uma.h>42#include <machine/resource.h>43#include <machine/bus.h>44#include <sys/rman.h>45#include <dev/pci/pcivar.h>46#include <dev/pci/pcireg.h>47#include <dev/ata/ata-all.h>48#include <dev/ata/ata-pci.h>49#include <ata_if.h>5051/* local prototypes */52static int ata_promise_chipinit(device_t dev);53static int ata_promise_ch_attach(device_t dev);54static int ata_promise_status(device_t dev);55static int ata_promise_dmastart(struct ata_request *request);56static int ata_promise_dmastop(struct ata_request *request);57static void ata_promise_dmareset(device_t dev);58static int ata_promise_setmode(device_t dev, int target, int mode);59static int ata_promise_tx2_ch_attach(device_t dev);60static int ata_promise_tx2_status(device_t dev);61static int ata_promise_mio_ch_attach(device_t dev);62static int ata_promise_mio_ch_detach(device_t dev);63static void ata_promise_mio_intr(void *data);64static int ata_promise_mio_status(device_t dev);65static int ata_promise_mio_command(struct ata_request *request);66static void ata_promise_mio_reset(device_t dev);67static int ata_promise_mio_pm_read(device_t dev, int port, int reg, u_int32_t *result);68static int ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t result);69static u_int32_t ata_promise_mio_softreset(device_t dev, int port);70static void ata_promise_mio_dmainit(device_t dev);71static void ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);72static int ata_promise_mio_setmode(device_t dev, int target, int mode);73static int ata_promise_mio_getrev(device_t dev, int target);74static void ata_promise_sx4_intr(void *data);75static int ata_promise_sx4_command(struct ata_request *request);76static int ata_promise_apkt(u_int8_t *bytep, struct ata_request *request);77static void ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt);78static void ata_promise_next_hpkt(struct ata_pci_controller *ctlr);7980/* misc defines */81#define PR_OLD 082#define PR_NEW 183#define PR_TX 284#define PR_MIO 385#define PR_TX4 0x0186#define PR_SX4X 0x0287#define PR_SX6K 0x0488#define PR_PATA 0x0889#define PR_CMBO 0x1090#define PR_CMBO2 0x2091#define PR_SATA 0x4092#define PR_SATA2 0x809394/*95* Promise chipset support functions96*/97#define ATA_PDC_APKT_OFFSET 0x0000001098#define ATA_PDC_HPKT_OFFSET 0x0000004099#define ATA_PDC_ASG_OFFSET 0x00000080100#define ATA_PDC_LSG_OFFSET 0x000000c0101#define ATA_PDC_HSG_OFFSET 0x00000100102#define ATA_PDC_CHN_OFFSET 0x00000400103#define ATA_PDC_BUF_BASE 0x00400000104#define ATA_PDC_BUF_OFFSET 0x00100000105#define ATA_PDC_MAX_HPKT 8106#define ATA_PDC_WRITE_REG 0x00107#define ATA_PDC_WRITE_CTL 0x0e108#define ATA_PDC_WRITE_END 0x08109#define ATA_PDC_WAIT_NBUSY 0x10110#define ATA_PDC_WAIT_READY 0x18111#define ATA_PDC_1B 0x20112#define ATA_PDC_2B 0x40113114struct host_packet {115u_int32_t addr;116TAILQ_ENTRY(host_packet) chain;117};118119struct ata_promise_sx4 {120struct mtx mtx;121TAILQ_HEAD(, host_packet) queue;122int busy;123};124125static int126ata_promise_probe(device_t dev)127{128struct ata_pci_controller *ctlr = device_get_softc(dev);129const struct ata_chip_id *idx;130static const struct ata_chip_id ids[] =131{{ ATA_PDC20246, 0, PR_OLD, 0x00, ATA_UDMA2, "PDC20246" },132{ ATA_PDC20262, 0, PR_NEW, 0x00, ATA_UDMA4, "PDC20262" },133{ ATA_PDC20263, 0, PR_NEW, 0x00, ATA_UDMA4, "PDC20263" },134{ ATA_PDC20265, 0, PR_NEW, 0x00, ATA_UDMA5, "PDC20265" },135{ ATA_PDC20267, 0, PR_NEW, 0x00, ATA_UDMA5, "PDC20267" },136{ ATA_PDC20268, 0, PR_TX, PR_TX4, ATA_UDMA5, "PDC20268" },137{ ATA_PDC20269, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20269" },138{ ATA_PDC20270, 0, PR_TX, PR_TX4, ATA_UDMA5, "PDC20270" },139{ ATA_PDC20271, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20271" },140{ ATA_PDC20275, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20275" },141{ ATA_PDC20276, 0, PR_TX, PR_SX6K, ATA_UDMA6, "PDC20276" },142{ ATA_PDC20277, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20277" },143{ ATA_PDC20318, 0, PR_MIO, PR_SATA, ATA_SA150, "PDC20318" },144{ ATA_PDC20319, 0, PR_MIO, PR_SATA, ATA_SA150, "PDC20319" },145{ ATA_PDC20371, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20371" },146{ ATA_PDC20375, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20375" },147{ ATA_PDC20376, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20376" },148{ ATA_PDC20377, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20377" },149{ ATA_PDC20378, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20378" },150{ ATA_PDC20379, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20379" },151{ ATA_PDC20571, 0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20571" },152{ ATA_PDC20575, 0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20575" },153{ ATA_PDC20579, 0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20579" },154{ ATA_PDC20771, 0, PR_MIO, PR_CMBO2, ATA_SA300, "PDC20771" },155{ ATA_PDC40775, 0, PR_MIO, PR_CMBO2, ATA_SA300, "PDC40775" },156{ ATA_PDC20617, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20617" },157{ ATA_PDC20618, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20618" },158{ ATA_PDC20619, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20619" },159{ ATA_PDC20620, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20620" },160{ ATA_PDC20621, 0, PR_MIO, PR_SX4X, ATA_UDMA5, "PDC20621" },161{ ATA_PDC20622, 0, PR_MIO, PR_SX4X, ATA_SA150, "PDC20622" },162{ ATA_PDC40518, 0, PR_MIO, PR_SATA2, ATA_SA150, "PDC40518" },163{ ATA_PDC40519, 0, PR_MIO, PR_SATA2, ATA_SA150, "PDC40519" },164{ ATA_PDC40718, 0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40718" },165{ ATA_PDC40719, 0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40719" },166{ ATA_PDC40779, 0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40779" },167{ 0, 0, 0, 0, 0, 0}};168const char *channel;169uintptr_t devid = 0;170171if (pci_get_vendor(dev) != ATA_PROMISE_ID)172return ENXIO;173174if (!(idx = ata_match_chip(dev, ids)))175return ENXIO;176177/* if we are on a SuperTrak SX6000 dont attach */178if ((idx->cfg2 & PR_SX6K) && pci_get_class(GRANDPARENT(dev))==PCIC_BRIDGE &&179!BUS_READ_IVAR(device_get_parent(GRANDPARENT(dev)),180GRANDPARENT(dev), PCI_IVAR_DEVID, &devid) &&181devid == ATA_I960RM)182return ENXIO;183184/* if we are on a FastTrak TX4, adjust the interrupt resource */185channel = NULL;186if ((idx->cfg2 & PR_TX4) && pci_get_class(GRANDPARENT(dev))==PCIC_BRIDGE &&187!BUS_READ_IVAR(device_get_parent(GRANDPARENT(dev)),188GRANDPARENT(dev), PCI_IVAR_DEVID, &devid) &&189((devid == ATA_DEC_21150) || (devid == ATA_DEC_21150_1))) {190static rman_res_t start = 0, end = 0;191192if (pci_get_slot(dev) == 1) {193bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &end);194channel = " (channel 0+1)";195}196else if (pci_get_slot(dev) == 2 && start && end) {197bus_set_resource(dev, SYS_RES_IRQ, 0, start, end);198channel = " (channel 2+3)";199}200else {201start = end = 0;202}203}204device_set_descf(dev, "Promise %s%s %s controller", idx->text,205channel == NULL ? "" : channel, ata_mode2str(idx->max_dma));206ctlr->chip = idx;207ctlr->chipinit = ata_promise_chipinit;208return (BUS_PROBE_LOW_PRIORITY);209}210211static int212ata_promise_chipinit(device_t dev)213{214struct ata_pci_controller *ctlr = device_get_softc(dev);215int stat_reg;216217if (ata_setup_interrupt(dev, ata_generic_intr))218return ENXIO;219220switch (ctlr->chip->cfg1) {221case PR_NEW:222/* setup clocks */223ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);224/* FALLTHROUGH */225226case PR_OLD:227/* enable burst mode */228ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);229ctlr->ch_attach = ata_promise_ch_attach;230ctlr->ch_detach = ata_pci_ch_detach;231ctlr->setmode = ata_promise_setmode;232return 0;233234case PR_TX:235ctlr->ch_attach = ata_promise_tx2_ch_attach;236ctlr->ch_detach = ata_pci_ch_detach;237ctlr->setmode = ata_promise_setmode;238return 0;239240case PR_MIO:241ctlr->r_type1 = SYS_RES_MEMORY;242ctlr->r_rid1 = PCIR_BAR(4);243if (!(ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1,244&ctlr->r_rid1, RF_ACTIVE)))245goto failnfree;246247ctlr->r_type2 = SYS_RES_MEMORY;248ctlr->r_rid2 = PCIR_BAR(3);249if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,250&ctlr->r_rid2, RF_ACTIVE)))251goto failnfree;252253if (ctlr->chip->cfg2 == PR_SX4X) {254struct ata_promise_sx4 *hpkt;255u_int32_t dimm = ATA_INL(ctlr->r_res2, 0x000c0080);256257if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) ||258bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL,259ata_promise_sx4_intr, ctlr, &ctlr->handle)) {260device_printf(dev, "unable to setup interrupt\n");261goto failnfree;262}263264/* print info about cache memory */265device_printf(dev, "DIMM size %dMB @ 0x%08x%s\n",266(((dimm >> 16) & 0xff)-((dimm >> 24) & 0xff)+1) << 4,267((dimm >> 24) & 0xff),268ATA_INL(ctlr->r_res2, 0x000c0088) & (1<<16) ?269" ECC enabled" : "" );270271/* adjust cache memory parameters */272ATA_OUTL(ctlr->r_res2, 0x000c000c,273(ATA_INL(ctlr->r_res2, 0x000c000c) & 0xffff0000));274275/* setup host packet controls */276hpkt = malloc(sizeof(struct ata_promise_sx4),277M_ATAPCI, M_NOWAIT | M_ZERO);278if (hpkt == NULL) {279device_printf(dev, "Cannot allocate HPKT\n");280goto failnfree;281}282mtx_init(&hpkt->mtx, "ATA promise HPKT lock", NULL, MTX_DEF);283TAILQ_INIT(&hpkt->queue);284hpkt->busy = 0;285ctlr->chipset_data = hpkt;286ctlr->ch_attach = ata_promise_mio_ch_attach;287ctlr->ch_detach = ata_promise_mio_ch_detach;288ctlr->reset = ata_promise_mio_reset;289ctlr->setmode = ata_promise_setmode;290ctlr->channels = 4;291return 0;292}293294/* mio type controllers need an interrupt intercept */295if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) ||296bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL,297ata_promise_mio_intr, ctlr, &ctlr->handle)) {298device_printf(dev, "unable to setup interrupt\n");299goto failnfree;300}301302switch (ctlr->chip->cfg2) {303case PR_PATA:304ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x01) > 0) +305((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 2;306goto sata150;307case PR_CMBO:308ctlr->channels = 3;309goto sata150;310case PR_SATA:311ctlr->channels = 4;312sata150:313stat_reg = 0x6c;314break;315316case PR_CMBO2:317ctlr->channels = 3;318goto sataii;319case PR_SATA2:320default:321ctlr->channels = 4;322sataii:323stat_reg = 0x60;324break;325}326327/* prime fake interrupt register */328ctlr->chipset_data = (void *)(uintptr_t)0xffffffff;329330/* clear SATA status and unmask interrupts */331ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);332333/* enable "long burst length" on gen2 chips */334if ((ctlr->chip->cfg2 == PR_SATA2) || (ctlr->chip->cfg2 == PR_CMBO2))335ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000);336337ctlr->ch_attach = ata_promise_mio_ch_attach;338ctlr->ch_detach = ata_promise_mio_ch_detach;339ctlr->reset = ata_promise_mio_reset;340ctlr->setmode = ata_promise_mio_setmode;341ctlr->getrev = ata_promise_mio_getrev;342343return 0;344}345346failnfree:347if (ctlr->r_res2)348bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2);349if (ctlr->r_res1)350bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1);351return ENXIO;352}353354static int355ata_promise_ch_attach(device_t dev)356{357struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));358struct ata_channel *ch = device_get_softc(dev);359360if (ata_pci_ch_attach(dev))361return ENXIO;362363if (ctlr->chip->cfg1 == PR_NEW) {364ch->dma.start = ata_promise_dmastart;365ch->dma.stop = ata_promise_dmastop;366ch->dma.reset = ata_promise_dmareset;367}368369ch->hw.status = ata_promise_status;370ch->flags |= ATA_NO_ATAPI_DMA;371ch->flags |= ATA_CHECKS_CABLE;372return 0;373}374375static int376ata_promise_status(device_t dev)377{378struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));379struct ata_channel *ch = device_get_softc(dev);380381if (ATA_INL(ctlr->r_res1, 0x1c) & (ch->unit ? 0x00004000 : 0x00000400)) {382return ata_pci_status(dev);383}384return 0;385}386387static int388ata_promise_dmastart(struct ata_request *request)389{390struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));391struct ata_channel *ch = device_get_softc(request->parent);392393if (request->flags & ATA_R_48BIT) {394ATA_OUTB(ctlr->r_res1, 0x11,395ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02));396ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20,397((request->flags & ATA_R_READ) ? 0x05000000 : 0x06000000) |398(request->bytecount >> 1));399}400ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, (ATA_IDX_INB(ch, ATA_BMSTAT_PORT) |401(ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));402ATA_IDX_OUTL(ch, ATA_BMDTP_PORT, request->dma->sg_bus);403ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,404((request->flags & ATA_R_READ) ? ATA_BMCMD_WRITE_READ : 0) |405ATA_BMCMD_START_STOP);406ch->dma.flags |= ATA_DMA_ACTIVE;407return 0;408}409410static int411ata_promise_dmastop(struct ata_request *request)412{413struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));414struct ata_channel *ch = device_get_softc(request->parent);415int error;416417if (request->flags & ATA_R_48BIT) {418ATA_OUTB(ctlr->r_res1, 0x11,419ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02));420ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, 0);421}422error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT);423ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,424ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);425ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);426ch->dma.flags &= ~ATA_DMA_ACTIVE;427return error;428}429430static void431ata_promise_dmareset(device_t dev)432{433struct ata_channel *ch = device_get_softc(dev);434435ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,436ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);437ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);438ch->flags &= ~ATA_DMA_ACTIVE;439}440441static int442ata_promise_setmode(device_t dev, int target, int mode)443{444device_t parent = device_get_parent(dev);445struct ata_pci_controller *ctlr = device_get_softc(parent);446struct ata_channel *ch = device_get_softc(dev);447int devno = (ch->unit << 1) + target;448static const uint32_t timings[][2] = {449/* PR_OLD PR_NEW mode */450{ 0x004ff329, 0x004fff2f }, /* PIO 0 */451{ 0x004fec25, 0x004ff82a }, /* PIO 1 */452{ 0x004fe823, 0x004ff026 }, /* PIO 2 */453{ 0x004fe622, 0x004fec24 }, /* PIO 3 */454{ 0x004fe421, 0x004fe822 }, /* PIO 4 */455{ 0x004567f3, 0x004acef6 }, /* MWDMA 0 */456{ 0x004467f3, 0x0048cef6 }, /* MWDMA 1 */457{ 0x004367f3, 0x0046cef6 }, /* MWDMA 2 */458{ 0x004367f3, 0x0046cef6 }, /* UDMA 0 */459{ 0x004247f3, 0x00448ef6 }, /* UDMA 1 */460{ 0x004127f3, 0x00436ef6 }, /* UDMA 2 */461{ 0, 0x00424ef6 }, /* UDMA 3 */462{ 0, 0x004127f3 }, /* UDMA 4 */463{ 0, 0x004127f3 } /* UDMA 5 */464};465466mode = min(mode, ctlr->chip->max_dma);467468switch (ctlr->chip->cfg1) {469case PR_OLD:470case PR_NEW:471if (ata_dma_check_80pin && mode > ATA_UDMA2 &&472(pci_read_config(parent, 0x50, 2) &473(ch->unit ? 1 << 11 : 1 << 10))) {474ata_print_cable(dev, "controller");475mode = ATA_UDMA2;476}477break;478479case PR_TX:480ATA_IDX_OUTB(ch, ATA_BMDEVSPEC_0, 0x0b);481if (ata_dma_check_80pin && mode > ATA_UDMA2 &&482ATA_IDX_INB(ch, ATA_BMDEVSPEC_1) & 0x04) {483ata_print_cable(dev, "controller");484mode = ATA_UDMA2;485}486break;487488case PR_MIO:489if (ata_dma_check_80pin && mode > ATA_UDMA2 &&490(ATA_INL(ctlr->r_res2,491(ctlr->chip->cfg2 & PR_SX4X ? 0x000c0260 : 0x0260) +492(ch->unit << 7)) & 0x01000000)) {493ata_print_cable(dev, "controller");494mode = ATA_UDMA2;495}496break;497}498499if (ctlr->chip->cfg1 < PR_TX)500pci_write_config(parent, 0x60 + (devno << 2),501timings[ata_mode2idx(mode)][ctlr->chip->cfg1], 4);502return (mode);503}504505static int506ata_promise_tx2_ch_attach(device_t dev)507{508struct ata_channel *ch = device_get_softc(dev);509510if (ata_pci_ch_attach(dev))511return ENXIO;512513ch->hw.status = ata_promise_tx2_status;514ch->flags |= ATA_CHECKS_CABLE;515return 0;516}517518static int519ata_promise_tx2_status(device_t dev)520{521struct ata_channel *ch = device_get_softc(dev);522523ATA_IDX_OUTB(ch, ATA_BMDEVSPEC_0, 0x0b);524if (ATA_IDX_INB(ch, ATA_BMDEVSPEC_1) & 0x20) {525return ata_pci_status(dev);526}527return 0;528}529530static int531ata_promise_mio_ch_attach(device_t dev)532{533struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));534struct ata_channel *ch = device_get_softc(dev);535int offset = (ctlr->chip->cfg2 & PR_SX4X) ? 0x000c0000 : 0;536int i;537538ata_promise_mio_dmainit(dev);539540for (i = ATA_DATA; i <= ATA_COMMAND; i++) {541ch->r_io[i].res = ctlr->r_res2;542ch->r_io[i].offset = offset + 0x0200 + (i << 2) + (ch->unit << 7);543}544ch->r_io[ATA_CONTROL].res = ctlr->r_res2;545ch->r_io[ATA_CONTROL].offset = offset + 0x0238 + (ch->unit << 7);546ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2;547ata_default_registers(dev);548if ((ctlr->chip->cfg2 & (PR_SATA | PR_SATA2)) ||549((ctlr->chip->cfg2 & (PR_CMBO | PR_CMBO2)) && ch->unit < 2)) {550ch->r_io[ATA_SSTATUS].res = ctlr->r_res2;551ch->r_io[ATA_SSTATUS].offset = 0x400 + (ch->unit << 8);552ch->r_io[ATA_SERROR].res = ctlr->r_res2;553ch->r_io[ATA_SERROR].offset = 0x404 + (ch->unit << 8);554ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;555ch->r_io[ATA_SCONTROL].offset = 0x408 + (ch->unit << 8);556ch->flags |= ATA_NO_SLAVE;557ch->flags |= ATA_SATA;558}559ch->flags |= ATA_USE_16BIT;560ch->flags |= ATA_CHECKS_CABLE;561562ata_generic_hw(dev);563if (ctlr->chip->cfg2 & PR_SX4X) {564ch->hw.command = ata_promise_sx4_command;565}566else {567ch->hw.command = ata_promise_mio_command;568ch->hw.status = ata_promise_mio_status;569ch->hw.softreset = ata_promise_mio_softreset;570ch->hw.pm_read = ata_promise_mio_pm_read;571ch->hw.pm_write = ata_promise_mio_pm_write;572}573return 0;574}575576static int577ata_promise_mio_ch_detach(device_t dev)578{579580ata_dmafini(dev);581return (0);582}583584static void585ata_promise_mio_intr(void *data)586{587struct ata_pci_controller *ctlr = data;588struct ata_channel *ch;589u_int32_t vector;590int unit;591592/*593* since reading interrupt status register on early "mio" chips594* clears the status bits we cannot read it for each channel later on595* in the generic interrupt routine.596*/597vector = ATA_INL(ctlr->r_res2, 0x040);598ATA_OUTL(ctlr->r_res2, 0x040, vector);599ctlr->chipset_data = (void *)(uintptr_t)vector;600601for (unit = 0; unit < ctlr->channels; unit++) {602if ((ch = ctlr->interrupt[unit].argument))603ctlr->interrupt[unit].function(ch);604}605606ctlr->chipset_data = (void *)(uintptr_t)0xffffffff;607}608609static int610ata_promise_mio_status(device_t dev)611{612struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));613struct ata_channel *ch = device_get_softc(dev);614u_int32_t stat_reg, vector, status;615616switch (ctlr->chip->cfg2) {617case PR_PATA:618case PR_CMBO:619case PR_SATA:620stat_reg = 0x6c;621break;622case PR_CMBO2:623case PR_SATA2:624default:625stat_reg = 0x60;626break;627}628629/* read and acknowledge interrupt */630vector = (uint32_t)(uintptr_t)ctlr->chipset_data;631632/* read and clear interface status */633status = ATA_INL(ctlr->r_res2, stat_reg);634ATA_OUTL(ctlr->r_res2, stat_reg, status & (0x00000011 << ch->unit));635636/* check for and handle disconnect events */637if (status & (0x00000001 << ch->unit)) {638if (bootverbose)639device_printf(dev, "DISCONNECT requested\n");640taskqueue_enqueue(taskqueue_thread, &ch->conntask);641}642643/* check for and handle connect events */644if (status & (0x00000010 << ch->unit)) {645if (bootverbose)646device_printf(dev, "CONNECT requested\n");647taskqueue_enqueue(taskqueue_thread, &ch->conntask);648}649650/* do we have any device action ? */651return (vector & (1 << (ch->unit + 1)));652}653654static int655ata_promise_mio_command(struct ata_request *request)656{657struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));658struct ata_channel *ch = device_get_softc(request->parent);659660u_int32_t *wordp = (u_int32_t *)ch->dma.work;661662ATA_OUTL(ctlr->r_res2, (ch->unit + 1) << 2, 0x00000001);663664if ((ctlr->chip->cfg2 == PR_SATA2) ||665((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {666/* set portmultiplier port */667ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), request->unit & 0x0f);668}669670/* XXX SOS add ATAPI commands support later */671switch (request->u.ata.command) {672default:673return ata_generic_command(request);674675case ATA_READ_DMA:676case ATA_READ_DMA48:677wordp[0] = htole32(0x04 | ((ch->unit + 1) << 16) | (0x00 << 24));678break;679680case ATA_WRITE_DMA:681case ATA_WRITE_DMA48:682wordp[0] = htole32(0x00 | ((ch->unit + 1) << 16) | (0x00 << 24));683break;684}685wordp[1] = htole32(request->dma->sg_bus);686wordp[2] = 0;687ata_promise_apkt((u_int8_t*)wordp, request);688689ATA_OUTL(ctlr->r_res2, 0x0240 + (ch->unit << 7), ch->dma.work_bus);690return 0;691}692693static void694ata_promise_mio_reset(device_t dev)695{696struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));697struct ata_channel *ch = device_get_softc(dev);698struct ata_promise_sx4 *hpktp;699700switch (ctlr->chip->cfg2) {701case PR_SX4X:702703/* softreset channel ATA module */704hpktp = ctlr->chipset_data;705ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), ch->unit + 1);706ata_udelay(1000);707ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7),708(ATA_INL(ctlr->r_res2, 0xc0260 + (ch->unit << 7)) &709~0x00003f9f) | (ch->unit + 1));710711/* softreset HOST module */ /* XXX SOS what about other outstandings */712mtx_lock(&hpktp->mtx);713ATA_OUTL(ctlr->r_res2, 0xc012c,714(ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f) | (1 << 11));715DELAY(10);716ATA_OUTL(ctlr->r_res2, 0xc012c,717(ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f));718hpktp->busy = 0;719mtx_unlock(&hpktp->mtx);720ata_generic_reset(dev);721break;722723case PR_PATA:724case PR_CMBO:725case PR_SATA:726if ((ctlr->chip->cfg2 == PR_SATA) ||727((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2))) {728/* mask plug/unplug intr */729ATA_OUTL(ctlr->r_res2, 0x06c, (0x00110000 << ch->unit));730}731732/* softreset channels ATA module */733ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11));734ata_udelay(10000);735ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7),736(ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) &737~0x00003f9f) | (ch->unit + 1));738739if ((ctlr->chip->cfg2 == PR_SATA) ||740((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2))) {741if (ata_sata_phy_reset(dev, -1, 1))742ata_generic_reset(dev);743else744ch->devices = 0;745746/* reset and enable plug/unplug intr */747ATA_OUTL(ctlr->r_res2, 0x06c, (0x00000011 << ch->unit));748}749else750ata_generic_reset(dev);751break;752753case PR_CMBO2:754case PR_SATA2:755if ((ctlr->chip->cfg2 == PR_SATA2) ||756((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {757/* set portmultiplier port */758//ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);759760/* mask plug/unplug intr */761ATA_OUTL(ctlr->r_res2, 0x060, (0x00110000 << ch->unit));762}763764/* softreset channels ATA module */765ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11));766ata_udelay(10000);767ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7),768(ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) &769~0x00003f9f) | (ch->unit + 1));770771if ((ctlr->chip->cfg2 == PR_SATA2) ||772((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {773/* set PHY mode to "improved" */774ATA_OUTL(ctlr->r_res2, 0x414 + (ch->unit << 8),775(ATA_INL(ctlr->r_res2, 0x414 + (ch->unit << 8)) &776~0x00000003) | 0x00000001);777778if (ata_sata_phy_reset(dev, -1, 1)) {779u_int32_t signature = ch->hw.softreset(dev, ATA_PM);780781if (bootverbose)782device_printf(dev, "SIGNATURE: %08x\n", signature);783784switch (signature >> 16) {785case 0x0000:786ch->devices = ATA_ATA_MASTER;787break;788case 0x9669:789ch->devices = ATA_PORTMULTIPLIER;790ata_pm_identify(dev);791break;792case 0xeb14:793ch->devices = ATA_ATAPI_MASTER;794break;795default: /* SOS XXX */796if (bootverbose)797device_printf(dev,798"No signature, assuming disk device\n");799ch->devices = ATA_ATA_MASTER;800}801if (bootverbose)802device_printf(dev, "promise_mio_reset devices=%08x\n",803ch->devices);804805} else806ch->devices = 0;807808/* reset and enable plug/unplug intr */809ATA_OUTL(ctlr->r_res2, 0x060, (0x00000011 << ch->unit));810811///* set portmultiplier port */812ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x00);813}814else815ata_generic_reset(dev);816break;817}818}819820static int821ata_promise_mio_pm_read(device_t dev, int port, int reg, u_int32_t *result)822{823struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));824struct ata_channel *ch = device_get_softc(dev);825int timeout = 0;826827if (port < 0) {828*result = ATA_IDX_INL(ch, reg);829return (0);830}831if (port < ATA_PM) {832switch (reg) {833case ATA_SSTATUS:834reg = 0;835break;836case ATA_SERROR:837reg = 1;838break;839case ATA_SCONTROL:840reg = 2;841break;842default:843return (EINVAL);844}845}846/* set portmultiplier port */847ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);848849ATA_IDX_OUTB(ch, ATA_FEATURE, reg);850ATA_IDX_OUTB(ch, ATA_DRIVE, port);851852ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_READ_PM);853854while (timeout < 1000000) {855u_int8_t status = ATA_IDX_INB(ch, ATA_STATUS);856if (!(status & ATA_S_BUSY))857break;858timeout += 1000;859DELAY(1000);860}861if (timeout >= 1000000)862return ATA_E_ABORT;863864*result = ATA_IDX_INB(ch, ATA_COUNT) |865(ATA_IDX_INB(ch, ATA_SECTOR) << 8) |866(ATA_IDX_INB(ch, ATA_CYL_LSB) << 16) |867(ATA_IDX_INB(ch, ATA_CYL_MSB) << 24);868return 0;869}870871static int872ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t value)873{874struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));875struct ata_channel *ch = device_get_softc(dev);876int timeout = 0;877878if (port < 0) {879ATA_IDX_OUTL(ch, reg, value);880return (0);881}882if (port < ATA_PM) {883switch (reg) {884case ATA_SSTATUS:885reg = 0;886break;887case ATA_SERROR:888reg = 1;889break;890case ATA_SCONTROL:891reg = 2;892break;893default:894return (EINVAL);895}896}897/* set portmultiplier port */898ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);899900ATA_IDX_OUTB(ch, ATA_FEATURE, reg);901ATA_IDX_OUTB(ch, ATA_DRIVE, port);902ATA_IDX_OUTB(ch, ATA_COUNT, value & 0xff);903ATA_IDX_OUTB(ch, ATA_SECTOR, (value >> 8) & 0xff);904ATA_IDX_OUTB(ch, ATA_CYL_LSB, (value >> 16) & 0xff);905ATA_IDX_OUTB(ch, ATA_CYL_MSB, (value >> 24) & 0xff);906907ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_WRITE_PM);908909while (timeout < 1000000) {910u_int8_t status = ATA_IDX_INB(ch, ATA_STATUS);911if (!(status & ATA_S_BUSY))912break;913timeout += 1000;914DELAY(1000);915}916if (timeout >= 1000000)917return ATA_E_ABORT;918919return ATA_IDX_INB(ch, ATA_ERROR);920}921922/* must be called with ATA channel locked and state_mtx held */923static u_int32_t924ata_promise_mio_softreset(device_t dev, int port)925{926struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));927struct ata_channel *ch = device_get_softc(dev);928int timeout;929930/* set portmultiplier port */931ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), port & 0x0f);932933/* softreset device on this channel */934ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER));935DELAY(10);936ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS | ATA_A_RESET);937ata_udelay(10000);938ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS);939ata_udelay(150000);940ATA_IDX_INB(ch, ATA_ERROR);941942/* wait for BUSY to go inactive */943for (timeout = 0; timeout < 100; timeout++) {944u_int8_t /* err, */ stat;945946/* err = */ ATA_IDX_INB(ch, ATA_ERROR);947stat = ATA_IDX_INB(ch, ATA_STATUS);948949//if (stat == err && timeout > (stat & ATA_S_BUSY ? 100 : 10))950//break;951952if (!(stat & ATA_S_BUSY)) {953//if ((err & 0x7f) == ATA_E_ILI) {954return ATA_IDX_INB(ch, ATA_COUNT) |955(ATA_IDX_INB(ch, ATA_SECTOR) << 8) |956(ATA_IDX_INB(ch, ATA_CYL_LSB) << 16) |957(ATA_IDX_INB(ch, ATA_CYL_MSB) << 24);958//}959//else if (stat & 0x0f) {960//stat |= ATA_S_BUSY;961//}962}963964if (!(stat & ATA_S_BUSY) || (stat == 0xff && timeout > 10))965break;966ata_udelay(100000);967}968return -1;969}970971static void972ata_promise_mio_dmainit(device_t dev)973{974struct ata_channel *ch = device_get_softc(dev);975976/* note start and stop are not used here */977ch->dma.setprd = ata_promise_mio_setprd;978ch->dma.max_iosize = 65536;979ata_dmainit(dev);980}981982#define MAXLASTSGSIZE (32 * sizeof(u_int32_t))983static void984ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)985{986struct ata_dmasetprd_args *args = xsc;987struct ata_dma_prdentry *prd = args->dmatab;988int i;989990if ((args->error = error))991return;992993for (i = 0; i < nsegs; i++) {994prd[i].addr = htole32(segs[i].ds_addr);995prd[i].count = htole32(segs[i].ds_len);996}997if (segs[i - 1].ds_len > MAXLASTSGSIZE) {998//printf("split last SG element of %u\n", segs[i - 1].ds_len);999prd[i - 1].count = htole32(segs[i - 1].ds_len - MAXLASTSGSIZE);1000prd[i].count = htole32(MAXLASTSGSIZE);1001prd[i].addr = htole32(segs[i - 1].ds_addr +1002(segs[i - 1].ds_len - MAXLASTSGSIZE));1003nsegs++;1004i++;1005}1006prd[i - 1].count |= htole32(ATA_DMA_EOT);1007KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries\n"));1008args->nsegs = nsegs;1009}10101011static int1012ata_promise_mio_setmode(device_t dev, int target, int mode)1013{1014struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));1015struct ata_channel *ch = device_get_softc(dev);10161017if ( (ctlr->chip->cfg2 == PR_SATA) ||1018((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||1019(ctlr->chip->cfg2 == PR_SATA2) ||1020((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))1021mode = ata_sata_setmode(dev, target, mode);1022else1023mode = ata_promise_setmode(dev, target, mode);1024return (mode);1025}10261027static int1028ata_promise_mio_getrev(device_t dev, int target)1029{1030struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));1031struct ata_channel *ch = device_get_softc(dev);10321033if ( (ctlr->chip->cfg2 == PR_SATA) ||1034((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||1035(ctlr->chip->cfg2 == PR_SATA2) ||1036((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))1037return (ata_sata_getrev(dev, target));1038else1039return (0);1040}10411042static void1043ata_promise_sx4_intr(void *data)1044{1045struct ata_pci_controller *ctlr = data;1046struct ata_channel *ch;1047u_int32_t vector = ATA_INL(ctlr->r_res2, 0x000c0480);1048int unit;10491050for (unit = 0; unit < ctlr->channels; unit++) {1051if (vector & (1 << (unit + 1)))1052if ((ch = ctlr->interrupt[unit].argument))1053ctlr->interrupt[unit].function(ch);1054if (vector & (1 << (unit + 5)))1055if ((ch = ctlr->interrupt[unit].argument))1056ata_promise_queue_hpkt(ctlr,1057htole32((ch->unit * ATA_PDC_CHN_OFFSET) +1058ATA_PDC_HPKT_OFFSET));1059if (vector & (1 << (unit + 9))) {1060ata_promise_next_hpkt(ctlr);1061if ((ch = ctlr->interrupt[unit].argument))1062ctlr->interrupt[unit].function(ch);1063}1064if (vector & (1 << (unit + 13))) {1065ata_promise_next_hpkt(ctlr);1066if ((ch = ctlr->interrupt[unit].argument))1067ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7),1068htole32((ch->unit * ATA_PDC_CHN_OFFSET) +1069ATA_PDC_APKT_OFFSET));1070}1071}1072}10731074static int1075ata_promise_sx4_command(struct ata_request *request)1076{1077device_t gparent = device_get_parent(request->parent);1078struct ata_pci_controller *ctlr = device_get_softc(gparent);1079struct ata_channel *ch = device_get_softc(request->parent);1080struct ata_dma_prdentry *prd;1081caddr_t window = rman_get_virtual(ctlr->r_res1);1082u_int32_t *wordp;1083int i, idx;10841085/* XXX SOS add ATAPI commands support later */1086switch (request->u.ata.command) {10871088default:1089return -1;10901091case ATA_ATA_IDENTIFY:1092case ATA_READ:1093case ATA_READ48:1094case ATA_READ_MUL:1095case ATA_READ_MUL48:1096case ATA_WRITE:1097case ATA_WRITE48:1098case ATA_WRITE_MUL:1099case ATA_WRITE_MUL48:1100ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001);1101return ata_generic_command(request);11021103case ATA_SETFEATURES:1104case ATA_FLUSHCACHE:1105case ATA_FLUSHCACHE48:1106case ATA_SLEEP:1107case ATA_SET_MULTI:1108wordp = (u_int32_t *)1109(window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET);1110wordp[0] = htole32(0x08 | ((ch->unit + 1)<<16) | (0x00 << 24));1111wordp[1] = 0;1112wordp[2] = 0;1113ata_promise_apkt((u_int8_t *)wordp, request);1114ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001);1115ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001);1116ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7),1117htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_APKT_OFFSET));1118return 0;11191120case ATA_READ_DMA:1121case ATA_READ_DMA48:1122case ATA_WRITE_DMA:1123case ATA_WRITE_DMA48:1124prd = request->dma->sg;1125wordp = (u_int32_t *)1126(window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HSG_OFFSET);1127i = idx = 0;1128do {1129wordp[idx++] = prd[i].addr;1130wordp[idx++] = prd[i].count;1131} while (!(prd[i++].count & ATA_DMA_EOT));11321133wordp = (u_int32_t *)1134(window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_LSG_OFFSET);1135wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE);1136wordp[1] = htole32(request->bytecount | ATA_DMA_EOT);11371138wordp = (u_int32_t *)1139(window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_ASG_OFFSET);1140wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE);1141wordp[1] = htole32(request->bytecount | ATA_DMA_EOT);11421143wordp = (u_int32_t *)1144(window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HPKT_OFFSET);1145if (request->flags & ATA_R_READ)1146wordp[0] = htole32(0x14 | ((ch->unit+9)<<16) | ((ch->unit+5)<<24));1147if (request->flags & ATA_R_WRITE)1148wordp[0] = htole32(0x00 | ((ch->unit+13)<<16) | (0x00<<24));1149wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_HSG_OFFSET);1150wordp[2] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_LSG_OFFSET);1151wordp[3] = 0;11521153wordp = (u_int32_t *)1154(window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET);1155if (request->flags & ATA_R_READ)1156wordp[0] = htole32(0x04 | ((ch->unit+5)<<16) | (0x00<<24));1157if (request->flags & ATA_R_WRITE)1158wordp[0] = htole32(0x10 | ((ch->unit+1)<<16) | ((ch->unit+13)<<24));1159wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_ASG_OFFSET);1160wordp[2] = 0;1161ata_promise_apkt((u_int8_t *)wordp, request);1162ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001);11631164if (request->flags & ATA_R_READ) {1165ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+5)<<2), 0x00000001);1166ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+9)<<2), 0x00000001);1167ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7),1168htole32((ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET));1169}1170if (request->flags & ATA_R_WRITE) {1171ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+1)<<2), 0x00000001);1172ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+13)<<2), 0x00000001);1173ata_promise_queue_hpkt(ctlr,1174htole32((ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HPKT_OFFSET));1175}1176return 0;1177}1178}11791180static int1181ata_promise_apkt(u_int8_t *bytep, struct ata_request *request)1182{1183int i = 12;11841185bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_PDC_WAIT_NBUSY|ATA_DRIVE;1186bytep[i++] = ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit);1187bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_CTL;1188bytep[i++] = ATA_A_4BIT;11891190if (request->flags & ATA_R_48BIT) {1191bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_FEATURE;1192bytep[i++] = request->u.ata.feature >> 8;1193bytep[i++] = request->u.ata.feature;1194bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_COUNT;1195bytep[i++] = request->u.ata.count >> 8;1196bytep[i++] = request->u.ata.count;1197bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_SECTOR;1198bytep[i++] = request->u.ata.lba >> 24;1199bytep[i++] = request->u.ata.lba;1200bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_LSB;1201bytep[i++] = request->u.ata.lba >> 32;1202bytep[i++] = request->u.ata.lba >> 8;1203bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_MSB;1204bytep[i++] = request->u.ata.lba >> 40;1205bytep[i++] = request->u.ata.lba >> 16;1206bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;1207bytep[i++] = ATA_D_LBA | ATA_DEV(request->unit);1208}1209else {1210bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_FEATURE;1211bytep[i++] = request->u.ata.feature;1212bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_COUNT;1213bytep[i++] = request->u.ata.count;1214bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_SECTOR;1215bytep[i++] = request->u.ata.lba;1216bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_LSB;1217bytep[i++] = request->u.ata.lba >> 8;1218bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_MSB;1219bytep[i++] = request->u.ata.lba >> 16;1220bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;1221bytep[i++] = ATA_D_LBA | ATA_D_IBM | ATA_DEV(request->unit) |1222((request->u.ata.lba >> 24)&0xf);1223}1224bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_END | ATA_COMMAND;1225bytep[i++] = request->u.ata.command;1226return i;1227}12281229static void1230ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt)1231{1232struct ata_promise_sx4 *hpktp = ctlr->chipset_data;12331234mtx_lock(&hpktp->mtx);1235if (hpktp->busy) {1236struct host_packet *hp =1237malloc(sizeof(struct host_packet), M_TEMP, M_NOWAIT | M_ZERO);1238hp->addr = hpkt;1239TAILQ_INSERT_TAIL(&hpktp->queue, hp, chain);1240}1241else {1242hpktp->busy = 1;1243ATA_OUTL(ctlr->r_res2, 0x000c0100, hpkt);1244}1245mtx_unlock(&hpktp->mtx);1246}12471248static void1249ata_promise_next_hpkt(struct ata_pci_controller *ctlr)1250{1251struct ata_promise_sx4 *hpktp = ctlr->chipset_data;1252struct host_packet *hp;12531254mtx_lock(&hpktp->mtx);1255if ((hp = TAILQ_FIRST(&hpktp->queue))) {1256TAILQ_REMOVE(&hpktp->queue, hp, chain);1257ATA_OUTL(ctlr->r_res2, 0x000c0100, hp->addr);1258free(hp, M_TEMP);1259}1260else1261hpktp->busy = 0;1262mtx_unlock(&hpktp->mtx);1263}12641265ATA_DECLARE_DRIVER(ata_promise);126612671268