ata-all.c revision 144790
1135669Scognet/*- 2135669Scognet * Copyright (c) 1998 - 2005 S�ren Schmidt <sos@FreeBSD.org> 3139735Simp * All rights reserved. 4135669Scognet * 5135669Scognet * Redistribution and use in source and binary forms, with or without 6135669Scognet * modification, are permitted provided that the following conditions 7135669Scognet * are met: 8135669Scognet * 1. Redistributions of source code must retain the above copyright 9135669Scognet * notice, this list of conditions and the following disclaimer, 10135669Scognet * without modification, immediately at the beginning of the file. 11135669Scognet * 2. Redistributions in binary form must reproduce the above copyright 12135669Scognet * notice, this list of conditions and the following disclaimer in the 13135669Scognet * documentation and/or other materials provided with the distribution. 14135669Scognet * 3. The name of the author may not be used to endorse or promote products 15135669Scognet * derived from this software without specific prior written permission. 16135669Scognet * 17135669Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18135669Scognet * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19135669Scognet * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20135669Scognet * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21135669Scognet * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22135669Scognet * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23135669Scognet * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24135669Scognet * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25135669Scognet * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26135669Scognet * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27135669Scognet */ 28135669Scognet 29135669Scognet#include <sys/cdefs.h> 30135669Scognet__FBSDID("$FreeBSD: head/sys/dev/ata/ata-all.c 144790 2005-04-08 09:37:47Z sos $"); 31135669Scognet 32135669Scognet#include "opt_ata.h" 33135669Scognet#include <sys/param.h> 34135669Scognet#include <sys/systm.h> 35135669Scognet#include <sys/ata.h> 36135669Scognet#include <sys/kernel.h> 37135669Scognet#include <sys/module.h> 38135669Scognet#include <sys/endian.h> 39135669Scognet#include <sys/ctype.h> 40135669Scognet#include <sys/conf.h> 41135669Scognet#include <sys/bus.h> 42135669Scognet#include <sys/bio.h> 43135669Scognet#include <sys/malloc.h> 44135669Scognet#include <sys/sysctl.h> 45135669Scognet#include <sys/sema.h> 46135669Scognet#include <sys/taskqueue.h> 47135669Scognet#include <vm/uma.h> 48135669Scognet#include <machine/stdarg.h> 49135669Scognet#include <machine/resource.h> 50135669Scognet#include <machine/bus.h> 51135669Scognet#include <sys/rman.h> 52135669Scognet#ifdef __alpha__ 53135669Scognet#include <machine/md_var.h> 54135669Scognet#endif 55135669Scognet#include <dev/ata/ata-all.h> 56135669Scognet#include <dev/ata/ata-commands.h> 57135669Scognet#include <ata_if.h> 58135669Scognet 59135669Scognet/* device structure */ 60135669Scognetstatic d_ioctl_t ata_ioctl; 61135669Scognetstatic struct cdevsw ata_cdevsw = { 62135669Scognet .d_version = D_VERSION, 63135669Scognet .d_flags = D_NEEDGIANT, /* we need this as newbus isn't safe */ 64135669Scognet .d_ioctl = ata_ioctl, 65135669Scognet .d_name = "ata", 66135669Scognet}; 67135669Scognet 68135669Scognet/* prototypes */ 69135669Scognetstatic void ata_interrupt(void *); 70135669Scognetstatic void ata_boot_attach(void); 71135669Scognetdevice_t ata_add_child(driver_t *driver, device_t parent, struct ata_device *atadev, const char *name, int unit); 72135669Scognet 73135669Scognet/* global vars */ 74135669ScognetMALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer"); 75135669Scognetint (*ata_ioctl_func)(struct ata_cmd *iocmd) = NULL; 76135669Scognetdevclass_t ata_devclass; 77135669Scognetuma_zone_t ata_zone; 78135669Scognetint ata_wc = 1; 79135669Scognet 80135669Scognet/* local vars */ 81135669Scognetstatic struct intr_config_hook *ata_delayed_attach = NULL; 82135669Scognetstatic int ata_dma = 1; 83135669Scognetstatic int atapi_dma = 1; 84135669Scognet 85135669Scognet/* sysctl vars */ 86135669ScognetSYSCTL_NODE(_hw, OID_AUTO, ata, CTLFLAG_RD, 0, "ATA driver parameters"); 87135669ScognetTUNABLE_INT("hw.ata.ata_dma", &ata_dma); 88135669ScognetSYSCTL_INT(_hw_ata, OID_AUTO, ata_dma, CTLFLAG_RDTUN, &ata_dma, 0, 89135669Scognet "ATA disk DMA mode control"); 90135669ScognetTUNABLE_INT("hw.ata.atapi_dma", &atapi_dma); 91135669ScognetSYSCTL_INT(_hw_ata, OID_AUTO, atapi_dma, CTLFLAG_RDTUN, &atapi_dma, 0, 92135669Scognet "ATAPI device DMA mode control"); 93135669ScognetTUNABLE_INT("hw.ata.wc", &ata_wc); 94161592ScognetSYSCTL_INT(_hw_ata, OID_AUTO, wc, CTLFLAG_RDTUN, &ata_wc, 0, 95135669Scognet "ATA disk write caching"); 96135669Scognet 97161592Scognet/* 98135669Scognet * newbus device interface related functions 99135669Scognet */ 100135669Scognetint 101135669Scognetata_probe(device_t dev) 102161592Scognet{ 103135669Scognet return 0; 104135669Scognet} 105161592Scognet 106135669Scognetint 107135669Scognetata_attach(device_t dev) 108135669Scognet{ 109135669Scognet struct ata_channel *ch = device_get_softc(dev); 110135669Scognet int error, rid; 111135669Scognet 112135669Scognet /* check that we have a virgin channel to attach */ 113135669Scognet if (ch->r_irq) 114135669Scognet return EEXIST; 115135669Scognet 116135669Scognet /* initialize the softc basics */ 117135669Scognet ch->dev = dev; 118135669Scognet ch->state = ATA_IDLE; 119135669Scognet bzero(&ch->state_mtx, sizeof(struct mtx)); 120135669Scognet mtx_init(&ch->state_mtx, "ATA state lock", NULL, MTX_DEF); 121135669Scognet bzero(&ch->queue_mtx, sizeof(struct mtx)); 122135669Scognet mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF); 123135669Scognet TAILQ_INIT(&ch->ata_queue); 124135669Scognet 125135669Scognet /* reset the controller HW, the channel and device(s) */ 126135669Scognet while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit) 127135669Scognet tsleep(&error, PRIBIO, "ataatch", 1); 128135669Scognet ch->hw.reset(ch); 129135669Scognet ATA_LOCKING(dev, ATA_LF_UNLOCK); 130135669Scognet 131135669Scognet /* setup interrupt delivery */ 132135669Scognet rid = ATA_IRQ_RID; 133135669Scognet ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 134135669Scognet RF_SHAREABLE | RF_ACTIVE); 135135669Scognet if (!ch->r_irq) { 136135669Scognet device_printf(dev, "unable to allocate interrupt\n"); 137135669Scognet return ENXIO; 138135669Scognet } 139135669Scognet if ((error = bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, 140135669Scognet ata_interrupt, ch, &ch->ih))) { 141135669Scognet device_printf(dev, "unable to setup interrupt\n"); 142135669Scognet return error; 143135669Scognet } 144135669Scognet 145135669Scognet /* do not attach devices if we are in early boot */ 146135669Scognet if (ata_delayed_attach) 147135669Scognet return 0; 148135669Scognet 149135669Scognet /* probe and attach devices on this channel */ 150135669Scognet bus_generic_probe(dev); 151135669Scognet bus_generic_attach(dev); 152135669Scognet return 0; 153135669Scognet} 154135669Scognet 155135669Scognetint 156135669Scognetata_detach(device_t dev) 157135669Scognet{ 158135669Scognet struct ata_channel *ch = device_get_softc(dev); 159135669Scognet device_t *children; 160135669Scognet int nchildren, i; 161135669Scognet 162135669Scognet /* check that we have a vaild channel to detach */ 163135669Scognet if (!ch->r_irq) 164135669Scognet return ENXIO; 165135669Scognet 166135669Scognet /* detach & delete all children */ 167135669Scognet if (!device_get_children(dev, &children, &nchildren)) { 168135669Scognet for (i = 0; i < nchildren; i++) 169135669Scognet if (children[i]) 170135669Scognet device_delete_child(dev, children[i]); 171135669Scognet free(children, M_TEMP); 172135669Scognet } 173135669Scognet 174135669Scognet /* fail outstanding requests on this channel (SOS shouldn't be any XXX ) */ 175135669Scognet ata_fail_requests(ch, NULL); 176135669Scognet 177135669Scognet /* release resources */ 178135669Scognet bus_teardown_intr(dev, ch->r_irq, ch->ih); 179135669Scognet bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); 180135669Scognet ch->r_irq = NULL; 181135669Scognet mtx_destroy(&ch->state_mtx); 182135669Scognet mtx_destroy(&ch->queue_mtx); 183135669Scognet return 0; 184135669Scognet} 185135669Scognet 186135669Scognetint 187135669Scognetata_reinit(device_t dev) 188135669Scognet{ 189135669Scognet struct ata_channel *ch = device_get_softc(dev); 190135669Scognet device_t *children; 191135669Scognet int nchildren, i; 192135669Scognet 193135669Scognet if (!ch || !ch->r_irq) 194135669Scognet return ENXIO; 195135669Scognet 196135669Scognet if (bootverbose) 197135669Scognet device_printf(dev, "reiniting channel ..\n"); 198135669Scognet 199135669Scognet /* poll for locking the channel */ 200135669Scognet while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit) 201135669Scognet tsleep(&dev, PRIBIO, "atarini", 1); 202135669Scognet 203135669Scognet /* grap the channel lock */ 204135669Scognet mtx_lock(&ch->state_mtx); 205135669Scognet ch->state = ATA_STALL_QUEUE; 206135669Scognet mtx_unlock(&ch->state_mtx); 207135669Scognet 208135669Scognet /* reset the controller HW, the channel and device(s) */ 209135669Scognet ch->hw.reset(ch); 210135669Scognet 211135669Scognet /* reinit the children and delete any that fails */ 212135669Scognet if (!device_get_children(dev, &children, &nchildren)) { 213135669Scognet mtx_lock(&Giant); /* newbus suckage it needs Giant */ 214135669Scognet for (i = 0; i < nchildren; i++) { 215135669Scognet if (children[i] && device_is_attached(children[i])) 216135669Scognet if (ATA_REINIT(children[i])) { 217135669Scognet if (ch->running->dev == children[i]) { 218135669Scognet device_printf(ch->running->dev, 219135669Scognet "FAILURE - device detached\n"); 220135669Scognet ch->running->dev = NULL; 221135669Scognet ch->running = NULL; 222135669Scognet } 223135669Scognet device_delete_child(dev, children[i]); 224135669Scognet } 225135669Scognet } 226135669Scognet free(children, M_TEMP); 227135669Scognet mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ 228135669Scognet } 229135669Scognet 230135669Scognet /* catch running request if any */ 231135669Scognet ata_catch_inflight(ch); 232135669Scognet 233135669Scognet /* we're done release the channel for new work */ 234135669Scognet mtx_lock(&ch->state_mtx); 235135669Scognet ch->state = ATA_IDLE; 236135669Scognet mtx_unlock(&ch->state_mtx); 237135669Scognet ATA_LOCKING(dev, ATA_LF_UNLOCK); 238135669Scognet 239135669Scognet if (bootverbose) 240135669Scognet device_printf(dev, "reinit done ..\n"); 241135669Scognet 242135669Scognet /* kick off requests on the queue */ 243135669Scognet ata_start(dev); 244135669Scognet return 0; 245135669Scognet} 246135669Scognet 247135669Scognetint 248135669Scognetata_suspend(device_t dev) 249135669Scognet{ 250135669Scognet struct ata_channel *ch; 251135669Scognet 252135669Scognet if (!dev || !(ch = device_get_softc(dev))) 253135669Scognet return ENXIO; 254135669Scognet 255135669Scognet /* wait for the channel to be IDLE before when enter suspend mode */ 256135669Scognet while (1) { 257135669Scognet mtx_lock(&ch->state_mtx); 258135669Scognet if (ch->state == ATA_IDLE) { 259135669Scognet ch->state = ATA_ACTIVE; 260135669Scognet mtx_unlock(&ch->state_mtx); 261135669Scognet break; 262135669Scognet } 263135669Scognet mtx_unlock(&ch->state_mtx); 264135669Scognet tsleep(ch, PRIBIO, "atasusp", hz/10); 265135669Scognet } 266135669Scognet ATA_LOCKING(dev, ATA_LF_UNLOCK); 267135669Scognet return 0; 268135669Scognet} 269135669Scognet 270135669Scognetint 271135669Scognetata_resume(device_t dev) 272135669Scognet{ 273135669Scognet struct ata_channel *ch; 274135669Scognet int error; 275135669Scognet 276135669Scognet if (!dev || !(ch = device_get_softc(dev))) 277135669Scognet return ENXIO; 278135669Scognet 279135669Scognet /* reinit the devices, we dont know what mode/state they have */ 280135669Scognet error = ata_reinit(dev); 281135669Scognet 282135669Scognet /* kick off requests on the queue */ 283135669Scognet ata_start(dev); 284135669Scognet return error; 285135669Scognet} 286135669Scognet 287135669Scognetstatic void 288135669Scognetata_interrupt(void *data) 289135669Scognet{ 290135669Scognet struct ata_channel *ch = (struct ata_channel *)data; 291135669Scognet struct ata_request *request; 292135669Scognet 293135669Scognet mtx_lock(&ch->state_mtx); 294135669Scognet do { 295135669Scognet /* do we have a running request */ 296135669Scognet if (ch->state & ATA_TIMEOUT || !(request = ch->running)) 297135669Scognet break; 298135669Scognet 299135669Scognet ATA_DEBUG_RQ(request, "interrupt"); 300135669Scognet 301135669Scognet /* ignore interrupt if device is busy */ 302135669Scognet if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) { 303135669Scognet DELAY(100); 304135669Scognet if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) 305135669Scognet break; 306135669Scognet } 307135669Scognet 308135669Scognet /* check for the right state */ 309135669Scognet if (ch->state == ATA_ACTIVE || ch->state == ATA_STALL_QUEUE) { 310135669Scognet request->flags |= ATA_R_INTR_SEEN; 311135669Scognet } 312135669Scognet else { 313135669Scognet device_printf(request->dev, 314135669Scognet "interrupt state=%d unexpected\n", ch->state); 315135669Scognet break; 316135669Scognet } 317135669Scognet 318135669Scognet /* 319135669Scognet * we have the HW locks, so start the tranaction for this request 320135669Scognet * if it finishes immediately we dont need to wait for interrupt 321135669Scognet */ 322135669Scognet if (ch->hw.end_transaction(request) == ATA_OP_FINISHED) { 323135669Scognet ch->running = NULL; 324135669Scognet if (ch->state == ATA_ACTIVE) 325135669Scognet ch->state = ATA_IDLE; 326135669Scognet mtx_unlock(&ch->state_mtx); 327135669Scognet ATA_LOCKING(ch->dev, ATA_LF_UNLOCK); 328135669Scognet ata_finish(request); 329135669Scognet return; 330135669Scognet } 331135669Scognet else { 332135669Scognet request->flags &= ~ATA_R_INTR_SEEN; 333135669Scognet } 334135669Scognet } while (0); 335135669Scognet mtx_unlock(&ch->state_mtx); 336135669Scognet} 337135669Scognet 338135669Scognet/* 339135669Scognet * device related interfaces 340135669Scognet */ 341135669Scognetstatic int 342161592Scognetata_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, 343161592Scognet int32_t flag, struct thread *td) 344161592Scognet{ 345161592Scognet struct ata_cmd *iocmd = (struct ata_cmd *)addr; 346161592Scognet device_t *children, device = NULL; 347135669Scognet struct ata_request *request; 348161592Scognet caddr_t buf; 349161592Scognet int nchildren, i; 350135669Scognet int error = ENOTTY; 351161592Scognet 352161592Scognet if (cmd != IOCATA) 353161592Scognet return ENOTSUP; 354161592Scognet if (iocmd->cmd == ATAGMAXCHANNEL) { 355161592Scognet iocmd->u.maxchan = devclass_get_maxunit(ata_devclass); 356135669Scognet return 0; 357161592Scognet } 358161592Scognet if (iocmd->channel < 0 || 359135669Scognet iocmd->channel >= devclass_get_maxunit(ata_devclass)) { 360135669Scognet return ENXIO; 361135669Scognet } 362135669Scognet if (!(device = devclass_get_device(ata_devclass, iocmd->channel))) 363135669Scognet return ENXIO; 364135669Scognet 365135669Scognet switch (iocmd->cmd) { 366135669Scognet case ATAGPARM: 367135669Scognet if (!device_get_children(device, &children, &nchildren)) { 368135669Scognet struct ata_channel *ch; 369135669Scognet 370135669Scognet if (!(ch = device_get_softc(device))) 371135669Scognet return ENXIO; 372135669Scognet iocmd->u.param.type[0] = 373135669Scognet ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER); 374161592Scognet iocmd->u.param.type[1] = 375161592Scognet ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE); 376161592Scognet for (i = 0; i < nchildren; i++) { 377161592Scognet if (children[i] && device_is_attached(children[i])) { 378161592Scognet struct ata_device *atadev = device_get_softc(children[i]); 379161592Scognet 380135669Scognet if (atadev->unit == ATA_MASTER) { 381135669Scognet strcpy(iocmd->u.param.name[0], 382161592Scognet device_get_nameunit(children[i])); 383161592Scognet bcopy(&atadev->param, &iocmd->u.param.params[0], 384135669Scognet sizeof(struct ata_params)); 385135669Scognet } 386135669Scognet if (atadev->unit == ATA_SLAVE) { 387135669Scognet strcpy(iocmd->u.param.name[1], 388135669Scognet device_get_nameunit(children[i])); 389135669Scognet bcopy(&atadev->param, &iocmd->u.param.params[1], 390135669Scognet sizeof(struct ata_params)); 391161592Scognet } 392161592Scognet } 393161592Scognet } 394161592Scognet free(children, M_TEMP); 395161592Scognet error = 0; 396161592Scognet } 397161592Scognet else 398161592Scognet error = ENXIO; 399161592Scognet break; 400161592Scognet 401161592Scognet case ATAGMODE: 402161592Scognet if (!device_get_children(device, &children, &nchildren)) { 403161592Scognet for (i = 0; i < nchildren; i++) { 404135669Scognet if (children[i] && device_is_attached(children[i])) { 405135669Scognet struct ata_device *atadev = device_get_softc(children[i]); 406135669Scognet 407135669Scognet atadev = device_get_softc(children[i]); 408135669Scognet if (atadev->unit == ATA_MASTER) 409161592Scognet iocmd->u.mode.mode[0] = atadev->mode; 410135669Scognet if (atadev->unit == ATA_SLAVE) 411135669Scognet iocmd->u.mode.mode[1] = atadev->mode; 412135669Scognet } 413135669Scognet free(children, M_TEMP); 414161592Scognet } 415135669Scognet error = 0; 416135669Scognet } 417135669Scognet else 418135669Scognet error = ENXIO; 419135669Scognet break; 420135669Scognet 421135669Scognet case ATASMODE: 422135669Scognet if (!device_get_children(device, &children, &nchildren)) { 423135669Scognet for (i = 0; i < nchildren; i++) { 424135669Scognet if (children[i] && device_is_attached(children[i])) { 425135669Scognet struct ata_device *atadev = device_get_softc(children[i]); 426135669Scognet 427135669Scognet if (atadev->unit == ATA_MASTER) { 428135669Scognet atadev->mode = iocmd->u.mode.mode[0]; 429135669Scognet ATA_SETMODE(device, children[i]); 430135669Scognet iocmd->u.mode.mode[0] = atadev->mode; 431135669Scognet } 432135669Scognet if (atadev->unit == ATA_SLAVE) { 433135669Scognet atadev->mode = iocmd->u.mode.mode[1]; 434135669Scognet ATA_SETMODE(device, children[i]); 435135669Scognet iocmd->u.mode.mode[1] = atadev->mode; 436135669Scognet } 437135669Scognet } 438135669Scognet } 439135669Scognet free(children, M_TEMP); 440135669Scognet error = 0; 441135669Scognet } 442135669Scognet else 443135669Scognet error = ENXIO; 444135669Scognet break; 445135669Scognet 446135669Scognet case ATAREQUEST: 447135669Scognet if (!device_get_children(device, &children, &nchildren)) { 448135669Scognet for (i = 0; i < nchildren; i++) { 449135669Scognet if (children[i] && device_is_attached(children[i])) { 450135669Scognet struct ata_device *atadev = device_get_softc(children[i]); 451135669Scognet 452135669Scognet if (ATA_DEV(atadev->unit) == iocmd->device) { 453135669Scognet if (!(buf = malloc(iocmd->u.request.count, 454135669Scognet M_ATA, M_NOWAIT))) { 455135669Scognet error = ENOMEM; 456135669Scognet break; 457135669Scognet } 458135669Scognet if (!(request = ata_alloc_request())) { 459135669Scognet error = ENOMEM; 460135669Scognet free(buf, M_ATA); 461135669Scognet break; 462135669Scognet } 463135669Scognet if (iocmd->u.request.flags & ATA_CMD_WRITE) { 464135669Scognet error = copyin(iocmd->u.request.data, buf, 465161592Scognet iocmd->u.request.count); 466161592Scognet if (error) { 467135669Scognet free(buf, M_ATA); 468135669Scognet ata_free_request(request); 469135669Scognet break; 470135669Scognet } 471135669Scognet } 472135669Scognet request->dev = atadev->dev; 473135669Scognet if (iocmd->u.request.flags & ATA_CMD_ATAPI) { 474135669Scognet request->flags = ATA_R_ATAPI; 475135669Scognet bcopy(iocmd->u.request.u.atapi.ccb, 476135669Scognet request->u.atapi.ccb, 16); 477135669Scognet } 478135669Scognet else { 479135669Scognet request->u.ata.command = 480135669Scognet iocmd->u.request.u.ata.command; 481135669Scognet request->u.ata.feature = 482135669Scognet iocmd->u.request.u.ata.feature; 483135669Scognet request->u.ata.lba = iocmd->u.request.u.ata.lba; 484135669Scognet request->u.ata.count = iocmd->u.request.u.ata.count; 485135669Scognet } 486135669Scognet request->timeout = iocmd->u.request.timeout; 487135669Scognet request->data = buf; 488135669Scognet request->bytecount = iocmd->u.request.count; 489135669Scognet request->transfersize = request->bytecount; 490135669Scognet if (iocmd->u.request.flags & ATA_CMD_CONTROL) 491135669Scognet request->flags |= ATA_R_CONTROL; 492135669Scognet if (iocmd->u.request.flags & ATA_CMD_READ) 493135669Scognet request->flags |= ATA_R_READ; 494135669Scognet if (iocmd->u.request.flags & ATA_CMD_WRITE) 495135669Scognet request->flags |= ATA_R_WRITE; 496135669Scognet ata_queue_request(request); 497135669Scognet if (!(request->flags & ATA_R_ATAPI)) { 498135669Scognet iocmd->u.request.u.ata.command = 499135669Scognet request->u.ata.command; 500135669Scognet iocmd->u.request.u.ata.feature = 501135669Scognet request->u.ata.feature; 502135669Scognet iocmd->u.request.u.ata.lba = request->u.ata.lba; 503135669Scognet iocmd->u.request.u.ata.count = request->u.ata.count; 504135669Scognet } 505135669Scognet iocmd->u.request.error = request->result; 506135669Scognet if (iocmd->u.request.flags & ATA_CMD_READ) 507135669Scognet error = copyout(buf, iocmd->u.request.data, 508135669Scognet iocmd->u.request.count); 509135669Scognet else 510135669Scognet error = 0; 511135669Scognet free(buf, M_ATA); 512135669Scognet ata_free_request(request); 513135669Scognet break; 514135669Scognet } 515135669Scognet } 516135669Scognet } 517135669Scognet free(children, M_TEMP); 518135669Scognet } 519135669Scognet else 520135669Scognet error = ENXIO; 521135669Scognet break; 522135669Scognet 523135669Scognet case ATAREINIT: 524135669Scognet error = ata_reinit(device); 525135669Scognet ata_start(device); 526135669Scognet break; 527135669Scognet 528135669Scognet case ATAATTACH: 529135669Scognet /* SOS should enable channel HW on controller XXX */ 530135669Scognet error = ata_attach(device); 531135669Scognet break; 532135669Scognet 533135669Scognet case ATADETACH: 534135669Scognet error = ata_detach(device); 535135669Scognet /* SOS should disable channel HW on controller XXX */ 536135669Scognet break; 537135669Scognet 538135669Scognet default: 539135669Scognet if (ata_ioctl_func) 540135669Scognet error = ata_ioctl_func(iocmd); 541135669Scognet } 542135669Scognet return error; 543135669Scognet} 544135669Scognet 545135669Scognetstatic void 546135669Scognetata_boot_attach(void) 547135669Scognet{ 548 struct ata_channel *ch; 549 int ctlr; 550 551 /* release the hook that got us here, only needed during boot */ 552 if (ata_delayed_attach) { 553 config_intrhook_disestablish(ata_delayed_attach); 554 free(ata_delayed_attach, M_TEMP); 555 ata_delayed_attach = NULL; 556 } 557 558 /* kick of probe and attach on all channels */ 559 for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) { 560 if ((ch = devclass_get_softc(ata_devclass, ctlr))) { 561 bus_generic_probe(ch->dev); 562 bus_generic_attach(ch->dev); 563 } 564 } 565} 566 567/* 568 * misc support functions 569 */ 570device_t 571ata_add_child(driver_t *driver, device_t parent, struct ata_device *atadev, 572 const char *name, int unit) 573{ 574 struct ata_channel *ch = device_get_softc(parent); 575 device_t child; 576 577 if ((child = device_add_child(parent, name, unit))) { 578 char buffer[64]; 579 580 device_set_driver(child, driver); 581 device_set_softc(child, atadev); 582 sprintf(buffer, "%.40s/%.8s", 583 atadev->param.model, atadev->param.revision); 584 device_set_desc_copy(child, buffer); 585 device_quiet(child); 586 atadev->dev = child; 587 atadev->max_iosize = DEV_BSIZE; 588 atadev->mode = ATA_PIO_MAX; 589 if ((atadev->param.config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) { 590 if (atapi_dma && ch->dma && 591 (atadev->param.config & ATA_DRQ_MASK) != ATA_DRQ_INTR && 592 ata_umode(&atadev->param) >= ATA_UDMA2) 593 atadev->mode = ATA_DMA_MAX; 594 } 595 else { 596 if (ata_dma && ch->dma) 597 atadev->mode = ATA_DMA_MAX; 598 } 599 } 600 return child; 601} 602 603void 604ata_identify(driver_t *driver, device_t parent, int type, const char *name) 605{ 606 struct ata_channel *ch = device_get_softc(parent); 607 struct ata_device *master, *slave; 608 int master_res = EIO, slave_res = EIO, master_unit = -1, slave_unit = -1; 609 610 if (!(master = malloc(sizeof(struct ata_device), 611 M_ATA, M_NOWAIT | M_ZERO))) { 612 device_printf(parent, "out of memory\n"); 613 return; 614 } 615 master->unit = ATA_MASTER; 616 if (!(slave = malloc(sizeof(struct ata_device), 617 M_ATA, M_NOWAIT | M_ZERO))) { 618 free(master, M_ATA); 619 device_printf(parent, "out of memory\n"); 620 return; 621 } 622 slave->unit = ATA_SLAVE; 623 624 /* wait for the channel to be IDLE then grab it before touching HW */ 625 while (ATA_LOCKING(parent, ATA_LF_LOCK) != ch->unit) 626 tsleep(ch, PRIBIO, "ataidnt2", 1); 627 while (1) { 628 mtx_lock(&ch->state_mtx); 629 if (ch->state == ATA_IDLE) { 630 ch->state = ATA_ACTIVE; 631 mtx_unlock(&ch->state_mtx); 632 break; 633 } 634 mtx_unlock(&ch->state_mtx); 635 tsleep(ch, PRIBIO, "ataidnt1", 1); 636 } 637 638 if (type < 0) { 639 if (ch->devices & ATA_ATA_SLAVE) 640 slave_res = ata_getparam(parent, slave, ATA_ATA_IDENTIFY); 641 if (ch->devices & ATA_ATA_MASTER) 642 master_res = ata_getparam(parent, master, ATA_ATA_IDENTIFY); 643#ifdef ATA_STATIC_ID 644 master_unit = (device_get_unit(parent) << 1); 645 slave_unit = (device_get_unit(parent) << 1) + 1; 646#endif 647 } 648 else { 649 if (ch->devices & ATA_ATAPI_SLAVE) 650 slave_res = ata_getparam(parent, slave, ATA_ATAPI_IDENTIFY); 651 if (ch->devices & ATA_ATAPI_MASTER) 652 master_res = ata_getparam(parent, master, ATA_ATAPI_IDENTIFY); 653 } 654 655 if (master_res || 656 !(type < 0 || (master->param.config & ATA_ATAPI_TYPE_MASK) == type) || 657 !ata_add_child(driver, parent, master, name, master_unit)) 658 free(master, M_ATA); 659 660 if (slave_res || 661 !(type < 0 || (slave->param.config & ATA_ATAPI_TYPE_MASK) == type) || 662 !ata_add_child(driver, parent, slave, name, slave_unit)) 663 free(slave, M_ATA); 664 665 mtx_lock(&ch->state_mtx); 666 ch->state = ATA_IDLE; 667 mtx_unlock(&ch->state_mtx); 668 ATA_LOCKING(parent, ATA_LF_UNLOCK); 669} 670 671void 672ata_default_registers(struct ata_channel *ch) 673{ 674 /* fill in the defaults from whats setup already */ 675 ch->r_io[ATA_ERROR].res = ch->r_io[ATA_FEATURE].res; 676 ch->r_io[ATA_ERROR].offset = ch->r_io[ATA_FEATURE].offset; 677 ch->r_io[ATA_IREASON].res = ch->r_io[ATA_COUNT].res; 678 ch->r_io[ATA_IREASON].offset = ch->r_io[ATA_COUNT].offset; 679 ch->r_io[ATA_STATUS].res = ch->r_io[ATA_COMMAND].res; 680 ch->r_io[ATA_STATUS].offset = ch->r_io[ATA_COMMAND].offset; 681 ch->r_io[ATA_ALTSTAT].res = ch->r_io[ATA_CONTROL].res; 682 ch->r_io[ATA_ALTSTAT].offset = ch->r_io[ATA_CONTROL].offset; 683} 684 685void 686ata_udelay(int interval) 687{ 688 /* for now just use DELAY, the timer/sleep subsytems are not there yet */ 689 if (1 || interval < (1000000/hz) || ata_delayed_attach) 690 DELAY(interval); 691 else 692 tsleep(&interval, PRIBIO, "ataslp", interval/(1000000/hz)); 693} 694 695char * 696ata_mode2str(int mode) 697{ 698 switch (mode) { 699 case ATA_PIO0: return "PIO0"; 700 case ATA_PIO1: return "PIO1"; 701 case ATA_PIO2: return "PIO2"; 702 case ATA_PIO3: return "PIO3"; 703 case ATA_PIO4: return "PIO4"; 704 case ATA_WDMA0: return "WDMA0"; 705 case ATA_WDMA1: return "WDMA1"; 706 case ATA_WDMA2: return "WDMA2"; 707 case ATA_UDMA0: return "UDMA16"; 708 case ATA_UDMA1: return "UDMA25"; 709 case ATA_UDMA2: return "UDMA33"; 710 case ATA_UDMA3: return "UDMA40"; 711 case ATA_UDMA4: return "UDMA66"; 712 case ATA_UDMA5: return "UDMA100"; 713 case ATA_UDMA6: return "UDMA133"; 714 case ATA_SA150: return "SATA150"; 715 default: 716 if (mode & ATA_DMA_MASK) 717 return "BIOSDMA"; 718 else 719 return "BIOSPIO"; 720 } 721} 722 723int 724ata_pmode(struct ata_params *ap) 725{ 726 if (ap->atavalid & ATA_FLAG_64_70) { 727 if (ap->apiomodes & 0x02) 728 return ATA_PIO4; 729 if (ap->apiomodes & 0x01) 730 return ATA_PIO3; 731 } 732 if (ap->mwdmamodes & 0x04) 733 return ATA_PIO4; 734 if (ap->mwdmamodes & 0x02) 735 return ATA_PIO3; 736 if (ap->mwdmamodes & 0x01) 737 return ATA_PIO2; 738 if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200) 739 return ATA_PIO2; 740 if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100) 741 return ATA_PIO1; 742 if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000) 743 return ATA_PIO0; 744 return ATA_PIO0; 745} 746 747int 748ata_wmode(struct ata_params *ap) 749{ 750 if (ap->mwdmamodes & 0x04) 751 return ATA_WDMA2; 752 if (ap->mwdmamodes & 0x02) 753 return ATA_WDMA1; 754 if (ap->mwdmamodes & 0x01) 755 return ATA_WDMA0; 756 return -1; 757} 758 759int 760ata_umode(struct ata_params *ap) 761{ 762 if (ap->atavalid & ATA_FLAG_88) { 763 if (ap->udmamodes & 0x40) 764 return ATA_UDMA6; 765 if (ap->udmamodes & 0x20) 766 return ATA_UDMA5; 767 if (ap->udmamodes & 0x10) 768 return ATA_UDMA4; 769 if (ap->udmamodes & 0x08) 770 return ATA_UDMA3; 771 if (ap->udmamodes & 0x04) 772 return ATA_UDMA2; 773 if (ap->udmamodes & 0x02) 774 return ATA_UDMA1; 775 if (ap->udmamodes & 0x01) 776 return ATA_UDMA0; 777 } 778 return -1; 779} 780 781int 782ata_limit_mode(struct ata_device *atadev, int mode, int maxmode) 783{ 784 if (maxmode && mode > maxmode) 785 mode = maxmode; 786 787 if (mode >= ATA_UDMA0 && ata_umode(&atadev->param) > 0) 788 return min(mode, ata_umode(&atadev->param)); 789 790 if (mode >= ATA_WDMA0 && ata_wmode(&atadev->param) > 0) 791 return min(mode, ata_wmode(&atadev->param)); 792 793 if (mode > ata_pmode(&atadev->param)) 794 return min(mode, ata_pmode(&atadev->param)); 795 796 return mode; 797} 798 799/* 800 * module handeling 801 */ 802static int 803ata_module_event_handler(module_t mod, int what, void *arg) 804{ 805 static struct cdev *atacdev; 806 807 switch (what) { 808 case MOD_LOAD: 809 /* register controlling device */ 810 atacdev = make_dev(&ata_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "ata"); 811 812 if (cold) { 813 /* register boot attach to be run when interrupts are enabled */ 814 if (!(ata_delayed_attach = (struct intr_config_hook *) 815 malloc(sizeof(struct intr_config_hook), 816 M_TEMP, M_NOWAIT | M_ZERO))) { 817 printf("ata: malloc of delayed attach hook failed\n"); 818 return EIO; 819 } 820 ata_delayed_attach->ich_func = (void*)ata_boot_attach; 821 if (config_intrhook_establish(ata_delayed_attach) != 0) { 822 printf("ata: config_intrhook_establish failed\n"); 823 free(ata_delayed_attach, M_TEMP); 824 } 825 } 826 return 0; 827 828 case MOD_UNLOAD: 829 /* deregister controlling device */ 830 destroy_dev(atacdev); 831 return 0; 832 833 default: 834 return EOPNOTSUPP; 835 } 836} 837 838static moduledata_t ata_moduledata = { "ata", ata_module_event_handler, NULL }; 839DECLARE_MODULE(ata, ata_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND); 840MODULE_VERSION(ata, 1); 841 842static void 843ata_init(void) 844{ 845 /* init our UMA zone for ATA requests */ 846 ata_zone = uma_zcreate("ata_request", sizeof(struct ata_request), 847 NULL, NULL, NULL, NULL, 0, 0); 848} 849 850SYSINIT(atadev, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL) 851