1183724Ssos/*- 2230132Suqs * Copyright (c) 1998 - 2008 S��ren Schmidt <sos@FreeBSD.org> 3183724Ssos * All rights reserved. 4183724Ssos * 5183724Ssos * Redistribution and use in source and binary forms, with or without 6183724Ssos * modification, are permitted provided that the following conditions 7183724Ssos * are met: 8183724Ssos * 1. Redistributions of source code must retain the above copyright 9183724Ssos * notice, this list of conditions and the following disclaimer, 10183724Ssos * without modification, immediately at the beginning of the file. 11183724Ssos * 2. Redistributions in binary form must reproduce the above copyright 12183724Ssos * notice, this list of conditions and the following disclaimer in the 13183724Ssos * documentation and/or other materials provided with the distribution. 14183724Ssos * 15183724Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16183724Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17183724Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18183724Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19183724Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20183724Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21183724Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22183724Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23183724Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24183724Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25183724Ssos */ 26183724Ssos 27183724Ssos#include <sys/cdefs.h> 28183724Ssos__FBSDID("$FreeBSD$"); 29183724Ssos 30183724Ssos#include <sys/param.h> 31183724Ssos#include <sys/module.h> 32183724Ssos#include <sys/systm.h> 33183724Ssos#include <sys/kernel.h> 34183724Ssos#include <sys/ata.h> 35183724Ssos#include <sys/bus.h> 36183724Ssos#include <sys/endian.h> 37183724Ssos#include <sys/malloc.h> 38183724Ssos#include <sys/lock.h> 39183724Ssos#include <sys/mutex.h> 40183724Ssos#include <sys/sema.h> 41183724Ssos#include <sys/taskqueue.h> 42183724Ssos#include <vm/uma.h> 43183724Ssos#include <machine/stdarg.h> 44183724Ssos#include <machine/resource.h> 45183724Ssos#include <machine/bus.h> 46183724Ssos#include <sys/rman.h> 47183724Ssos#include <dev/pci/pcivar.h> 48183724Ssos#include <dev/pci/pcireg.h> 49183724Ssos#include <dev/ata/ata-all.h> 50183724Ssos#include <dev/ata/ata-pci.h> 51183724Ssos#include <ata_if.h> 52183724Ssos 53183724Ssos/* local prototypes */ 54183724Ssosstatic int ata_promise_chipinit(device_t dev); 55188765Smavstatic int ata_promise_ch_attach(device_t dev); 56183724Ssosstatic int ata_promise_status(device_t dev); 57183724Ssosstatic int ata_promise_dmastart(struct ata_request *request); 58183724Ssosstatic int ata_promise_dmastop(struct ata_request *request); 59183724Ssosstatic void ata_promise_dmareset(device_t dev); 60200171Smavstatic int ata_promise_setmode(device_t dev, int target, int mode); 61188765Smavstatic int ata_promise_tx2_ch_attach(device_t dev); 62183724Ssosstatic int ata_promise_tx2_status(device_t dev); 63188765Smavstatic int ata_promise_mio_ch_attach(device_t dev); 64188769Smavstatic int ata_promise_mio_ch_detach(device_t dev); 65183724Ssosstatic void ata_promise_mio_intr(void *data); 66183724Ssosstatic int ata_promise_mio_status(device_t dev); 67183724Ssosstatic int ata_promise_mio_command(struct ata_request *request); 68183724Ssosstatic void ata_promise_mio_reset(device_t dev); 69183724Ssosstatic int ata_promise_mio_pm_read(device_t dev, int port, int reg, u_int32_t *result); 70183724Ssosstatic int ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t result); 71183724Ssosstatic u_int32_t ata_promise_mio_softreset(device_t dev, int port); 72183724Ssosstatic void ata_promise_mio_dmainit(device_t dev); 73183724Ssosstatic void ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); 74200171Smavstatic int ata_promise_mio_setmode(device_t dev, int target, int mode); 75203034Smavstatic int ata_promise_mio_getrev(device_t dev, int target); 76183724Ssosstatic void ata_promise_sx4_intr(void *data); 77183724Ssosstatic int ata_promise_sx4_command(struct ata_request *request); 78183724Ssosstatic int ata_promise_apkt(u_int8_t *bytep, struct ata_request *request); 79183724Ssosstatic void ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt); 80183724Ssosstatic void ata_promise_next_hpkt(struct ata_pci_controller *ctlr); 81183724Ssos 82183724Ssos/* misc defines */ 83183724Ssos#define PR_OLD 0 84183724Ssos#define PR_NEW 1 85183724Ssos#define PR_TX 2 86183724Ssos#define PR_MIO 3 87183724Ssos#define PR_TX4 0x01 88183724Ssos#define PR_SX4X 0x02 89183724Ssos#define PR_SX6K 0x04 90183724Ssos#define PR_PATA 0x08 91183724Ssos#define PR_CMBO 0x10 92183724Ssos#define PR_CMBO2 0x20 93183724Ssos#define PR_SATA 0x40 94183724Ssos#define PR_SATA2 0x80 95183724Ssos 96183724Ssos/* 97183724Ssos * Promise chipset support functions 98183724Ssos */ 99183724Ssos#define ATA_PDC_APKT_OFFSET 0x00000010 100183724Ssos#define ATA_PDC_HPKT_OFFSET 0x00000040 101183724Ssos#define ATA_PDC_ASG_OFFSET 0x00000080 102183724Ssos#define ATA_PDC_LSG_OFFSET 0x000000c0 103183724Ssos#define ATA_PDC_HSG_OFFSET 0x00000100 104183724Ssos#define ATA_PDC_CHN_OFFSET 0x00000400 105183724Ssos#define ATA_PDC_BUF_BASE 0x00400000 106183724Ssos#define ATA_PDC_BUF_OFFSET 0x00100000 107183724Ssos#define ATA_PDC_MAX_HPKT 8 108183724Ssos#define ATA_PDC_WRITE_REG 0x00 109183724Ssos#define ATA_PDC_WRITE_CTL 0x0e 110183724Ssos#define ATA_PDC_WRITE_END 0x08 111183724Ssos#define ATA_PDC_WAIT_NBUSY 0x10 112183724Ssos#define ATA_PDC_WAIT_READY 0x18 113183724Ssos#define ATA_PDC_1B 0x20 114183724Ssos#define ATA_PDC_2B 0x40 115183724Ssos 116183724Ssosstruct host_packet { 117183724Ssos u_int32_t addr; 118183724Ssos TAILQ_ENTRY(host_packet) chain; 119183724Ssos}; 120183724Ssos 121183724Ssosstruct ata_promise_sx4 { 122183724Ssos struct mtx mtx; 123183724Ssos TAILQ_HEAD(, host_packet) queue; 124183724Ssos int busy; 125183724Ssos}; 126183724Ssos 127183724Ssosstatic int 128183724Ssosata_promise_probe(device_t dev) 129183724Ssos{ 130183724Ssos struct ata_pci_controller *ctlr = device_get_softc(dev); 131233282Smarius const struct ata_chip_id *idx; 132242625Sdim static const struct ata_chip_id ids[] = 133183724Ssos {{ ATA_PDC20246, 0, PR_OLD, 0x00, ATA_UDMA2, "PDC20246" }, 134183724Ssos { ATA_PDC20262, 0, PR_NEW, 0x00, ATA_UDMA4, "PDC20262" }, 135183724Ssos { ATA_PDC20263, 0, PR_NEW, 0x00, ATA_UDMA4, "PDC20263" }, 136183724Ssos { ATA_PDC20265, 0, PR_NEW, 0x00, ATA_UDMA5, "PDC20265" }, 137183724Ssos { ATA_PDC20267, 0, PR_NEW, 0x00, ATA_UDMA5, "PDC20267" }, 138183724Ssos { ATA_PDC20268, 0, PR_TX, PR_TX4, ATA_UDMA5, "PDC20268" }, 139183724Ssos { ATA_PDC20269, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20269" }, 140183724Ssos { ATA_PDC20270, 0, PR_TX, PR_TX4, ATA_UDMA5, "PDC20270" }, 141183724Ssos { ATA_PDC20271, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20271" }, 142183724Ssos { ATA_PDC20275, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20275" }, 143183724Ssos { ATA_PDC20276, 0, PR_TX, PR_SX6K, ATA_UDMA6, "PDC20276" }, 144183724Ssos { ATA_PDC20277, 0, PR_TX, 0x00, ATA_UDMA6, "PDC20277" }, 145183724Ssos { ATA_PDC20318, 0, PR_MIO, PR_SATA, ATA_SA150, "PDC20318" }, 146183724Ssos { ATA_PDC20319, 0, PR_MIO, PR_SATA, ATA_SA150, "PDC20319" }, 147183724Ssos { ATA_PDC20371, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20371" }, 148183724Ssos { ATA_PDC20375, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20375" }, 149183724Ssos { ATA_PDC20376, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20376" }, 150183724Ssos { ATA_PDC20377, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20377" }, 151183724Ssos { ATA_PDC20378, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20378" }, 152183724Ssos { ATA_PDC20379, 0, PR_MIO, PR_CMBO, ATA_SA150, "PDC20379" }, 153183724Ssos { ATA_PDC20571, 0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20571" }, 154183724Ssos { ATA_PDC20575, 0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20575" }, 155183724Ssos { ATA_PDC20579, 0, PR_MIO, PR_CMBO2, ATA_SA150, "PDC20579" }, 156183724Ssos { ATA_PDC20771, 0, PR_MIO, PR_CMBO2, ATA_SA300, "PDC20771" }, 157183724Ssos { ATA_PDC40775, 0, PR_MIO, PR_CMBO2, ATA_SA300, "PDC40775" }, 158183724Ssos { ATA_PDC20617, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20617" }, 159183724Ssos { ATA_PDC20618, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20618" }, 160183724Ssos { ATA_PDC20619, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20619" }, 161183724Ssos { ATA_PDC20620, 0, PR_MIO, PR_PATA, ATA_UDMA6, "PDC20620" }, 162183724Ssos { ATA_PDC20621, 0, PR_MIO, PR_SX4X, ATA_UDMA5, "PDC20621" }, 163183724Ssos { ATA_PDC20622, 0, PR_MIO, PR_SX4X, ATA_SA150, "PDC20622" }, 164183724Ssos { ATA_PDC40518, 0, PR_MIO, PR_SATA2, ATA_SA150, "PDC40518" }, 165183724Ssos { ATA_PDC40519, 0, PR_MIO, PR_SATA2, ATA_SA150, "PDC40519" }, 166183724Ssos { ATA_PDC40718, 0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40718" }, 167183724Ssos { ATA_PDC40719, 0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40719" }, 168183724Ssos { ATA_PDC40779, 0, PR_MIO, PR_SATA2, ATA_SA300, "PDC40779" }, 169183724Ssos { 0, 0, 0, 0, 0, 0}}; 170183724Ssos char buffer[64]; 171183724Ssos uintptr_t devid = 0; 172183724Ssos 173183724Ssos if (pci_get_vendor(dev) != ATA_PROMISE_ID) 174183724Ssos return ENXIO; 175183724Ssos 176183724Ssos if (!(idx = ata_match_chip(dev, ids))) 177183724Ssos return ENXIO; 178183724Ssos 179183724Ssos /* if we are on a SuperTrak SX6000 dont attach */ 180183724Ssos if ((idx->cfg2 & PR_SX6K) && pci_get_class(GRANDPARENT(dev))==PCIC_BRIDGE && 181183724Ssos !BUS_READ_IVAR(device_get_parent(GRANDPARENT(dev)), 182183724Ssos GRANDPARENT(dev), PCI_IVAR_DEVID, &devid) && 183183724Ssos devid == ATA_I960RM) 184183724Ssos return ENXIO; 185183724Ssos 186183724Ssos strcpy(buffer, "Promise "); 187183724Ssos strcat(buffer, idx->text); 188183724Ssos 189183724Ssos /* if we are on a FastTrak TX4, adjust the interrupt resource */ 190183724Ssos if ((idx->cfg2 & PR_TX4) && pci_get_class(GRANDPARENT(dev))==PCIC_BRIDGE && 191183724Ssos !BUS_READ_IVAR(device_get_parent(GRANDPARENT(dev)), 192183724Ssos GRANDPARENT(dev), PCI_IVAR_DEVID, &devid) && 193183724Ssos ((devid == ATA_DEC_21150) || (devid == ATA_DEC_21150_1))) { 194183724Ssos static long start = 0, end = 0; 195183724Ssos 196183724Ssos if (pci_get_slot(dev) == 1) { 197183724Ssos bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &end); 198183724Ssos strcat(buffer, " (channel 0+1)"); 199183724Ssos } 200183724Ssos else if (pci_get_slot(dev) == 2 && start && end) { 201183724Ssos bus_set_resource(dev, SYS_RES_IRQ, 0, start, end); 202183724Ssos strcat(buffer, " (channel 2+3)"); 203183724Ssos } 204183724Ssos else { 205183724Ssos start = end = 0; 206183724Ssos } 207183724Ssos } 208183724Ssos sprintf(buffer, "%s %s controller", buffer, ata_mode2str(idx->max_dma)); 209183724Ssos device_set_desc_copy(dev, buffer); 210183724Ssos ctlr->chip = idx; 211183724Ssos ctlr->chipinit = ata_promise_chipinit; 212281140Smav return (BUS_PROBE_LOW_PRIORITY); 213183724Ssos} 214183724Ssos 215183724Ssosstatic int 216183724Ssosata_promise_chipinit(device_t dev) 217183724Ssos{ 218183724Ssos struct ata_pci_controller *ctlr = device_get_softc(dev); 219203043Smav int stat_reg; 220183724Ssos 221183724Ssos if (ata_setup_interrupt(dev, ata_generic_intr)) 222183724Ssos return ENXIO; 223183724Ssos 224183724Ssos switch (ctlr->chip->cfg1) { 225183724Ssos case PR_NEW: 226183724Ssos /* setup clocks */ 227183724Ssos ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a); 228183724Ssos /* FALLTHROUGH */ 229183724Ssos 230183724Ssos case PR_OLD: 231183724Ssos /* enable burst mode */ 232183724Ssos ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01); 233188765Smav ctlr->ch_attach = ata_promise_ch_attach; 234188769Smav ctlr->ch_detach = ata_pci_ch_detach; 235183724Ssos ctlr->setmode = ata_promise_setmode; 236183724Ssos return 0; 237183724Ssos 238183724Ssos case PR_TX: 239188765Smav ctlr->ch_attach = ata_promise_tx2_ch_attach; 240188769Smav ctlr->ch_detach = ata_pci_ch_detach; 241183724Ssos ctlr->setmode = ata_promise_setmode; 242183724Ssos return 0; 243183724Ssos 244183724Ssos case PR_MIO: 245183724Ssos ctlr->r_type1 = SYS_RES_MEMORY; 246183724Ssos ctlr->r_rid1 = PCIR_BAR(4); 247183724Ssos if (!(ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1, 248183724Ssos &ctlr->r_rid1, RF_ACTIVE))) 249183724Ssos goto failnfree; 250183724Ssos 251227000Smarius#ifdef __sparc64__ 252227000Smarius if (ctlr->chip->cfg2 == PR_SX4X && 253227000Smarius !bus_space_map(rman_get_bustag(ctlr->r_res1), 254227000Smarius rman_get_bushandle(ctlr->r_res1), rman_get_size(ctlr->r_res1), 255227000Smarius BUS_SPACE_MAP_LINEAR, NULL)) 256227000Smarius goto failnfree; 257227000Smarius#endif 258227000Smarius 259183724Ssos ctlr->r_type2 = SYS_RES_MEMORY; 260183724Ssos ctlr->r_rid2 = PCIR_BAR(3); 261183724Ssos if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, 262183724Ssos &ctlr->r_rid2, RF_ACTIVE))) 263183724Ssos goto failnfree; 264183724Ssos 265183724Ssos if (ctlr->chip->cfg2 == PR_SX4X) { 266183724Ssos struct ata_promise_sx4 *hpkt; 267183724Ssos u_int32_t dimm = ATA_INL(ctlr->r_res2, 0x000c0080); 268183724Ssos 269183724Ssos if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) || 270183724Ssos bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL, 271183724Ssos ata_promise_sx4_intr, ctlr, &ctlr->handle)) { 272183724Ssos device_printf(dev, "unable to setup interrupt\n"); 273183724Ssos goto failnfree; 274183724Ssos } 275183724Ssos 276183724Ssos /* print info about cache memory */ 277183724Ssos device_printf(dev, "DIMM size %dMB @ 0x%08x%s\n", 278183724Ssos (((dimm >> 16) & 0xff)-((dimm >> 24) & 0xff)+1) << 4, 279183724Ssos ((dimm >> 24) & 0xff), 280183724Ssos ATA_INL(ctlr->r_res2, 0x000c0088) & (1<<16) ? 281183724Ssos " ECC enabled" : "" ); 282183724Ssos 283183724Ssos /* adjust cache memory parameters */ 284183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c000c, 285183724Ssos (ATA_INL(ctlr->r_res2, 0x000c000c) & 0xffff0000)); 286183724Ssos 287183724Ssos /* setup host packet controls */ 288183724Ssos hpkt = malloc(sizeof(struct ata_promise_sx4), 289224270Smav M_ATAPCI, M_NOWAIT | M_ZERO); 290253644Smav if (hpkt == NULL) { 291253644Smav device_printf(dev, "Cannot allocate HPKT\n"); 292253644Smav goto failnfree; 293253644Smav } 294183724Ssos mtx_init(&hpkt->mtx, "ATA promise HPKT lock", NULL, MTX_DEF); 295183724Ssos TAILQ_INIT(&hpkt->queue); 296183724Ssos hpkt->busy = 0; 297192105Sjhb ctlr->chipset_data = hpkt; 298188765Smav ctlr->ch_attach = ata_promise_mio_ch_attach; 299188769Smav ctlr->ch_detach = ata_promise_mio_ch_detach; 300183724Ssos ctlr->reset = ata_promise_mio_reset; 301183724Ssos ctlr->setmode = ata_promise_setmode; 302183724Ssos ctlr->channels = 4; 303183724Ssos return 0; 304183724Ssos } 305183724Ssos 306183724Ssos /* mio type controllers need an interrupt intercept */ 307183724Ssos if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) || 308183724Ssos bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL, 309183724Ssos ata_promise_mio_intr, ctlr, &ctlr->handle)) { 310183724Ssos device_printf(dev, "unable to setup interrupt\n"); 311183724Ssos goto failnfree; 312183724Ssos } 313183724Ssos 314183724Ssos switch (ctlr->chip->cfg2) { 315183724Ssos case PR_PATA: 316183724Ssos ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x01) > 0) + 317183724Ssos ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 2; 318183724Ssos goto sata150; 319183724Ssos case PR_CMBO: 320183724Ssos ctlr->channels = 3; 321183724Ssos goto sata150; 322183724Ssos case PR_SATA: 323183724Ssos ctlr->channels = 4; 324183724Ssossata150: 325183724Ssos stat_reg = 0x6c; 326183724Ssos break; 327183724Ssos 328183724Ssos case PR_CMBO2: 329183724Ssos ctlr->channels = 3; 330183724Ssos goto sataii; 331183724Ssos case PR_SATA2: 332183724Ssos default: 333183724Ssos ctlr->channels = 4; 334183724Ssossataii: 335183724Ssos stat_reg = 0x60; 336183724Ssos break; 337183724Ssos } 338183724Ssos 339183724Ssos /* prime fake interrupt register */ 340203043Smav ctlr->chipset_data = (void *)(uintptr_t)0xffffffff; 341183724Ssos 342183724Ssos /* clear SATA status and unmask interrupts */ 343183724Ssos ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff); 344183724Ssos 345183724Ssos /* enable "long burst length" on gen2 chips */ 346183724Ssos if ((ctlr->chip->cfg2 == PR_SATA2) || (ctlr->chip->cfg2 == PR_CMBO2)) 347183724Ssos ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000); 348183724Ssos 349188765Smav ctlr->ch_attach = ata_promise_mio_ch_attach; 350188769Smav ctlr->ch_detach = ata_promise_mio_ch_detach; 351183724Ssos ctlr->reset = ata_promise_mio_reset; 352183724Ssos ctlr->setmode = ata_promise_mio_setmode; 353203034Smav ctlr->getrev = ata_promise_mio_getrev; 354183724Ssos 355183724Ssos return 0; 356183724Ssos } 357183724Ssos 358183724Ssosfailnfree: 359183724Ssos if (ctlr->r_res2) 360183724Ssos bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2); 361183724Ssos if (ctlr->r_res1) 362183724Ssos bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1); 363183724Ssos return ENXIO; 364183724Ssos} 365183724Ssos 366183724Ssosstatic int 367188765Smavata_promise_ch_attach(device_t dev) 368183724Ssos{ 369188765Smav struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 370183724Ssos struct ata_channel *ch = device_get_softc(dev); 371183724Ssos 372188765Smav if (ata_pci_ch_attach(dev)) 373183724Ssos return ENXIO; 374183724Ssos 375188769Smav if (ctlr->chip->cfg1 == PR_NEW) { 376188769Smav ch->dma.start = ata_promise_dmastart; 377188769Smav ch->dma.stop = ata_promise_dmastop; 378188769Smav ch->dma.reset = ata_promise_dmareset; 379188769Smav } 380188769Smav 381183724Ssos ch->hw.status = ata_promise_status; 382200171Smav ch->flags |= ATA_NO_ATAPI_DMA; 383200171Smav ch->flags |= ATA_CHECKS_CABLE; 384183724Ssos return 0; 385183724Ssos} 386183724Ssos 387183724Ssosstatic int 388183724Ssosata_promise_status(device_t dev) 389183724Ssos{ 390183724Ssos struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 391183724Ssos struct ata_channel *ch = device_get_softc(dev); 392183724Ssos 393183724Ssos if (ATA_INL(ctlr->r_res1, 0x1c) & (ch->unit ? 0x00004000 : 0x00000400)) { 394183724Ssos return ata_pci_status(dev); 395183724Ssos } 396183724Ssos return 0; 397183724Ssos} 398183724Ssos 399183724Ssosstatic int 400183724Ssosata_promise_dmastart(struct ata_request *request) 401183724Ssos{ 402198717Smav struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent)); 403183724Ssos struct ata_channel *ch = device_get_softc(request->parent); 404183724Ssos 405198717Smav if (request->flags & ATA_R_48BIT) { 406183724Ssos ATA_OUTB(ctlr->r_res1, 0x11, 407183724Ssos ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02)); 408183724Ssos ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, 409183724Ssos ((request->flags & ATA_R_READ) ? 0x05000000 : 0x06000000) | 410183724Ssos (request->bytecount >> 1)); 411183724Ssos } 412183724Ssos ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, (ATA_IDX_INB(ch, ATA_BMSTAT_PORT) | 413183724Ssos (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 414183724Ssos ATA_IDX_OUTL(ch, ATA_BMDTP_PORT, request->dma->sg_bus); 415183724Ssos ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, 416183724Ssos ((request->flags & ATA_R_READ) ? ATA_BMCMD_WRITE_READ : 0) | 417183724Ssos ATA_BMCMD_START_STOP); 418183724Ssos ch->dma.flags |= ATA_DMA_ACTIVE; 419183724Ssos return 0; 420183724Ssos} 421183724Ssos 422183724Ssosstatic int 423183724Ssosata_promise_dmastop(struct ata_request *request) 424183724Ssos{ 425198717Smav struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent)); 426183724Ssos struct ata_channel *ch = device_get_softc(request->parent); 427183724Ssos int error; 428183724Ssos 429198717Smav if (request->flags & ATA_R_48BIT) { 430183724Ssos ATA_OUTB(ctlr->r_res1, 0x11, 431183724Ssos ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02)); 432183724Ssos ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, 0); 433183724Ssos } 434183724Ssos error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT); 435183724Ssos ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, 436183724Ssos ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 437183724Ssos ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); 438183724Ssos ch->dma.flags &= ~ATA_DMA_ACTIVE; 439183724Ssos return error; 440183724Ssos} 441183724Ssos 442183724Ssosstatic void 443183724Ssosata_promise_dmareset(device_t dev) 444183724Ssos{ 445183724Ssos struct ata_channel *ch = device_get_softc(dev); 446183724Ssos 447183724Ssos ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, 448183724Ssos ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 449183724Ssos ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); 450183724Ssos ch->flags &= ~ATA_DMA_ACTIVE; 451183724Ssos} 452183724Ssos 453200171Smavstatic int 454200171Smavata_promise_setmode(device_t dev, int target, int mode) 455183724Ssos{ 456200171Smav device_t parent = device_get_parent(dev); 457200171Smav struct ata_pci_controller *ctlr = device_get_softc(parent); 458200171Smav struct ata_channel *ch = device_get_softc(dev); 459200171Smav int devno = (ch->unit << 1) + target; 460233282Smarius static const uint32_t timings[][2] = { 461183724Ssos /* PR_OLD PR_NEW mode */ 462183724Ssos { 0x004ff329, 0x004fff2f }, /* PIO 0 */ 463183724Ssos { 0x004fec25, 0x004ff82a }, /* PIO 1 */ 464183724Ssos { 0x004fe823, 0x004ff026 }, /* PIO 2 */ 465183724Ssos { 0x004fe622, 0x004fec24 }, /* PIO 3 */ 466183724Ssos { 0x004fe421, 0x004fe822 }, /* PIO 4 */ 467183724Ssos { 0x004567f3, 0x004acef6 }, /* MWDMA 0 */ 468183724Ssos { 0x004467f3, 0x0048cef6 }, /* MWDMA 1 */ 469183724Ssos { 0x004367f3, 0x0046cef6 }, /* MWDMA 2 */ 470183724Ssos { 0x004367f3, 0x0046cef6 }, /* UDMA 0 */ 471183724Ssos { 0x004247f3, 0x00448ef6 }, /* UDMA 1 */ 472183724Ssos { 0x004127f3, 0x00436ef6 }, /* UDMA 2 */ 473183724Ssos { 0, 0x00424ef6 }, /* UDMA 3 */ 474183724Ssos { 0, 0x004127f3 }, /* UDMA 4 */ 475183724Ssos { 0, 0x004127f3 } /* UDMA 5 */ 476183724Ssos }; 477183724Ssos 478200171Smav mode = min(mode, ctlr->chip->max_dma); 479183724Ssos 480183724Ssos switch (ctlr->chip->cfg1) { 481183724Ssos case PR_OLD: 482183724Ssos case PR_NEW: 483209872Smav if (ata_dma_check_80pin && mode > ATA_UDMA2 && 484209872Smav (pci_read_config(parent, 0x50, 2) & 485183724Ssos (ch->unit ? 1 << 11 : 1 << 10))) { 486183724Ssos ata_print_cable(dev, "controller"); 487183724Ssos mode = ATA_UDMA2; 488183724Ssos } 489183724Ssos break; 490183724Ssos 491183724Ssos case PR_TX: 492183724Ssos ATA_IDX_OUTB(ch, ATA_BMDEVSPEC_0, 0x0b); 493209872Smav if (ata_dma_check_80pin && mode > ATA_UDMA2 && 494183724Ssos ATA_IDX_INB(ch, ATA_BMDEVSPEC_1) & 0x04) { 495183724Ssos ata_print_cable(dev, "controller"); 496183724Ssos mode = ATA_UDMA2; 497183724Ssos } 498183724Ssos break; 499183724Ssos 500183724Ssos case PR_MIO: 501209872Smav if (ata_dma_check_80pin && mode > ATA_UDMA2 && 502183724Ssos (ATA_INL(ctlr->r_res2, 503183724Ssos (ctlr->chip->cfg2 & PR_SX4X ? 0x000c0260 : 0x0260) + 504183724Ssos (ch->unit << 7)) & 0x01000000)) { 505183724Ssos ata_print_cable(dev, "controller"); 506183724Ssos mode = ATA_UDMA2; 507183724Ssos } 508183724Ssos break; 509183724Ssos } 510183724Ssos 511183724Ssos if (ctlr->chip->cfg1 < PR_TX) 512200171Smav pci_write_config(parent, 0x60 + (devno << 2), 513183724Ssos timings[ata_mode2idx(mode)][ctlr->chip->cfg1], 4); 514200171Smav return (mode); 515183724Ssos} 516183724Ssos 517183724Ssosstatic int 518188765Smavata_promise_tx2_ch_attach(device_t dev) 519183724Ssos{ 520183724Ssos struct ata_channel *ch = device_get_softc(dev); 521183724Ssos 522188765Smav if (ata_pci_ch_attach(dev)) 523183724Ssos return ENXIO; 524183724Ssos 525183724Ssos ch->hw.status = ata_promise_tx2_status; 526200171Smav ch->flags |= ATA_CHECKS_CABLE; 527183724Ssos return 0; 528183724Ssos} 529183724Ssos 530183724Ssosstatic int 531183724Ssosata_promise_tx2_status(device_t dev) 532183724Ssos{ 533183724Ssos struct ata_channel *ch = device_get_softc(dev); 534183724Ssos 535183724Ssos ATA_IDX_OUTB(ch, ATA_BMDEVSPEC_0, 0x0b); 536183724Ssos if (ATA_IDX_INB(ch, ATA_BMDEVSPEC_1) & 0x20) { 537183724Ssos return ata_pci_status(dev); 538183724Ssos } 539183724Ssos return 0; 540183724Ssos} 541183724Ssos 542183724Ssosstatic int 543188765Smavata_promise_mio_ch_attach(device_t dev) 544183724Ssos{ 545183724Ssos struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 546183724Ssos struct ata_channel *ch = device_get_softc(dev); 547183724Ssos int offset = (ctlr->chip->cfg2 & PR_SX4X) ? 0x000c0000 : 0; 548183724Ssos int i; 549188765Smav 550188765Smav ata_promise_mio_dmainit(dev); 551188765Smav 552183724Ssos for (i = ATA_DATA; i <= ATA_COMMAND; i++) { 553183724Ssos ch->r_io[i].res = ctlr->r_res2; 554183724Ssos ch->r_io[i].offset = offset + 0x0200 + (i << 2) + (ch->unit << 7); 555183724Ssos } 556183724Ssos ch->r_io[ATA_CONTROL].res = ctlr->r_res2; 557183724Ssos ch->r_io[ATA_CONTROL].offset = offset + 0x0238 + (ch->unit << 7); 558183724Ssos ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2; 559183724Ssos ata_default_registers(dev); 560183724Ssos if ((ctlr->chip->cfg2 & (PR_SATA | PR_SATA2)) || 561183724Ssos ((ctlr->chip->cfg2 & (PR_CMBO | PR_CMBO2)) && ch->unit < 2)) { 562183724Ssos ch->r_io[ATA_SSTATUS].res = ctlr->r_res2; 563183724Ssos ch->r_io[ATA_SSTATUS].offset = 0x400 + (ch->unit << 8); 564183724Ssos ch->r_io[ATA_SERROR].res = ctlr->r_res2; 565183724Ssos ch->r_io[ATA_SERROR].offset = 0x404 + (ch->unit << 8); 566183724Ssos ch->r_io[ATA_SCONTROL].res = ctlr->r_res2; 567183724Ssos ch->r_io[ATA_SCONTROL].offset = 0x408 + (ch->unit << 8); 568183724Ssos ch->flags |= ATA_NO_SLAVE; 569200171Smav ch->flags |= ATA_SATA; 570183724Ssos } 571183724Ssos ch->flags |= ATA_USE_16BIT; 572200171Smav ch->flags |= ATA_CHECKS_CABLE; 573183724Ssos 574183724Ssos ata_generic_hw(dev); 575183724Ssos if (ctlr->chip->cfg2 & PR_SX4X) { 576183724Ssos ch->hw.command = ata_promise_sx4_command; 577183724Ssos } 578183724Ssos else { 579183724Ssos ch->hw.command = ata_promise_mio_command; 580183724Ssos ch->hw.status = ata_promise_mio_status; 581183724Ssos ch->hw.softreset = ata_promise_mio_softreset; 582183724Ssos ch->hw.pm_read = ata_promise_mio_pm_read; 583183724Ssos ch->hw.pm_write = ata_promise_mio_pm_write; 584183724Ssos } 585183724Ssos return 0; 586183724Ssos} 587183724Ssos 588188769Smavstatic int 589188769Smavata_promise_mio_ch_detach(device_t dev) 590188769Smav{ 591188769Smav 592188769Smav ata_dmafini(dev); 593188769Smav return (0); 594188769Smav} 595188769Smav 596183724Ssosstatic void 597183724Ssosata_promise_mio_intr(void *data) 598183724Ssos{ 599183724Ssos struct ata_pci_controller *ctlr = data; 600183724Ssos struct ata_channel *ch; 601183724Ssos u_int32_t vector; 602203043Smav int unit; 603183724Ssos 604183724Ssos /* 605183724Ssos * since reading interrupt status register on early "mio" chips 606183724Ssos * clears the status bits we cannot read it for each channel later on 607183724Ssos * in the generic interrupt routine. 608183724Ssos */ 609183724Ssos vector = ATA_INL(ctlr->r_res2, 0x040); 610183724Ssos ATA_OUTL(ctlr->r_res2, 0x040, vector); 611203043Smav ctlr->chipset_data = (void *)(uintptr_t)vector; 612183724Ssos 613183724Ssos for (unit = 0; unit < ctlr->channels; unit++) { 614183724Ssos if ((ch = ctlr->interrupt[unit].argument)) 615183724Ssos ctlr->interrupt[unit].function(ch); 616183724Ssos } 617183724Ssos 618203043Smav ctlr->chipset_data = (void *)(uintptr_t)0xffffffff; 619183724Ssos} 620183724Ssos 621183724Ssosstatic int 622183724Ssosata_promise_mio_status(device_t dev) 623183724Ssos{ 624183724Ssos struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 625183724Ssos struct ata_channel *ch = device_get_softc(dev); 626203043Smav u_int32_t stat_reg, vector, status; 627183724Ssos 628183724Ssos switch (ctlr->chip->cfg2) { 629183724Ssos case PR_PATA: 630183724Ssos case PR_CMBO: 631183724Ssos case PR_SATA: 632183724Ssos stat_reg = 0x6c; 633183724Ssos break; 634183724Ssos case PR_CMBO2: 635183724Ssos case PR_SATA2: 636183724Ssos default: 637183724Ssos stat_reg = 0x60; 638183724Ssos break; 639183724Ssos } 640183724Ssos 641183724Ssos /* read and acknowledge interrupt */ 642203058Smav vector = (uint32_t)(uintptr_t)ctlr->chipset_data; 643183724Ssos 644183724Ssos /* read and clear interface status */ 645183724Ssos status = ATA_INL(ctlr->r_res2, stat_reg); 646183724Ssos ATA_OUTL(ctlr->r_res2, stat_reg, status & (0x00000011 << ch->unit)); 647183724Ssos 648183724Ssos /* check for and handle disconnect events */ 649188903Smav if (status & (0x00000001 << ch->unit)) { 650183724Ssos if (bootverbose) 651183724Ssos device_printf(dev, "DISCONNECT requested\n"); 652188903Smav taskqueue_enqueue(taskqueue_thread, &ch->conntask); 653183724Ssos } 654183724Ssos 655183724Ssos /* check for and handle connect events */ 656188903Smav if (status & (0x00000010 << ch->unit)) { 657183724Ssos if (bootverbose) 658183724Ssos device_printf(dev, "CONNECT requested\n"); 659188903Smav taskqueue_enqueue(taskqueue_thread, &ch->conntask); 660183724Ssos } 661183724Ssos 662183724Ssos /* do we have any device action ? */ 663183724Ssos return (vector & (1 << (ch->unit + 1))); 664183724Ssos} 665183724Ssos 666183724Ssosstatic int 667183724Ssosata_promise_mio_command(struct ata_request *request) 668183724Ssos{ 669198717Smav struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent)); 670183724Ssos struct ata_channel *ch = device_get_softc(request->parent); 671183724Ssos 672183724Ssos u_int32_t *wordp = (u_int32_t *)ch->dma.work; 673183724Ssos 674183724Ssos ATA_OUTL(ctlr->r_res2, (ch->unit + 1) << 2, 0x00000001); 675183724Ssos 676189295Smav if ((ctlr->chip->cfg2 == PR_SATA2) || 677189295Smav ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) { 678189295Smav /* set portmultiplier port */ 679198717Smav ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), request->unit & 0x0f); 680189295Smav } 681183724Ssos 682183724Ssos /* XXX SOS add ATAPI commands support later */ 683183724Ssos switch (request->u.ata.command) { 684183724Ssos default: 685183724Ssos return ata_generic_command(request); 686183724Ssos 687183724Ssos case ATA_READ_DMA: 688183724Ssos case ATA_READ_DMA48: 689183724Ssos wordp[0] = htole32(0x04 | ((ch->unit + 1) << 16) | (0x00 << 24)); 690183724Ssos break; 691183724Ssos 692183724Ssos case ATA_WRITE_DMA: 693183724Ssos case ATA_WRITE_DMA48: 694183724Ssos wordp[0] = htole32(0x00 | ((ch->unit + 1) << 16) | (0x00 << 24)); 695183724Ssos break; 696183724Ssos } 697183724Ssos wordp[1] = htole32(request->dma->sg_bus); 698183724Ssos wordp[2] = 0; 699183724Ssos ata_promise_apkt((u_int8_t*)wordp, request); 700183724Ssos 701183724Ssos ATA_OUTL(ctlr->r_res2, 0x0240 + (ch->unit << 7), ch->dma.work_bus); 702183724Ssos return 0; 703183724Ssos} 704183724Ssos 705183724Ssosstatic void 706183724Ssosata_promise_mio_reset(device_t dev) 707183724Ssos{ 708183724Ssos struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 709183724Ssos struct ata_channel *ch = device_get_softc(dev); 710183724Ssos struct ata_promise_sx4 *hpktp; 711183724Ssos 712183724Ssos switch (ctlr->chip->cfg2) { 713183724Ssos case PR_SX4X: 714183724Ssos 715183724Ssos /* softreset channel ATA module */ 716192105Sjhb hpktp = ctlr->chipset_data; 717183724Ssos ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), ch->unit + 1); 718183724Ssos ata_udelay(1000); 719183724Ssos ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), 720183724Ssos (ATA_INL(ctlr->r_res2, 0xc0260 + (ch->unit << 7)) & 721183724Ssos ~0x00003f9f) | (ch->unit + 1)); 722183724Ssos 723183724Ssos /* softreset HOST module */ /* XXX SOS what about other outstandings */ 724183724Ssos mtx_lock(&hpktp->mtx); 725183724Ssos ATA_OUTL(ctlr->r_res2, 0xc012c, 726183724Ssos (ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f) | (1 << 11)); 727183724Ssos DELAY(10); 728183724Ssos ATA_OUTL(ctlr->r_res2, 0xc012c, 729183724Ssos (ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f)); 730183724Ssos hpktp->busy = 0; 731183724Ssos mtx_unlock(&hpktp->mtx); 732183724Ssos ata_generic_reset(dev); 733183724Ssos break; 734183724Ssos 735183724Ssos case PR_PATA: 736183724Ssos case PR_CMBO: 737183724Ssos case PR_SATA: 738183724Ssos if ((ctlr->chip->cfg2 == PR_SATA) || 739183724Ssos ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2))) { 740183724Ssos 741183724Ssos /* mask plug/unplug intr */ 742183724Ssos ATA_OUTL(ctlr->r_res2, 0x06c, (0x00110000 << ch->unit)); 743183724Ssos } 744183724Ssos 745183724Ssos /* softreset channels ATA module */ 746183724Ssos ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11)); 747183724Ssos ata_udelay(10000); 748183724Ssos ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), 749183724Ssos (ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) & 750183724Ssos ~0x00003f9f) | (ch->unit + 1)); 751183724Ssos 752183724Ssos if ((ctlr->chip->cfg2 == PR_SATA) || 753183724Ssos ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2))) { 754183724Ssos 755190581Smav if (ata_sata_phy_reset(dev, -1, 1)) 756183724Ssos ata_generic_reset(dev); 757209884Smav else 758209884Smav ch->devices = 0; 759183724Ssos 760183724Ssos /* reset and enable plug/unplug intr */ 761183724Ssos ATA_OUTL(ctlr->r_res2, 0x06c, (0x00000011 << ch->unit)); 762183724Ssos } 763183724Ssos else 764183724Ssos ata_generic_reset(dev); 765183724Ssos break; 766183724Ssos 767183724Ssos case PR_CMBO2: 768183724Ssos case PR_SATA2: 769183724Ssos if ((ctlr->chip->cfg2 == PR_SATA2) || 770183724Ssos ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) { 771183724Ssos /* set portmultiplier port */ 772183724Ssos //ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f); 773183724Ssos 774183724Ssos /* mask plug/unplug intr */ 775183724Ssos ATA_OUTL(ctlr->r_res2, 0x060, (0x00110000 << ch->unit)); 776183724Ssos } 777183724Ssos 778183724Ssos /* softreset channels ATA module */ 779183724Ssos ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11)); 780183724Ssos ata_udelay(10000); 781183724Ssos ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), 782183724Ssos (ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) & 783183724Ssos ~0x00003f9f) | (ch->unit + 1)); 784183724Ssos 785183724Ssos if ((ctlr->chip->cfg2 == PR_SATA2) || 786183724Ssos ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) { 787183724Ssos 788183724Ssos /* set PHY mode to "improved" */ 789183724Ssos ATA_OUTL(ctlr->r_res2, 0x414 + (ch->unit << 8), 790183724Ssos (ATA_INL(ctlr->r_res2, 0x414 + (ch->unit << 8)) & 791183724Ssos ~0x00000003) | 0x00000001); 792183724Ssos 793190581Smav if (ata_sata_phy_reset(dev, -1, 1)) { 794183724Ssos u_int32_t signature = ch->hw.softreset(dev, ATA_PM); 795183724Ssos 796183724Ssos if (1 | bootverbose) 797183724Ssos device_printf(dev, "SIGNATURE: %08x\n", signature); 798183724Ssos 799188906Smav switch (signature >> 16) { 800188906Smav case 0x0000: 801183724Ssos ch->devices = ATA_ATA_MASTER; 802183724Ssos break; 803188906Smav case 0x9669: 804183724Ssos ch->devices = ATA_PORTMULTIPLIER; 805183724Ssos ata_pm_identify(dev); 806183724Ssos break; 807188906Smav case 0xeb14: 808183724Ssos ch->devices = ATA_ATAPI_MASTER; 809183724Ssos break; 810183724Ssos default: /* SOS XXX */ 811183724Ssos if (bootverbose) 812183724Ssos device_printf(dev, 813188935Smav "No signature, assuming disk device\n"); 814183724Ssos ch->devices = ATA_ATA_MASTER; 815183724Ssos } 816183724Ssos if (bootverbose) 817183724Ssos device_printf(dev, "promise_mio_reset devices=%08x\n", 818183724Ssos ch->devices); 819183724Ssos 820203033Smav } else 821203033Smav ch->devices = 0; 822183724Ssos 823183724Ssos /* reset and enable plug/unplug intr */ 824183724Ssos ATA_OUTL(ctlr->r_res2, 0x060, (0x00000011 << ch->unit)); 825183724Ssos 826183724Ssos ///* set portmultiplier port */ 827183724Ssos ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x00); 828183724Ssos } 829183724Ssos else 830183724Ssos ata_generic_reset(dev); 831183724Ssos break; 832183724Ssos 833183724Ssos } 834183724Ssos} 835183724Ssos 836183724Ssosstatic int 837183724Ssosata_promise_mio_pm_read(device_t dev, int port, int reg, u_int32_t *result) 838183724Ssos{ 839183724Ssos struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 840183724Ssos struct ata_channel *ch = device_get_softc(dev); 841183724Ssos int timeout = 0; 842183724Ssos 843214016Smav if (port < 0) { 844214016Smav *result = ATA_IDX_INL(ch, reg); 845214016Smav return (0); 846214016Smav } 847214016Smav if (port < ATA_PM) { 848214016Smav switch (reg) { 849214016Smav case ATA_SSTATUS: 850214016Smav reg = 0; 851214016Smav break; 852214016Smav case ATA_SERROR: 853214016Smav reg = 1; 854214016Smav break; 855214016Smav case ATA_SCONTROL: 856214016Smav reg = 2; 857214016Smav break; 858214016Smav default: 859214016Smav return (EINVAL); 860214016Smav } 861214016Smav } 862183724Ssos /* set portmultiplier port */ 863183724Ssos ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f); 864183724Ssos 865183724Ssos ATA_IDX_OUTB(ch, ATA_FEATURE, reg); 866183724Ssos ATA_IDX_OUTB(ch, ATA_DRIVE, port); 867183724Ssos 868183724Ssos ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_READ_PM); 869183724Ssos 870183724Ssos while (timeout < 1000000) { 871183724Ssos u_int8_t status = ATA_IDX_INB(ch, ATA_STATUS); 872183724Ssos if (!(status & ATA_S_BUSY)) 873183724Ssos break; 874183724Ssos timeout += 1000; 875183724Ssos DELAY(1000); 876183724Ssos } 877183724Ssos if (timeout >= 1000000) 878183724Ssos return ATA_E_ABORT; 879183724Ssos 880183724Ssos *result = ATA_IDX_INB(ch, ATA_COUNT) | 881183724Ssos (ATA_IDX_INB(ch, ATA_SECTOR) << 8) | 882183724Ssos (ATA_IDX_INB(ch, ATA_CYL_LSB) << 16) | 883183724Ssos (ATA_IDX_INB(ch, ATA_CYL_MSB) << 24); 884183724Ssos return 0; 885183724Ssos} 886183724Ssos 887183724Ssosstatic int 888183724Ssosata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t value) 889183724Ssos{ 890183724Ssos struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 891183724Ssos struct ata_channel *ch = device_get_softc(dev); 892183724Ssos int timeout = 0; 893183724Ssos 894214016Smav if (port < 0) { 895214016Smav ATA_IDX_OUTL(ch, reg, value); 896214016Smav return (0); 897214016Smav } 898214016Smav if (port < ATA_PM) { 899214016Smav switch (reg) { 900214016Smav case ATA_SSTATUS: 901214016Smav reg = 0; 902214016Smav break; 903214016Smav case ATA_SERROR: 904214016Smav reg = 1; 905214016Smav break; 906214016Smav case ATA_SCONTROL: 907214016Smav reg = 2; 908214016Smav break; 909214016Smav default: 910214016Smav return (EINVAL); 911214016Smav } 912214016Smav } 913183724Ssos /* set portmultiplier port */ 914183724Ssos ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f); 915183724Ssos 916183724Ssos ATA_IDX_OUTB(ch, ATA_FEATURE, reg); 917183724Ssos ATA_IDX_OUTB(ch, ATA_DRIVE, port); 918183724Ssos ATA_IDX_OUTB(ch, ATA_COUNT, value & 0xff); 919183724Ssos ATA_IDX_OUTB(ch, ATA_SECTOR, (value >> 8) & 0xff); 920183724Ssos ATA_IDX_OUTB(ch, ATA_CYL_LSB, (value >> 16) & 0xff); 921183724Ssos ATA_IDX_OUTB(ch, ATA_CYL_MSB, (value >> 24) & 0xff); 922183724Ssos 923183724Ssos ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_WRITE_PM); 924183724Ssos 925183724Ssos while (timeout < 1000000) { 926183724Ssos u_int8_t status = ATA_IDX_INB(ch, ATA_STATUS); 927183724Ssos if (!(status & ATA_S_BUSY)) 928183724Ssos break; 929183724Ssos timeout += 1000; 930183724Ssos DELAY(1000); 931183724Ssos } 932183724Ssos if (timeout >= 1000000) 933183724Ssos return ATA_E_ABORT; 934183724Ssos 935183724Ssos return ATA_IDX_INB(ch, ATA_ERROR); 936183724Ssos} 937183724Ssos 938183724Ssos/* must be called with ATA channel locked and state_mtx held */ 939183724Ssosstatic u_int32_t 940183724Ssosata_promise_mio_softreset(device_t dev, int port) 941183724Ssos{ 942183724Ssos struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 943183724Ssos struct ata_channel *ch = device_get_softc(dev); 944183724Ssos int timeout; 945183724Ssos 946183724Ssos /* set portmultiplier port */ 947183724Ssos ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), port & 0x0f); 948183724Ssos 949183724Ssos /* softreset device on this channel */ 950183724Ssos ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER)); 951183724Ssos DELAY(10); 952183724Ssos ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS | ATA_A_RESET); 953183724Ssos ata_udelay(10000); 954183724Ssos ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS); 955183724Ssos ata_udelay(150000); 956183724Ssos ATA_IDX_INB(ch, ATA_ERROR); 957183724Ssos 958183724Ssos /* wait for BUSY to go inactive */ 959183724Ssos for (timeout = 0; timeout < 100; timeout++) { 960183724Ssos u_int8_t err, stat; 961183724Ssos 962183724Ssos err = ATA_IDX_INB(ch, ATA_ERROR); 963183724Ssos stat = ATA_IDX_INB(ch, ATA_STATUS); 964183724Ssos 965183724Ssos //if (stat == err && timeout > (stat & ATA_S_BUSY ? 100 : 10)) 966183724Ssos //break; 967183724Ssos 968183724Ssos if (!(stat & ATA_S_BUSY)) { 969183724Ssos //if ((err & 0x7f) == ATA_E_ILI) { 970183724Ssos return ATA_IDX_INB(ch, ATA_COUNT) | 971183724Ssos (ATA_IDX_INB(ch, ATA_SECTOR) << 8) | 972183724Ssos (ATA_IDX_INB(ch, ATA_CYL_LSB) << 16) | 973183724Ssos (ATA_IDX_INB(ch, ATA_CYL_MSB) << 24); 974183724Ssos //} 975183724Ssos //else if (stat & 0x0f) { 976183724Ssos //stat |= ATA_S_BUSY; 977183724Ssos //} 978183724Ssos } 979183724Ssos 980183724Ssos if (!(stat & ATA_S_BUSY) || (stat == 0xff && timeout > 10)) 981183724Ssos break; 982183724Ssos ata_udelay(100000); 983183724Ssos } 984183724Ssos return -1; 985183724Ssos} 986183724Ssos 987183724Ssosstatic void 988183724Ssosata_promise_mio_dmainit(device_t dev) 989183724Ssos{ 990183724Ssos struct ata_channel *ch = device_get_softc(dev); 991183724Ssos 992183724Ssos /* note start and stop are not used here */ 993183724Ssos ch->dma.setprd = ata_promise_mio_setprd; 994200607Smav ch->dma.max_iosize = 65536; 995216013Smarius ata_dmainit(dev); 996183724Ssos} 997183724Ssos 998183724Ssos#define MAXLASTSGSIZE (32 * sizeof(u_int32_t)) 999183724Ssosstatic void 1000183724Ssosata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 1001183724Ssos{ 1002183724Ssos struct ata_dmasetprd_args *args = xsc; 1003183724Ssos struct ata_dma_prdentry *prd = args->dmatab; 1004183724Ssos int i; 1005183724Ssos 1006183724Ssos if ((args->error = error)) 1007183724Ssos return; 1008183724Ssos 1009183724Ssos for (i = 0; i < nsegs; i++) { 1010183724Ssos prd[i].addr = htole32(segs[i].ds_addr); 1011183724Ssos prd[i].count = htole32(segs[i].ds_len); 1012183724Ssos } 1013183724Ssos if (segs[i - 1].ds_len > MAXLASTSGSIZE) { 1014183724Ssos //printf("split last SG element of %u\n", segs[i - 1].ds_len); 1015183724Ssos prd[i - 1].count = htole32(segs[i - 1].ds_len - MAXLASTSGSIZE); 1016183724Ssos prd[i].count = htole32(MAXLASTSGSIZE); 1017183724Ssos prd[i].addr = htole32(segs[i - 1].ds_addr + 1018183724Ssos (segs[i - 1].ds_len - MAXLASTSGSIZE)); 1019183724Ssos nsegs++; 1020183724Ssos i++; 1021183724Ssos } 1022183724Ssos prd[i - 1].count |= htole32(ATA_DMA_EOT); 1023183724Ssos KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries\n")); 1024183724Ssos args->nsegs = nsegs; 1025183724Ssos} 1026183724Ssos 1027200171Smavstatic int 1028200171Smavata_promise_mio_setmode(device_t dev, int target, int mode) 1029183724Ssos{ 1030200171Smav struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 1031200171Smav struct ata_channel *ch = device_get_softc(dev); 1032183724Ssos 1033200171Smav if ( (ctlr->chip->cfg2 == PR_SATA) || 1034200171Smav ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) || 1035203034Smav (ctlr->chip->cfg2 == PR_SATA2) || 1036200171Smav ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) 1037200171Smav mode = ata_sata_setmode(dev, target, mode); 1038200171Smav else 1039200171Smav mode = ata_promise_setmode(dev, target, mode); 1040200171Smav return (mode); 1041183724Ssos} 1042183724Ssos 1043203034Smavstatic int 1044203034Smavata_promise_mio_getrev(device_t dev, int target) 1045203034Smav{ 1046203034Smav struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); 1047203034Smav struct ata_channel *ch = device_get_softc(dev); 1048203034Smav 1049203034Smav if ( (ctlr->chip->cfg2 == PR_SATA) || 1050203034Smav ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) || 1051203034Smav (ctlr->chip->cfg2 == PR_SATA2) || 1052203034Smav ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) 1053203034Smav return (ata_sata_getrev(dev, target)); 1054203034Smav else 1055203034Smav return (0); 1056203034Smav} 1057203034Smav 1058183724Ssosstatic void 1059183724Ssosata_promise_sx4_intr(void *data) 1060183724Ssos{ 1061183724Ssos struct ata_pci_controller *ctlr = data; 1062183724Ssos struct ata_channel *ch; 1063183724Ssos u_int32_t vector = ATA_INL(ctlr->r_res2, 0x000c0480); 1064183724Ssos int unit; 1065183724Ssos 1066183724Ssos for (unit = 0; unit < ctlr->channels; unit++) { 1067183724Ssos if (vector & (1 << (unit + 1))) 1068183724Ssos if ((ch = ctlr->interrupt[unit].argument)) 1069183724Ssos ctlr->interrupt[unit].function(ch); 1070183724Ssos if (vector & (1 << (unit + 5))) 1071183724Ssos if ((ch = ctlr->interrupt[unit].argument)) 1072183724Ssos ata_promise_queue_hpkt(ctlr, 1073183724Ssos htole32((ch->unit * ATA_PDC_CHN_OFFSET) + 1074183724Ssos ATA_PDC_HPKT_OFFSET)); 1075183724Ssos if (vector & (1 << (unit + 9))) { 1076183724Ssos ata_promise_next_hpkt(ctlr); 1077183724Ssos if ((ch = ctlr->interrupt[unit].argument)) 1078183724Ssos ctlr->interrupt[unit].function(ch); 1079183724Ssos } 1080183724Ssos if (vector & (1 << (unit + 13))) { 1081183724Ssos ata_promise_next_hpkt(ctlr); 1082183724Ssos if ((ch = ctlr->interrupt[unit].argument)) 1083183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7), 1084183724Ssos htole32((ch->unit * ATA_PDC_CHN_OFFSET) + 1085183724Ssos ATA_PDC_APKT_OFFSET)); 1086183724Ssos } 1087183724Ssos } 1088183724Ssos} 1089183724Ssos 1090183724Ssosstatic int 1091183724Ssosata_promise_sx4_command(struct ata_request *request) 1092183724Ssos{ 1093198717Smav device_t gparent = device_get_parent(request->parent); 1094183724Ssos struct ata_pci_controller *ctlr = device_get_softc(gparent); 1095183724Ssos struct ata_channel *ch = device_get_softc(request->parent); 1096192433Smav struct ata_dma_prdentry *prd; 1097183724Ssos caddr_t window = rman_get_virtual(ctlr->r_res1); 1098183724Ssos u_int32_t *wordp; 1099183724Ssos int i, idx, length = 0; 1100183724Ssos 1101183724Ssos /* XXX SOS add ATAPI commands support later */ 1102183724Ssos switch (request->u.ata.command) { 1103183724Ssos 1104183724Ssos default: 1105183724Ssos return -1; 1106183724Ssos 1107183724Ssos case ATA_ATA_IDENTIFY: 1108183724Ssos case ATA_READ: 1109183724Ssos case ATA_READ48: 1110183724Ssos case ATA_READ_MUL: 1111183724Ssos case ATA_READ_MUL48: 1112183724Ssos case ATA_WRITE: 1113183724Ssos case ATA_WRITE48: 1114183724Ssos case ATA_WRITE_MUL: 1115183724Ssos case ATA_WRITE_MUL48: 1116183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001); 1117183724Ssos return ata_generic_command(request); 1118183724Ssos 1119183724Ssos case ATA_SETFEATURES: 1120183724Ssos case ATA_FLUSHCACHE: 1121183724Ssos case ATA_FLUSHCACHE48: 1122183724Ssos case ATA_SLEEP: 1123183724Ssos case ATA_SET_MULTI: 1124183724Ssos wordp = (u_int32_t *) 1125183724Ssos (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET); 1126183724Ssos wordp[0] = htole32(0x08 | ((ch->unit + 1)<<16) | (0x00 << 24)); 1127183724Ssos wordp[1] = 0; 1128183724Ssos wordp[2] = 0; 1129183724Ssos ata_promise_apkt((u_int8_t *)wordp, request); 1130183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001); 1131183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001); 1132183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7), 1133183724Ssos htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_APKT_OFFSET)); 1134183724Ssos return 0; 1135183724Ssos 1136183724Ssos case ATA_READ_DMA: 1137183724Ssos case ATA_READ_DMA48: 1138183724Ssos case ATA_WRITE_DMA: 1139183724Ssos case ATA_WRITE_DMA48: 1140192433Smav prd = request->dma->sg; 1141183724Ssos wordp = (u_int32_t *) 1142183724Ssos (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HSG_OFFSET); 1143183724Ssos i = idx = 0; 1144183724Ssos do { 1145183724Ssos wordp[idx++] = prd[i].addr; 1146183724Ssos wordp[idx++] = prd[i].count; 1147183724Ssos length += (prd[i].count & ~ATA_DMA_EOT); 1148183724Ssos } while (!(prd[i++].count & ATA_DMA_EOT)); 1149183724Ssos 1150183724Ssos wordp = (u_int32_t *) 1151183724Ssos (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_LSG_OFFSET); 1152183724Ssos wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE); 1153183724Ssos wordp[1] = htole32(request->bytecount | ATA_DMA_EOT); 1154183724Ssos 1155183724Ssos wordp = (u_int32_t *) 1156183724Ssos (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_ASG_OFFSET); 1157183724Ssos wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE); 1158183724Ssos wordp[1] = htole32(request->bytecount | ATA_DMA_EOT); 1159183724Ssos 1160183724Ssos wordp = (u_int32_t *) 1161183724Ssos (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HPKT_OFFSET); 1162183724Ssos if (request->flags & ATA_R_READ) 1163183724Ssos wordp[0] = htole32(0x14 | ((ch->unit+9)<<16) | ((ch->unit+5)<<24)); 1164183724Ssos if (request->flags & ATA_R_WRITE) 1165183724Ssos wordp[0] = htole32(0x00 | ((ch->unit+13)<<16) | (0x00<<24)); 1166183724Ssos wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_HSG_OFFSET); 1167183724Ssos wordp[2] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_LSG_OFFSET); 1168183724Ssos wordp[3] = 0; 1169183724Ssos 1170183724Ssos wordp = (u_int32_t *) 1171183724Ssos (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET); 1172183724Ssos if (request->flags & ATA_R_READ) 1173183724Ssos wordp[0] = htole32(0x04 | ((ch->unit+5)<<16) | (0x00<<24)); 1174183724Ssos if (request->flags & ATA_R_WRITE) 1175183724Ssos wordp[0] = htole32(0x10 | ((ch->unit+1)<<16) | ((ch->unit+13)<<24)); 1176183724Ssos wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_ASG_OFFSET); 1177183724Ssos wordp[2] = 0; 1178183724Ssos ata_promise_apkt((u_int8_t *)wordp, request); 1179183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001); 1180183724Ssos 1181183724Ssos if (request->flags & ATA_R_READ) { 1182183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+5)<<2), 0x00000001); 1183183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+9)<<2), 0x00000001); 1184183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7), 1185183724Ssos htole32((ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET)); 1186183724Ssos } 1187183724Ssos if (request->flags & ATA_R_WRITE) { 1188183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+1)<<2), 0x00000001); 1189183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+13)<<2), 0x00000001); 1190183724Ssos ata_promise_queue_hpkt(ctlr, 1191183724Ssos htole32((ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HPKT_OFFSET)); 1192183724Ssos } 1193183724Ssos return 0; 1194183724Ssos } 1195183724Ssos} 1196183724Ssos 1197183724Ssosstatic int 1198183724Ssosata_promise_apkt(u_int8_t *bytep, struct ata_request *request) 1199183724Ssos{ 1200183724Ssos int i = 12; 1201183724Ssos 1202183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_PDC_WAIT_NBUSY|ATA_DRIVE; 1203198717Smav bytep[i++] = ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit); 1204183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_CTL; 1205183724Ssos bytep[i++] = ATA_A_4BIT; 1206183724Ssos 1207198717Smav if (request->flags & ATA_R_48BIT) { 1208183724Ssos bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_FEATURE; 1209183724Ssos bytep[i++] = request->u.ata.feature >> 8; 1210183724Ssos bytep[i++] = request->u.ata.feature; 1211183724Ssos bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_COUNT; 1212183724Ssos bytep[i++] = request->u.ata.count >> 8; 1213183724Ssos bytep[i++] = request->u.ata.count; 1214183724Ssos bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_SECTOR; 1215183724Ssos bytep[i++] = request->u.ata.lba >> 24; 1216183724Ssos bytep[i++] = request->u.ata.lba; 1217183724Ssos bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_LSB; 1218183724Ssos bytep[i++] = request->u.ata.lba >> 32; 1219183724Ssos bytep[i++] = request->u.ata.lba >> 8; 1220183724Ssos bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_MSB; 1221183724Ssos bytep[i++] = request->u.ata.lba >> 40; 1222183724Ssos bytep[i++] = request->u.ata.lba >> 16; 1223183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE; 1224198717Smav bytep[i++] = ATA_D_LBA | ATA_DEV(request->unit); 1225183724Ssos } 1226183724Ssos else { 1227183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_FEATURE; 1228183724Ssos bytep[i++] = request->u.ata.feature; 1229183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_COUNT; 1230183724Ssos bytep[i++] = request->u.ata.count; 1231183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_SECTOR; 1232183724Ssos bytep[i++] = request->u.ata.lba; 1233183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_LSB; 1234183724Ssos bytep[i++] = request->u.ata.lba >> 8; 1235183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_MSB; 1236183724Ssos bytep[i++] = request->u.ata.lba >> 16; 1237183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE; 1238198717Smav bytep[i++] = ATA_D_LBA | ATA_D_IBM | ATA_DEV(request->unit) | 1239183724Ssos ((request->u.ata.lba >> 24)&0xf); 1240183724Ssos } 1241183724Ssos bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_END | ATA_COMMAND; 1242183724Ssos bytep[i++] = request->u.ata.command; 1243183724Ssos return i; 1244183724Ssos} 1245183724Ssos 1246183724Ssosstatic void 1247183724Ssosata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt) 1248183724Ssos{ 1249192105Sjhb struct ata_promise_sx4 *hpktp = ctlr->chipset_data; 1250183724Ssos 1251183724Ssos mtx_lock(&hpktp->mtx); 1252183724Ssos if (hpktp->busy) { 1253183724Ssos struct host_packet *hp = 1254183724Ssos malloc(sizeof(struct host_packet), M_TEMP, M_NOWAIT | M_ZERO); 1255183724Ssos hp->addr = hpkt; 1256183724Ssos TAILQ_INSERT_TAIL(&hpktp->queue, hp, chain); 1257183724Ssos } 1258183724Ssos else { 1259183724Ssos hpktp->busy = 1; 1260183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0100, hpkt); 1261183724Ssos } 1262183724Ssos mtx_unlock(&hpktp->mtx); 1263183724Ssos} 1264183724Ssos 1265183724Ssosstatic void 1266183724Ssosata_promise_next_hpkt(struct ata_pci_controller *ctlr) 1267183724Ssos{ 1268192105Sjhb struct ata_promise_sx4 *hpktp = ctlr->chipset_data; 1269183724Ssos struct host_packet *hp; 1270183724Ssos 1271183724Ssos mtx_lock(&hpktp->mtx); 1272183724Ssos if ((hp = TAILQ_FIRST(&hpktp->queue))) { 1273183724Ssos TAILQ_REMOVE(&hpktp->queue, hp, chain); 1274183724Ssos ATA_OUTL(ctlr->r_res2, 0x000c0100, hp->addr); 1275183724Ssos free(hp, M_TEMP); 1276183724Ssos } 1277183724Ssos else 1278183724Ssos hpktp->busy = 0; 1279183724Ssos mtx_unlock(&hpktp->mtx); 1280183724Ssos} 1281183724Ssos 1282183724SsosATA_DECLARE_DRIVER(ata_promise); 1283