ata-all.c revision 74253
1139749Simp/*- 259477Swpaul * Copyright (c) 1998,1999,2000,2001 S�ren Schmidt 359477Swpaul * All rights reserved. 459477Swpaul * 559477Swpaul * Redistribution and use in source and binary forms, with or without 659477Swpaul * modification, are permitted provided that the following conditions 759477Swpaul * are met: 859477Swpaul * 1. Redistributions of source code must retain the above copyright 959477Swpaul * notice, this list of conditions and the following disclaimer, 1059477Swpaul * without modification, immediately at the beginning of the file. 1159477Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1259477Swpaul * notice, this list of conditions and the following disclaimer in the 1359477Swpaul * documentation and/or other materials provided with the distribution. 1459477Swpaul * 3. The name of the author may not be used to endorse or promote products 1559477Swpaul * derived from this software without specific prior written permission. 1659477Swpaul * 1759477Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1859477Swpaul * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1959477Swpaul * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2059477Swpaul * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2159477Swpaul * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2259477Swpaul * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2359477Swpaul * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2459477Swpaul * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2559477Swpaul * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2659477Swpaul * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2759477Swpaul * 2859477Swpaul * $FreeBSD: head/sys/dev/ata/ata-all.c 74253 2001-03-14 14:00:09Z sos $ 2959477Swpaul */ 3059477Swpaul 3159477Swpaul#include "pci.h" 3259477Swpaul#include "opt_ata.h" 33119418Sobrien#include <sys/param.h> 34119418Sobrien#include <sys/systm.h> 35119418Sobrien#include <sys/kernel.h> 3659477Swpaul#include <sys/disk.h> 37165360Sjkim#include <sys/module.h> 3859477Swpaul#include <sys/bus.h> 3959477Swpaul#include <sys/bio.h> 4059477Swpaul#include <sys/malloc.h> 4159477Swpaul#include <sys/devicestat.h> 4259477Swpaul#include <sys/sysctl.h> 43129876Sphk#include <machine/stdarg.h> 4459477Swpaul#include <machine/resource.h> 4559477Swpaul#include <machine/bus.h> 4659477Swpaul#include <sys/rman.h> 4759477Swpaul#ifdef __alpha__ 48157642Sps#include <machine/md_var.h> 4959477Swpaul#endif 5059477Swpaul#include <dev/ata/ata-all.h> 5159477Swpaul#include <dev/ata/ata-disk.h> 5259477Swpaul#include <dev/ata/atapi-all.h> 53109514Sobrien 5459477Swpaul/* prototypes */ 5559477Swpaulstatic void ata_boot_attach(void); 56117659Swpaulstatic void ata_intr(void *); 57117659Swpaulstatic int ata_getparam(struct ata_softc *, int, u_int8_t); 58117659Swpaulstatic int ata_service(struct ata_softc *); 59157642Spsstatic char *active2str(int); 6059477Swpaulstatic void bswap(int8_t *, int); 61119285Simpstatic void btrim(int8_t *, int); 62119285Simpstatic void bpack(int8_t *, int8_t *, int); 63118814Swpaul 6459477Swpaul/* global vars */ 6559477Swpauldevclass_t ata_devclass; 66105135Salfred 67105135Salfred/* local vars */ 6859477Swpaulstatic struct intr_config_hook *ata_delayed_attach = NULL; 69166037Sjkimstatic char ata_conf[256]; 70166037Sjkimstatic MALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer"); 71166037Sjkim 72166037Sjkim/* misc defines */ 73166037Sjkim#define MASTER 0 74166037Sjkim#define SLAVE 1 7559477Swpaul 7659477Swpaulint 7759477Swpaulata_probe(device_t dev) 7859477Swpaul{ 7995722Sphk struct ata_softc *scp; 8059477Swpaul int rid; 8159477Swpaul 8259477Swpaul if (!dev) 8359477Swpaul return ENXIO; 8459477Swpaul scp = device_get_softc(dev); 8559477Swpaul if (!scp || scp->devices) 8659477Swpaul return ENXIO; 8759477Swpaul 8859477Swpaul /* initialize the softc basics */ 89166049Sjkim scp->active = ATA_IDLE; 9059477Swpaul scp->dev = dev; 9159477Swpaul 9259477Swpaul rid = ATA_IOADDR_RID; 9359477Swpaul scp->r_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 9484145Sjlemon ATA_IOSIZE, RF_ACTIVE); 95165360Sjkim if (!scp->r_io) 9684145Sjlemon goto failure; 9796026Sphk 98114590Sps rid = ATA_ALTADDR_RID; 99114590Sps scp->r_altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 100114590Sps ATA_ALTIOSIZE, RF_ACTIVE); 101114590Sps if (!scp->r_altio) 102166031Sjkim goto failure; 103166031Sjkim 104166031Sjkim rid = ATA_BMADDR_RID; 105166031Sjkim scp->r_bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 106166032Sjkim ATA_BMIOSIZE, RF_ACTIVE); 107166032Sjkim 10859477Swpaul if (bootverbose) 109160078Syongari ata_printf(scp, -1, "iobase=0x%04x altiobase=0x%04x bmaddr=0x%04x\n", 110160078Syongari (int)rman_get_start(scp->r_io), 111160078Syongari (int)rman_get_start(scp->r_altio), 112160078Syongari (scp->r_bmio) ? (int)rman_get_start(scp->r_bmio) : 0); 113160078Syongari 114160078Syongari ata_reset(scp); 115160078Syongari 116160078Syongari TAILQ_INIT(&scp->ata_queue); 117164830Smarius TAILQ_INIT(&scp->atapi_queue); 118164830Smarius return 0; 119160078Syongari 120164830Smariusfailure: 121165090Sscottl if (scp->r_io) 122160078Syongari bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io); 123166031Sjkim if (scp->r_altio) 124160078Syongari bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID,scp->r_altio); 125160078Syongari if (scp->r_bmio) 126160078Syongari bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio); 127105135Salfred if (bootverbose) 128150763Simp ata_printf(scp, -1, "probe allocation failed\n"); 12959477Swpaul return ENXIO; 13059477Swpaul} 131164827Smarius 13259477Swpaulint 13359477Swpaulata_attach(device_t dev) 134105135Salfred{ 135150763Simp struct ata_softc *scp; 13659477Swpaul int error, rid; 137166037Sjkim 13859477Swpaul if (!dev) 13959477Swpaul return ENXIO; 14059477Swpaul scp = device_get_softc(dev); 14159477Swpaul if (!scp) 142157642Sps return ENXIO; 143157642Sps 144118814Swpaul rid = ATA_IRQ_RID; 14559477Swpaul scp->r_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 146166037Sjkim RF_SHAREABLE | RF_ACTIVE); 147166037Sjkim if (!scp->r_irq) { 14859477Swpaul ata_printf(scp, -1, "unable to allocate interrupt\n"); 14959477Swpaul return ENXIO; 15059477Swpaul } 15159477Swpaul if ((error = bus_setup_intr(dev, scp->r_irq, INTR_TYPE_BIO|INTR_ENTROPY, 15259477Swpaul ata_intr, scp, &scp->ih))) 15359477Swpaul return error; 15459477Swpaul 15559477Swpaul /* 15659477Swpaul * do not attach devices if we are in early boot, this is done later 15759477Swpaul * when interrupts are enabled by a hook into the boot process. 15859477Swpaul * otherwise attach what the probe has found in scp->devices. 15959477Swpaul */ 16059477Swpaul if (!ata_delayed_attach) { 16159477Swpaul if (scp->devices & ATA_ATA_SLAVE) 16259477Swpaul if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY)) 16359477Swpaul scp->devices &= ~ATA_ATA_SLAVE; 16459477Swpaul if (scp->devices & ATA_ATAPI_SLAVE) 16559477Swpaul if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) 16659477Swpaul scp->devices &= ~ATA_ATAPI_SLAVE; 16759477Swpaul if (scp->devices & ATA_ATA_MASTER) 168165361Sjkim if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY)) 16959477Swpaul scp->devices &= ~ATA_ATA_MASTER; 17059477Swpaul if (scp->devices & ATA_ATAPI_MASTER) 171166037Sjkim if (ata_getparam(scp, ATA_MASTER,ATA_C_ATAPI_IDENTIFY)) 172166037Sjkim scp->devices &= ~ATA_ATAPI_MASTER; 173114590Sps#ifdef DEV_ATADISK 17459477Swpaul if (scp->devices & ATA_ATA_MASTER) 17595667Sphk ad_attach(scp, ATA_MASTER); 17695667Sphk if (scp->devices & ATA_ATA_SLAVE) 17759477Swpaul ad_attach(scp, ATA_SLAVE); 17895667Sphk#endif 179118814Swpaul#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 180157642Sps if (scp->devices & ATA_ATAPI_MASTER) 181157642Sps atapi_attach(scp, ATA_MASTER); 182165361Sjkim if (scp->devices & ATA_ATAPI_SLAVE) 183157642Sps atapi_attach(scp, ATA_SLAVE); 184157642Sps#endif 185157642Sps } 186157642Sps return 0; 187118814Swpaul} 188121816Sbrooks 189118814Swpaulint 190118814Swpaulata_detach(device_t dev) 191118814Swpaul{ 192118814Swpaul struct ata_softc *scp; 193118814Swpaul int s; 194118814Swpaul 195118814Swpaul if (!dev) 196118814Swpaul return ENXIO; 197118814Swpaul scp = device_get_softc(dev); 198118814Swpaul if (!scp || !scp->devices) 199118814Swpaul return ENXIO; 200118814Swpaul 201165343Soleg /* make sure channel is not busy SOS XXX */ 202165343Soleg s = splbio(); 203165343Soleg while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) 204118814Swpaul tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); 20559477Swpaul splx(s); 20659477Swpaul 20759477Swpaul /* disable interrupts on devices */ 20859477Swpaul ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); 20959477Swpaul ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); 21059477Swpaul ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); 21159477Swpaul ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); 21259477Swpaul 213164830Smarius#ifdef DEV_ATADISK 21459477Swpaul if (scp->devices & ATA_ATA_MASTER && scp->dev_softc[MASTER]) 21559477Swpaul ad_detach(scp->dev_softc[MASTER], 1); 21684145Sjlemon if (scp->devices & ATA_ATA_SLAVE && scp->dev_softc[SLAVE]) 217150763Simp ad_detach(scp->dev_softc[SLAVE], 1); 21859477Swpaul#endif 219166037Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 22059477Swpaul if (scp->devices & ATA_ATAPI_MASTER && scp->dev_softc[MASTER]) 22159477Swpaul atapi_detach(scp->dev_softc[MASTER]); 22259477Swpaul if (scp->devices & ATA_ATAPI_SLAVE && scp->dev_softc[SLAVE]) 22359477Swpaul atapi_detach(scp->dev_softc[SLAVE]); 224165343Soleg#endif 22559477Swpaul 22659477Swpaul if (scp->dev_param[MASTER]) { 22759477Swpaul free(scp->dev_param[MASTER], M_ATA); 22859477Swpaul scp->dev_param[MASTER] = NULL; 22959477Swpaul } 23059477Swpaul if (scp->dev_param[SLAVE]) { 23159477Swpaul free(scp->dev_param[SLAVE], M_ATA); 23259477Swpaul scp->dev_param[SLAVE] = NULL; 23359477Swpaul } 234165361Sjkim scp->dev_softc[MASTER] = NULL; 235165361Sjkim scp->dev_softc[SLAVE] = NULL; 23659477Swpaul scp->mode[MASTER] = ATA_PIO; 23759477Swpaul scp->mode[SLAVE] = ATA_PIO; 23859477Swpaul scp->devices = 0; 239165343Soleg 24059477Swpaul bus_teardown_intr(dev, scp->r_irq, scp->ih); 24159477Swpaul bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, scp->r_irq); 24259477Swpaul if (scp->r_bmio) 243114590Sps bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio); 24459477Swpaul bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, scp->r_altio); 24559477Swpaul bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io); 24659477Swpaul scp->active = ATA_IDLE; 24759477Swpaul return 0; 248165343Soleg} 24959477Swpaul 25059477Swpaulint 25159477Swpaulata_resume(device_t dev) 252165360Sjkim{ 25359477Swpaul struct ata_softc *scp = device_get_softc(dev); 25495673Sphk 25583029Swpaul ata_reinit(scp); 25683029Swpaul return 0; 257165360Sjkim} 258165360Sjkim 25959477Swpaulstatic int 26083597Swpaulata_getparam(struct ata_softc *scp, int device, u_int8_t command) 26183597Swpaul{ 262165360Sjkim struct ata_params *ata_parm; 26383597Swpaul int8_t buffer[DEV_BSIZE]; 26483597Swpaul int retry = 0; 26559477Swpaul 26659477Swpaul /* select drive */ 26759477Swpaul ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device); 26859477Swpaul DELAY(1); 26959477Swpaul 27059477Swpaul /* enable interrupt */ 271165343Soleg ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); 27259477Swpaul DELAY(1); 27359477Swpaul 27459477Swpaul /* apparently some devices needs this repeated */ 275165343Soleg do { 27659477Swpaul if (ata_command(scp, device, command, 0, 0, 0, 0, 0, ATA_WAIT_INTR)) { 27759477Swpaul ata_printf(scp, device, "identify failed\n"); 27859477Swpaul return -1; 279165343Soleg } 280165343Soleg if (retry++ > 4) { 281165343Soleg ata_printf(scp, device, "identify retries exceeded\n"); 28284145Sjlemon return -1; 283165343Soleg } 28459477Swpaul } while (ata_wait(scp, device, 28559477Swpaul ((command == ATA_C_ATAPI_IDENTIFY) ? 28659477Swpaul ATA_S_DRQ : (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)))); 287165343Soleg 28859477Swpaul ATA_INSW(scp->r_io, ATA_DATA, (int16_t *)buffer, 289165361Sjkim sizeof(buffer)/sizeof(int16_t)); 290165343Soleg ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT); 29159477Swpaul if (!ata_parm) { 292165343Soleg ata_printf(scp, device, "malloc for identify data failed\n"); 29359477Swpaul return -1; 294165343Soleg } 295165343Soleg bcopy(buffer, ata_parm, sizeof(struct ata_params)); 296128870Sandre if (command == ATA_C_ATA_IDENTIFY || 297164830Smarius !((ata_parm->model[0] == 'N' && ata_parm->model[1] == 'E') || 298165343Soleg (ata_parm->model[0] == 'F' && ata_parm->model[1] == 'X'))) 299165343Soleg bswap(ata_parm->model, sizeof(ata_parm->model)); 300165343Soleg btrim(ata_parm->model, sizeof(ata_parm->model)); 301165343Soleg bpack(ata_parm->model, ata_parm->model, sizeof(ata_parm->model)); 30284145Sjlemon bswap(ata_parm->revision, sizeof(ata_parm->revision)); 303165360Sjkim btrim(ata_parm->revision, sizeof(ata_parm->revision)); 304153234Soleg bpack(ata_parm->revision, ata_parm->revision, sizeof(ata_parm->revision)); 30559477Swpaul scp->dev_param[ATA_DEV(device)] = ata_parm; 30659477Swpaul return 0; 30759477Swpaul} 30859477Swpaul 30959477Swpaulstatic void 310114628Spsata_boot_attach(void) 311114628Sps{ 312114628Sps struct ata_softc *scp; 313114628Sps int ctlr; 314164830Smarius 315114628Sps /* 316114628Sps * run through all ata devices and look for real ATA & ATAPI devices 317166037Sjkim * using the hints we found in the early probe, this avoids some of 318151370Sgrehan * the delays probing of non-exsistent devices can cause. 319114628Sps */ 320114628Sps for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) { 321166031Sjkim if (!(scp = devclass_get_softc(ata_devclass, ctlr))) 322166037Sjkim continue; 323166031Sjkim if (scp->devices & ATA_ATA_SLAVE) 324166031Sjkim if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY)) 325114628Sps scp->devices &= ~ATA_ATA_SLAVE; 326114628Sps if (scp->devices & ATA_ATAPI_SLAVE) 327114628Sps if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) 328114628Sps scp->devices &= ~ATA_ATAPI_SLAVE; 329114628Sps if (scp->devices & ATA_ATA_MASTER) 330128870Sandre if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY)) 33159477Swpaul scp->devices &= ~ATA_ATA_MASTER; 33259477Swpaul if (scp->devices & ATA_ATAPI_MASTER) 33359477Swpaul if (ata_getparam(scp, ATA_MASTER, ATA_C_ATAPI_IDENTIFY)) 33484145Sjlemon scp->devices &= ~ATA_ATAPI_MASTER; 335165360Sjkim } 336165360Sjkim 337166037Sjkim#ifdef DEV_ATADISK 338165360Sjkim /* now we know whats there, do the real attach, first the ATA disks */ 339165360Sjkim for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) { 340165360Sjkim if (!(scp = devclass_get_softc(ata_devclass, ctlr))) 341165360Sjkim continue; 342165360Sjkim if (scp->devices & ATA_ATA_MASTER) 343165360Sjkim ad_attach(scp, ATA_MASTER); 344165360Sjkim if (scp->devices & ATA_ATA_SLAVE) 345165360Sjkim ad_attach(scp, ATA_SLAVE); 346165360Sjkim } 347165360Sjkim#endif 348165360Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 349165360Sjkim /* then the atapi devices */ 350165360Sjkim for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) { 351165360Sjkim if (!(scp = devclass_get_softc(ata_devclass, ctlr))) 352165360Sjkim continue; 353165360Sjkim if (scp->devices & ATA_ATAPI_MASTER) 354165360Sjkim atapi_attach(scp, ATA_MASTER); 355165360Sjkim if (scp->devices & ATA_ATAPI_SLAVE) 356165360Sjkim atapi_attach(scp, ATA_SLAVE); 357165360Sjkim } 358165360Sjkim#endif 359165360Sjkim if (ata_delayed_attach) { 360165360Sjkim config_intrhook_disestablish(ata_delayed_attach); 361165360Sjkim free(ata_delayed_attach, M_ATA); 362165360Sjkim ata_delayed_attach = NULL; 363165360Sjkim } 364165360Sjkim} 365165360Sjkim 366165360Sjkimstatic void 367165360Sjkimata_intr(void *data) 368165360Sjkim{ 369165360Sjkim struct ata_softc *scp = (struct ata_softc *)data; 370165360Sjkim 371166037Sjkim /* 372165360Sjkim * on PCI systems we might share an interrupt line with another 373165360Sjkim * device or our twin ATA channel, so call scp->intr_func to figure 374165360Sjkim * out if it is really an interrupt we should process here 375165360Sjkim */ 376165360Sjkim if (scp->intr_func && scp->intr_func(scp)) 377165360Sjkim return; 378165360Sjkim 379165360Sjkim /* if drive is busy it didn't interrupt */ 380165360Sjkim if (ATA_INB(scp->r_altio, ATA_ALTSTAT) & ATA_S_BUSY) 381165360Sjkim return; 382165360Sjkim 383165360Sjkim /* clear interrupt and get status */ 384165360Sjkim scp->status = ATA_INB(scp->r_io, ATA_STATUS); 385165360Sjkim 386165360Sjkim if (scp->status & ATA_S_ERROR) 387165360Sjkim scp->error = ATA_INB(scp->r_io, ATA_ERROR); 388165360Sjkim 389165360Sjkim /* find & call the responsible driver to process this interrupt */ 390165360Sjkim switch (scp->active) { 391150763Simp#ifdef DEV_ATADISK 39259477Swpaul case ATA_ACTIVE_ATA: 39359477Swpaul if (!scp->running || ad_interrupt(scp->running) == ATA_OP_CONTINUES) 39483029Swpaul return; 395165360Sjkim break; 39659477Swpaul#endif 39759477Swpaul#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 39859477Swpaul case ATA_ACTIVE_ATAPI: 39959477Swpaul if (!scp->running || atapi_interrupt(scp->running) == ATA_OP_CONTINUES) 400165360Sjkim return; 40159477Swpaul break; 402165360Sjkim#endif 403165360Sjkim case ATA_WAIT_INTR: 40459477Swpaul case ATA_WAIT_INTR | ATA_REINITING: 40559477Swpaul wakeup((caddr_t)scp); 40659477Swpaul break; 40759477Swpaul 40859477Swpaul case ATA_WAIT_READY: 40959477Swpaul case ATA_WAIT_READY | ATA_REINITING: 41059477Swpaul break; 41159477Swpaul 41259477Swpaul case ATA_IDLE: 41359477Swpaul if (scp->flags & ATA_QUEUED) { 41459477Swpaul scp->active = ATA_ACTIVE; /* XXX */ 415165360Sjkim if (ata_service(scp) == ATA_OP_CONTINUES) 41659477Swpaul return; 417165360Sjkim } 41883029Swpaul /* FALLTHROUGH */ 41983029Swpaul 42083029Swpaul default: 42195673Sphk#ifdef ATA_DEBUG 42283029Swpaul { 42383029Swpaul static int intr_count = 0; 42495673Sphk 42583029Swpaul if (intr_count++ < 10) 42683029Swpaul ata_printf(scp, -1, "unwanted interrupt %d status = %02x\n", 42783029Swpaul intr_count, scp->status); 42883029Swpaul } 42983029Swpaul#endif 43083029Swpaul } 43183029Swpaul scp->active &= ATA_REINITING; 43283029Swpaul if (scp->active & ATA_REINITING) 43383029Swpaul return; 43483029Swpaul scp->running = NULL; 43583029Swpaul ata_start(scp); 43683029Swpaul return; 43783029Swpaul} 43883029Swpaul 43983029Swpaulvoid 44083029Swpaulata_start(struct ata_softc *scp) 44183029Swpaul{ 44283029Swpaul#ifdef DEV_ATADISK 44383029Swpaul struct ad_request *ad_request; 44483029Swpaul#endif 445165360Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 446165360Sjkim struct atapi_request *atapi_request; 44759477Swpaul#endif 44859477Swpaul 44959477Swpaul if (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) 450165360Sjkim return; 45159477Swpaul 452166037Sjkim#ifdef DEV_ATADISK 45396026Sphk /* find & call the responsible driver if anything on the ATA queue */ 45459477Swpaul if (TAILQ_EMPTY(&scp->ata_queue)) { 455165360Sjkim if (scp->devices & (ATA_ATA_MASTER) && scp->dev_softc[MASTER]) 456165360Sjkim ad_start((struct ad_softc *)scp->dev_softc[MASTER]); 457165360Sjkim if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[SLAVE]) 458166037Sjkim ad_start((struct ad_softc *)scp->dev_softc[SLAVE]); 459165361Sjkim } 460165360Sjkim if ((ad_request = TAILQ_FIRST(&scp->ata_queue))) { 461165360Sjkim TAILQ_REMOVE(&scp->ata_queue, ad_request, chain); 46296026Sphk scp->active = ATA_ACTIVE_ATA; 463165360Sjkim scp->running = ad_request; 464165360Sjkim if (ad_transfer(ad_request) == ATA_OP_CONTINUES) 46596026Sphk return; 466165360Sjkim } 46796026Sphk 468165360Sjkim#endif 46959477Swpaul#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 47059477Swpaul /* find & call the responsible driver if anything on the ATAPI queue */ 471114590Sps if (TAILQ_EMPTY(&scp->atapi_queue)) { 472114590Sps if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[MASTER]) 473114590Sps atapi_start((struct atapi_softc *)scp->dev_softc[MASTER]); 474114590Sps if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[SLAVE]) 475114590Sps atapi_start((struct atapi_softc *)scp->dev_softc[SLAVE]); 476114590Sps } 477114590Sps if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue))) { 478114590Sps TAILQ_REMOVE(&scp->atapi_queue, atapi_request, chain); 479164830Smarius scp->active = ATA_ACTIVE_ATAPI; 480114590Sps scp->running = atapi_request; 481114590Sps atapi_transfer(atapi_request); 482114590Sps return; 483114590Sps } 484114590Sps#endif 485114590Sps scp->active = ATA_IDLE; 486114590Sps} 487114590Sps 488114590Spsvoid 489114590Spsata_reset(struct ata_softc *scp) 490114590Sps{ 491114590Sps u_int8_t lsb, msb, ostat0, ostat1; 492114590Sps u_int8_t stat0 = ATA_S_BUSY, stat1 = ATA_S_BUSY; 493114590Sps int mask = 0, timeout; 494114590Sps 495114590Sps /* do we have any signs of ATA/ATAPI HW being present ? */ 496114590Sps ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); 497114590Sps DELAY(10); 498114590Sps ostat0 = ATA_INB(scp->r_io, ATA_STATUS); 499114590Sps if ((ostat0 & 0xf8) != 0xf8 && ostat0 != 0xa5) 500114590Sps mask |= 0x01; 501114590Sps ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); 502114590Sps DELAY(10); 503114590Sps ostat1 = ATA_INB(scp->r_io, ATA_STATUS); 504114590Sps if ((ostat1 & 0xf8) != 0xf8 && ostat1 != 0xa5) 505114590Sps mask |= 0x02; 506114590Sps 507114590Sps scp->devices = 0; 508114590Sps if (!mask) 509114590Sps return; 510114590Sps 511114590Sps /* in some setups we dont want to test for a slave */ 512114590Sps if (scp->flags & ATA_NO_SLAVE) 513114590Sps mask &= ~0x02; 514114590Sps 515114590Sps if (bootverbose) 516114590Sps ata_printf(scp, -1, "mask=%02x ostat0=%02x ostat2=%02x\n", 517114590Sps mask, ostat0, ostat1); 518114590Sps 519114590Sps /* reset channel */ 520114590Sps ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET); 521114590Sps DELAY(10000); 522114590Sps ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS); 523114590Sps DELAY(100000); 524114590Sps ATA_INB(scp->r_io, ATA_ERROR); 525114590Sps 526114590Sps /* wait for BUSY to go inactive */ 527114590Sps for (timeout = 0; timeout < 310000; timeout++) { 528114590Sps if (stat0 & ATA_S_BUSY) { 529114590Sps ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); 530114590Sps DELAY(10); 531114590Sps stat0 = ATA_INB(scp->r_io, ATA_STATUS); 532114590Sps if (!(stat0 & ATA_S_BUSY)) { 533114590Sps /* check for ATAPI signature while its still there */ 534114590Sps lsb = ATA_INB(scp->r_io, ATA_CYL_LSB); 535114590Sps msb = ATA_INB(scp->r_io, ATA_CYL_MSB); 536166031Sjkim if (bootverbose) 537114590Sps ata_printf(scp, ATA_MASTER, 538114590Sps "ATAPI probe %02x %02x\n", lsb, msb); 539114590Sps if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) 540114590Sps scp->devices |= ATA_ATAPI_MASTER; 541114590Sps } 542114590Sps } 543114590Sps if (stat1 & ATA_S_BUSY) { 544114590Sps ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); 545114590Sps DELAY(10); 546114590Sps stat1 = ATA_INB(scp->r_io, ATA_STATUS); 547114590Sps if (!(stat1 & ATA_S_BUSY)) { 548114590Sps /* check for ATAPI signature while its still there */ 549114590Sps lsb = ATA_INB(scp->r_io, ATA_CYL_LSB); 550114590Sps msb = ATA_INB(scp->r_io, ATA_CYL_MSB); 551114590Sps if (bootverbose) 552114590Sps ata_printf(scp, ATA_SLAVE, 553114590Sps "ATAPI probe %02x %02x\n", lsb, msb); 554166031Sjkim if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) 555114590Sps scp->devices |= ATA_ATAPI_SLAVE; 556114590Sps } 557114590Sps } 558114590Sps if (mask == 0x01) /* wait for master only */ 559114590Sps if (!(stat0 & ATA_S_BUSY)) 560114590Sps break; 561114590Sps if (mask == 0x02) /* wait for slave only */ 562114590Sps if (!(stat1 & ATA_S_BUSY)) 563114590Sps break; 564114590Sps if (mask == 0x03) /* wait for both master & slave */ 565114590Sps if (!(stat0 & ATA_S_BUSY) && !(stat1 & ATA_S_BUSY)) 566114590Sps break; 567114590Sps DELAY(100); 568114590Sps } 569114590Sps DELAY(10); 570114590Sps ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); 571166031Sjkim 572135772Sps if (stat0 & ATA_S_BUSY) 573135772Sps mask &= ~0x01; 574135772Sps if (stat1 & ATA_S_BUSY) 575135772Sps mask &= ~0x02; 576135772Sps if (bootverbose) 577166665Sjkim ata_printf(scp, -1, "mask=%02x stat0=%02x stat1=%02x\n", 578166665Sjkim mask, stat0, stat1); 579166665Sjkim if (!mask) 580166665Sjkim return; 581166665Sjkim 582166665Sjkim if (mask & 0x01 && ostat0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) { 583166665Sjkim ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); 584166665Sjkim DELAY(10); 585135772Sps ATA_OUTB(scp->r_io, ATA_ERROR, 0x58); 586135772Sps ATA_OUTB(scp->r_io, ATA_CYL_LSB, 0xa5); 587135772Sps lsb = ATA_INB(scp->r_io, ATA_ERROR); 588135772Sps msb = ATA_INB(scp->r_io, ATA_CYL_LSB); 589135772Sps if (bootverbose) 590135772Sps ata_printf(scp, ATA_MASTER, "ATA probe %02x %02x\n", lsb, msb); 591135772Sps if (lsb != 0x58 && msb == 0xa5) 592135772Sps scp->devices |= ATA_ATA_MASTER; 593135772Sps } 594166031Sjkim if (mask & 0x02 && ostat1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) { 595166031Sjkim ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); 596166031Sjkim DELAY(10); 597166031Sjkim ATA_OUTB(scp->r_io, ATA_ERROR, 0x58); 598166031Sjkim ATA_OUTB(scp->r_io, ATA_CYL_LSB, 0xa5); 599166031Sjkim lsb = ATA_INB(scp->r_io, ATA_ERROR); 600166031Sjkim msb = ATA_INB(scp->r_io, ATA_CYL_LSB); 601166031Sjkim if (bootverbose) 602166031Sjkim ata_printf(scp, ATA_SLAVE, "ATA probe %02x %02x\n", lsb, msb); 603166031Sjkim if (lsb != 0x58 && msb == 0xa5) 604166031Sjkim scp->devices |= ATA_ATA_SLAVE; 605166031Sjkim } 606166031Sjkim if (bootverbose) 607166031Sjkim ata_printf(scp, -1, "devices=%02x\n", scp->devices); 608166031Sjkim} 609166031Sjkim 610166031Sjkimint 611166031Sjkimata_reinit(struct ata_softc *scp) 612166031Sjkim{ 613166032Sjkim int devices, misdev, newdev; 614166032Sjkim 615166032Sjkim scp->active = ATA_REINITING; 616166032Sjkim scp->running = NULL; 617166032Sjkim devices = scp->devices; 618166032Sjkim ata_printf(scp, -1, "resetting devices .. "); 619166032Sjkim ata_reset(scp); 620166032Sjkim 621166032Sjkim if ((misdev = devices & ~scp->devices)) { 622166032Sjkim#ifdef DEV_ATADISK 623166032Sjkim if (misdev & ATA_ATA_MASTER && scp->dev_softc[MASTER]) 624166032Sjkim ad_detach(scp->dev_softc[MASTER], 0); 625166032Sjkim if (misdev & ATA_ATA_SLAVE && scp->dev_softc[SLAVE]) 626166666Sjkim ad_detach(scp->dev_softc[SLAVE], 0); 627166032Sjkim#endif 628166032Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 629166032Sjkim if (misdev & ATA_ATAPI_MASTER && scp->dev_softc[MASTER]) 630166032Sjkim atapi_detach(scp->dev_softc[MASTER]); 631166666Sjkim if (misdev & ATA_ATAPI_SLAVE && scp->dev_softc[SLAVE]) 632166666Sjkim atapi_detach(scp->dev_softc[SLAVE]); 633166666Sjkim#endif 634166666Sjkim if (misdev & ATA_ATA_MASTER || misdev & ATA_ATAPI_MASTER) { 635166666Sjkim free(scp->dev_param[MASTER], M_ATA); 636166666Sjkim scp->dev_param[MASTER] = NULL; 637166666Sjkim } 638166666Sjkim if (misdev & ATA_ATA_SLAVE || misdev & ATA_ATAPI_SLAVE) { 639166032Sjkim free(scp->dev_param[SLAVE], M_ATA); 640166032Sjkim scp->dev_param[SLAVE] = NULL; 641166032Sjkim } 642166032Sjkim } 643166032Sjkim if ((newdev = ~devices & scp->devices)) { 644166032Sjkim if (newdev & ATA_ATA_MASTER) 645166032Sjkim if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY)) 646166032Sjkim newdev &= ~ATA_ATA_MASTER; 647166032Sjkim if (newdev & ATA_ATA_SLAVE) 648166032Sjkim if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY)) 649166032Sjkim newdev &= ~ATA_ATA_SLAVE; 650166032Sjkim if (newdev & ATA_ATAPI_MASTER) 651166032Sjkim if (ata_getparam(scp, ATA_MASTER, ATA_C_ATAPI_IDENTIFY)) 652166032Sjkim newdev &= ~ATA_ATAPI_MASTER; 653166032Sjkim if (newdev & ATA_ATAPI_SLAVE) 654166032Sjkim if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) 655166032Sjkim newdev &= ~ATA_ATAPI_SLAVE; 656114590Sps if (newdev) 657114590Sps printf("\n"); 658166037Sjkim } 659166037Sjkim scp->active = ATA_IDLE; 660166037Sjkim#ifdef DEV_ATADISK 661166037Sjkim if (newdev & ATA_ATA_MASTER && !scp->dev_softc[MASTER]) 662114590Sps ad_attach(scp, ATA_MASTER); 663114590Sps else if (scp->devices & ATA_ATA_MASTER && scp->dev_softc[MASTER]) 664114590Sps ad_reinit((struct ad_softc *)scp->dev_softc[MASTER]); 665166037Sjkim if (newdev & ATA_ATA_SLAVE && !scp->dev_softc[SLAVE]) 666151370Sgrehan ad_attach(scp, ATA_SLAVE); 667114590Sps else if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[SLAVE]) 668114590Sps ad_reinit((struct ad_softc *)scp->dev_softc[SLAVE]); 669166031Sjkim#endif 670166037Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 671166031Sjkim if (newdev & ATA_ATAPI_MASTER && !scp->dev_softc[MASTER]) 672166031Sjkim atapi_attach(scp, ATA_MASTER); 673114590Sps else if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[MASTER]) 674114590Sps atapi_reinit((struct atapi_softc *)scp->dev_softc[MASTER]); 675114590Sps if (newdev & ATA_ATAPI_SLAVE && !scp->dev_softc[SLAVE]) 676114590Sps atapi_attach(scp, ATA_SLAVE); 677114590Sps else if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[SLAVE]) 678117659Swpaul atapi_reinit((struct atapi_softc *)scp->dev_softc[SLAVE]); 679117659Swpaul#endif 680157642Sps printf("done\n"); 681157642Sps ata_start(scp); 682165361Sjkim return 0; 683157642Sps} 684157642Sps 685157642Spsstatic int 686117659Swpaulata_service(struct ata_softc *scp) 687157642Sps{ 688157642Sps /* do we have a SERVICE request from the drive ? */ 689166031Sjkim if ((scp->status & (ATA_S_SERVICE|ATA_S_ERROR|ATA_S_DRQ)) == ATA_S_SERVICE){ 690166031Sjkim ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT, 691166031Sjkim ata_dmastatus(scp) | ATA_BMSTAT_INTERRUPT); 692166031Sjkim#ifdef DEV_ATADISK 693166031Sjkim if ((ATA_INB(scp->r_io, ATA_DRIVE) & ATA_SLAVE) == ATA_MASTER) { 694166031Sjkim if ((scp->devices & ATA_ATA_MASTER) && scp->dev_softc[MASTER]) 695166031Sjkim return ad_service((struct ad_softc *)scp->dev_softc[MASTER], 0); 696166031Sjkim } 697166031Sjkim else { 698157642Sps if ((scp->devices & ATA_ATA_SLAVE) && scp->dev_softc[SLAVE]) 699166032Sjkim return ad_service((struct ad_softc *)scp->dev_softc[SLAVE], 0); 700157642Sps } 701166032Sjkim#endif 702166032Sjkim } 703166032Sjkim return ATA_OP_FINISHED; 704166032Sjkim} 705166032Sjkim 706166032Sjkimint 707166032Sjkimata_wait(struct ata_softc *scp, int device, u_int8_t mask) 708166032Sjkim{ 709166032Sjkim int timeout = 0; 710166032Sjkim 711166032Sjkim DELAY(1); 712164830Smarius while (timeout < 5000000) { /* timeout 5 secs */ 713166032Sjkim scp->status = ATA_INB(scp->r_io, ATA_STATUS); 714166032Sjkim 715157642Sps /* if drive fails status, reselect the drive just to be sure */ 716166032Sjkim if (scp->status == 0xff) { 717166032Sjkim ata_printf(scp, device, "no status, reselecting device\n"); 718166032Sjkim ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device); 719166032Sjkim DELAY(10); 720119157Sambrisko scp->status = ATA_INB(scp->r_io, ATA_STATUS); 721114590Sps if (scp->status == 0xff) 722 return -1; 723 } 724 725 /* are we done ? */ 726 if (!(scp->status & ATA_S_BUSY)) 727 break; 728 729 if (timeout > 1000) { 730 timeout += 1000; 731 DELAY(1000); 732 } 733 else { 734 timeout += 10; 735 DELAY(10); 736 } 737 } 738 if (scp->status & ATA_S_ERROR) 739 scp->error = ATA_INB(scp->r_io, ATA_ERROR); 740 if (timeout >= 5000000) 741 return -1; 742 if (!mask) 743 return (scp->status & ATA_S_ERROR); 744 745 /* Wait 50 msec for bits wanted. */ 746 timeout = 5000; 747 while (timeout--) { 748 scp->status = ATA_INB(scp->r_io, ATA_STATUS); 749 if ((scp->status & mask) == mask) { 750 if (scp->status & ATA_S_ERROR) 751 scp->error = ATA_INB(scp->r_io, ATA_ERROR); 752 return (scp->status & ATA_S_ERROR); 753 } 754 DELAY (10); 755 } 756 return -1; 757} 758 759int 760ata_command(struct ata_softc *scp, int device, u_int8_t command, 761 u_int16_t cylinder, u_int8_t head, u_int8_t sector, 762 u_int8_t count, u_int8_t feature, int flags) 763{ 764 int error = 0; 765#ifdef ATA_DEBUG 766 ata_printf(scp, device, "ata_command: addr=%04x, cmd=%02x, " 767 "c=%d, h=%d, s=%d, count=%d, feature=%d, flags=%02x\n", 768 rman_get_start(scp->r_io), command, cylinder, head, sector, 769 count, feature, flags); 770#endif 771 772 /* disable interrupt from device */ 773 if (scp->flags & ATA_QUEUED) 774 ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); 775 776 /* select device */ 777 ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device); 778 779 /* ready to issue command ? */ 780 if (ata_wait(scp, device, 0) < 0) { 781 ata_printf(scp, device, 782 "timeout waiting to give command=%02x s=%02x e=%02x\n", 783 command, scp->status, scp->error); 784 return -1; 785 } 786 787 ATA_OUTB(scp->r_io, ATA_FEATURE, feature); 788 ATA_OUTB(scp->r_io, ATA_COUNT, count); 789 ATA_OUTB(scp->r_io, ATA_SECTOR, sector); 790 ATA_OUTB(scp->r_io, ATA_CYL_MSB, cylinder >> 8); 791 ATA_OUTB(scp->r_io, ATA_CYL_LSB, cylinder); 792 ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device | head); 793 794 switch (flags) { 795 case ATA_WAIT_INTR: 796 scp->active |= ATA_WAIT_INTR; 797 asleep((caddr_t)scp, PRIBIO, "atacmd", 10 * hz); 798 ATA_OUTB(scp->r_io, ATA_CMD, command); 799 800 /* enable interrupt */ 801 if (scp->flags & ATA_QUEUED) 802 ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); 803 804 if (await(PRIBIO, 10 * hz)) { 805 ata_printf(scp, device, "ata_command: timeout waiting for intr\n"); 806 scp->active &= ~ATA_WAIT_INTR; 807 error = -1; 808 } 809 break; 810 811 case ATA_WAIT_READY: 812 scp->active |= ATA_WAIT_READY; 813 ATA_OUTB(scp->r_io, ATA_CMD, command); 814 if (ata_wait(scp, device, ATA_S_READY) < 0) { 815 ata_printf(scp, device, 816 "timeout waiting for command=%02x s=%02x e=%02x\n", 817 command, scp->status, scp->error); 818 error = -1; 819 } 820 scp->active &= ~ATA_WAIT_READY; 821 break; 822 823 case ATA_IMMEDIATE: 824 ATA_OUTB(scp->r_io, ATA_CMD, command); 825 break; 826 827 default: 828 ata_printf(scp, device, "DANGER: illegal interrupt flag=%s\n", 829 active2str(flags)); 830 } 831 /* enable interrupt */ 832 if (scp->flags & ATA_QUEUED) 833 ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); 834 return error; 835} 836 837int 838ata_get_lun(u_int32_t *map) 839{ 840 int lun = ffs(~*map) - 1; 841 842 *map |= (1 << lun); 843 return lun; 844} 845 846int 847ata_test_lun(u_int32_t *map, int lun) 848{ 849 return (*map & (1 << lun)); 850} 851 852void 853ata_free_lun(u_int32_t *map, int lun) 854{ 855 *map &= ~(1 << lun); 856} 857 858int 859ata_printf(struct ata_softc *scp, int device, const char * fmt, ...) 860{ 861 va_list ap; 862 int ret; 863 864 if (device == -1) 865 ret = printf("ata%d: ", device_get_unit(scp->dev)); 866 else 867 ret = printf("ata%d-%s: ", device_get_unit(scp->dev), 868 (device == ATA_MASTER) ? "master" : "slave"); 869 va_start(ap, fmt); 870 ret += vprintf(fmt, ap); 871 va_end(ap); 872 return ret; 873} 874 875char * 876ata_mode2str(int mode) 877{ 878 switch (mode) { 879 case ATA_PIO: return "BIOSPIO"; 880 case ATA_PIO0: return "PIO0"; 881 case ATA_PIO1: return "PIO1"; 882 case ATA_PIO2: return "PIO2"; 883 case ATA_PIO3: return "PIO3"; 884 case ATA_PIO4: return "PIO4"; 885 case ATA_WDMA2: return "WDMA2"; 886 case ATA_UDMA2: return "UDMA33"; 887 case ATA_UDMA4: return "UDMA66"; 888 case ATA_UDMA5: return "UDMA100"; 889 case ATA_DMA: return "BIOSDMA"; 890 default: return "???"; 891 } 892} 893 894int 895ata_pio2mode(int pio) 896{ 897 switch (pio) { 898 default: 899 case 0: return ATA_PIO0; 900 case 1: return ATA_PIO1; 901 case 2: return ATA_PIO2; 902 case 3: return ATA_PIO3; 903 case 4: return ATA_PIO4; 904 } 905} 906 907int 908ata_pmode(struct ata_params *ap) 909{ 910 if (ap->atavalid & ATA_FLAG_64_70) { 911 if (ap->apiomodes & 2) 912 return 4; 913 if (ap->apiomodes & 1) 914 return 3; 915 } 916 if (ap->opiomode == 2) 917 return 2; 918 if (ap->opiomode == 1) 919 return 1; 920 if (ap->opiomode == 0) 921 return 0; 922 return -1; 923} 924 925int 926ata_wmode(struct ata_params *ap) 927{ 928 if (ap->wdmamodes & 4) 929 return 2; 930 if (ap->wdmamodes & 2) 931 return 1; 932 if (ap->wdmamodes & 1) 933 return 0; 934 return -1; 935} 936 937int 938ata_umode(struct ata_params *ap) 939{ 940 if (ap->atavalid & ATA_FLAG_88) { 941 if (ap->udmamodes & 0x20) 942 return 5; 943 if (ap->udmamodes & 0x10) 944 return 4; 945 if (ap->udmamodes & 0x08) 946 return 3; 947 if (ap->udmamodes & 0x04) 948 return 2; 949 if (ap->udmamodes & 0x02) 950 return 1; 951 if (ap->udmamodes & 0x01) 952 return 0; 953 } 954 return -1; 955} 956 957static char * 958active2str(int active) 959{ 960 static char buf[8]; 961 962 switch (active) { 963 case ATA_IDLE: 964 return("ATA_IDLE"); 965 case ATA_IMMEDIATE: 966 return("ATA_IMMEDIATE"); 967 case ATA_WAIT_INTR: 968 return("ATA_WAIT_INTR"); 969 case ATA_WAIT_READY: 970 return("ATA_WAIT_READY"); 971 case ATA_ACTIVE: 972 return("ATA_ACTIVE"); 973 case ATA_ACTIVE_ATA: 974 return("ATA_ACTIVE_ATA"); 975 case ATA_ACTIVE_ATAPI: 976 return("ATA_ACTIVE_ATAPI"); 977 case ATA_REINITING: 978 return("ATA_REINITING"); 979 default: 980 sprintf(buf, "0x%02x", active); 981 return buf; 982 } 983} 984 985static void 986bswap(int8_t *buf, int len) 987{ 988 u_int16_t *ptr = (u_int16_t*)(buf + len); 989 990 while (--ptr >= (u_int16_t*)buf) 991 *ptr = ntohs(*ptr); 992} 993 994static void 995btrim(int8_t *buf, int len) 996{ 997 int8_t *ptr; 998 999 for (ptr = buf; ptr < buf+len; ++ptr) 1000 if (!*ptr) 1001 *ptr = ' '; 1002 for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr) 1003 *ptr = 0; 1004} 1005 1006static void 1007bpack(int8_t *src, int8_t *dst, int len) 1008{ 1009 int i, j, blank; 1010 1011 for (i = j = blank = 0 ; i < len; i++) { 1012 if (blank && src[i] == ' ') continue; 1013 if (blank && src[i] != ' ') { 1014 dst[j++] = src[i]; 1015 blank = 0; 1016 continue; 1017 } 1018 if (src[i] == ' ') { 1019 blank = 1; 1020 if (i == 0) 1021 continue; 1022 } 1023 dst[j++] = src[i]; 1024 } 1025 if (j < len) 1026 dst[j] = 0x00; 1027} 1028 1029static void 1030ata_change_mode(struct ata_softc *scp, int device, int mode) 1031{ 1032 int s = splbio(); 1033 1034 while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) 1035 tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); 1036 1037 ata_dmainit(scp, device, ata_pmode(ATA_PARAM(scp, device)), 1038 mode < ATA_DMA ? -1 : ata_wmode(ATA_PARAM(scp, device)), 1039 mode < ATA_DMA ? -1 : ata_umode(ATA_PARAM(scp, device))); 1040 scp->active = ATA_IDLE; 1041 ata_start(scp); 1042 splx(s); 1043} 1044 1045static int 1046sysctl_hw_ata(SYSCTL_HANDLER_ARGS) 1047{ 1048 struct ata_softc *scp; 1049 int ctlr, error, i; 1050 1051 /* readout internal state */ 1052 bzero(ata_conf, sizeof(ata_conf)); 1053 for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) { 1054 if (!(scp = devclass_get_softc(ata_devclass, ctlr))) 1055 continue; 1056 for (i = 0; i < 2; i++) { 1057 if (!scp->dev_softc[i]) 1058 strcat(ata_conf, "---,"); 1059 else if (scp->mode[i] >= ATA_DMA) 1060 strcat(ata_conf, "dma,"); 1061 else 1062 strcat(ata_conf, "pio,"); 1063 } 1064 } 1065 error = sysctl_handle_string(oidp, ata_conf, sizeof(ata_conf), req); 1066 if (error == 0 && req->newptr != NULL) { 1067 char *ptr = ata_conf; 1068 1069 /* update internal state */ 1070 i = 0; 1071 while (*ptr) { 1072 if (!strncmp(ptr, "pio", 3) || !strncmp(ptr, "PIO", 3)) { 1073 if ((scp = devclass_get_softc(ata_devclass, i >> 1)) && 1074 scp->dev_softc[i & 1] && scp->mode[i & 1] >= ATA_DMA) 1075 ata_change_mode(scp, (i & 1)?ATA_SLAVE:ATA_MASTER, ATA_PIO); 1076 } 1077 else if (!strncmp(ptr, "dma", 3) || !strncmp(ptr, "DMA", 3)) { 1078 if ((scp = devclass_get_softc(ata_devclass, i >> 1)) && 1079 scp->dev_softc[i & 1] && scp->mode[i & 1] < ATA_DMA) 1080 ata_change_mode(scp, (i & 1)?ATA_SLAVE:ATA_MASTER, ATA_DMA); 1081 } 1082 else if (strncmp(ptr, "---", 3)) 1083 break; 1084 ptr+=3; 1085 if (*ptr++ != ',' || 1086 ++i > (devclass_get_maxunit(ata_devclass) << 1)) 1087 break; 1088 } 1089 } 1090 return error; 1091} 1092SYSCTL_PROC(_hw, OID_AUTO, atamodes, CTLTYPE_STRING | CTLFLAG_RW, 1093 0, sizeof(ata_conf), sysctl_hw_ata, "A", ""); 1094 1095static void 1096ata_init(void) 1097{ 1098 /* register boot attach to be run when interrupts are enabled */ 1099 if (!(ata_delayed_attach = (struct intr_config_hook *) 1100 malloc(sizeof(struct intr_config_hook), 1101 M_TEMP, M_NOWAIT | M_ZERO))) { 1102 printf("ata: malloc of delayed attach hook failed\n"); 1103 return; 1104 } 1105 1106 ata_delayed_attach->ich_func = (void*)ata_boot_attach; 1107 if (config_intrhook_establish(ata_delayed_attach) != 0) { 1108 printf("ata: config_intrhook_establish failed\n"); 1109 free(ata_delayed_attach, M_TEMP); 1110 } 1111} 1112SYSINIT(atadev, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL) 1113