1/*- 2 * Copyright (c) 1998,1999,2000,2001 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/sys/dev/ata/ata-all.c 74302 2001-03-15 15:36:25Z sos $ |
29 */ 30 31#include "pci.h" 32#include "opt_ata.h" 33#include <sys/param.h> 34#include <sys/systm.h> |
35#include <sys/ata.h> |
36#include <sys/kernel.h> |
37#include <sys/conf.h> |
38#include <sys/disk.h> 39#include <sys/module.h> 40#include <sys/bus.h> 41#include <sys/bio.h> 42#include <sys/malloc.h> 43#include <sys/devicestat.h> 44#include <sys/sysctl.h> 45#include <machine/stdarg.h> 46#include <machine/resource.h> 47#include <machine/bus.h> 48#include <sys/rman.h> 49#ifdef __alpha__ 50#include <machine/md_var.h> 51#endif 52#include <dev/ata/ata-all.h> 53#include <dev/ata/ata-disk.h> 54#include <dev/ata/atapi-all.h> 55 |
56/* device structures */ 57static d_ioctl_t ataioctl; 58static struct cdevsw ata_cdevsw = { 59 /* open */ nullopen, 60 /* close */ nullclose, 61 /* read */ noread, 62 /* write */ nowrite, 63 /* ioctl */ ataioctl, 64 /* poll */ nopoll, 65 /* mmap */ nommap, 66 /* strategy */ nostrategy, 67 /* name */ "ata", 68 /* maj */ 159, 69 /* dump */ nodump, 70 /* psize */ nopsize, 71 /* flags */ 0, 72 /* bmaj */ -1 73}; 74 |
75/* prototypes */ 76static void ata_boot_attach(void); 77static void ata_intr(void *); 78static int ata_getparam(struct ata_softc *, int, u_int8_t); 79static int ata_service(struct ata_softc *); 80static char *active2str(int); 81static void bswap(int8_t *, int); 82static void btrim(int8_t *, int); 83static void bpack(int8_t *, int8_t *, int); |
84static void ata_change_mode(struct ata_softc *, int, int); |
85 86/* global vars */ 87devclass_t ata_devclass; 88 89/* local vars */ 90static struct intr_config_hook *ata_delayed_attach = NULL; |
91static MALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer"); 92 93/* misc defines */ 94#define MASTER 0 95#define SLAVE 1 96 97int 98ata_probe(device_t dev) --- 160 unchanged lines hidden (view full) --- 259 scp->devices = 0; 260 261 bus_teardown_intr(dev, scp->r_irq, scp->ih); 262 bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, scp->r_irq); 263 if (scp->r_bmio) 264 bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio); 265 bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, scp->r_altio); 266 bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io); |
267 scp->r_io = NULL; 268 scp->r_altio = NULL; 269 scp->r_bmio = NULL; 270 scp->r_irq = NULL; |
271 scp->active = ATA_IDLE; 272 return 0; 273} 274 275int 276ata_resume(device_t dev) 277{ 278 struct ata_softc *scp = device_get_softc(dev); 279 280 ata_reinit(scp); 281 return 0; 282} 283 284static int |
285ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) 286{ 287 int error = 0; 288 289 switch (cmd) { 290 case ATAATTACH: { 291 device_t device = devclass_get_device(ata_devclass, *(int *)addr); 292 /* should enable channel HW on controller that can SOS XXX */ 293 if (!device) 294 error = ENXIO; 295 if (!error) 296 error = ata_probe(device); 297 if (!error) 298 error = ata_attach(device); 299 break; 300 } 301 302 case ATADETACH: { 303 device_t device = devclass_get_device(ata_devclass, *(int *)addr); 304 if (!device) 305 error = ENXIO; 306 if (!error) 307 error = ata_detach(device); 308 /* should disable channel HW on controller that can SOS XXX */ 309 break; 310 } 311 312 case ATAREINIT: { 313 device_t device = devclass_get_device(ata_devclass, *(int *)addr); 314 struct ata_softc *scp; 315 int s; 316 317 if (!device) 318 return ENXIO; 319 scp = device_get_softc(device); 320 if (!scp) 321 return ENXIO; 322 323 /* make sure channel is not busy SOS XXX */ 324 s = splbio(); 325 while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) 326 tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); 327 splx(s); 328 error = ata_reinit(scp); 329 break; 330 } 331 332 case ATAGMODE: { 333 struct ata_modes *mode = (struct ata_modes *)addr; 334 device_t device = devclass_get_device(ata_devclass, mode->channel); 335 struct ata_softc *scp; 336 337 if (!device) 338 return ENXIO; 339 scp = device_get_softc(device); 340 if (!scp) 341 return ENXIO; 342 mode->mode[MASTER] = scp->mode[MASTER]; 343 mode->mode[SLAVE] = scp->mode[SLAVE]; 344 break; 345 } 346 347 case ATASMODE: { 348 struct ata_modes *mode = (struct ata_modes *)addr; 349 device_t device = devclass_get_device(ata_devclass, mode->channel); 350 struct ata_softc *scp; 351 352 if (!device) 353 return ENXIO; 354 scp = device_get_softc(device); 355 if (!scp) 356 return ENXIO; 357 if (mode->mode[MASTER] >= 0) 358 ata_change_mode(scp, ATA_MASTER, mode->mode[MASTER]); 359 if (mode->mode[SLAVE] >= 0) 360 ata_change_mode(scp, ATA_SLAVE, mode->mode[SLAVE]); 361 mode->mode[MASTER] = scp->mode[MASTER]; 362 mode->mode[SLAVE] = scp->mode[SLAVE]; 363 break; 364 } 365 366 case ATAGPARM: { 367 struct ata_param *parm = (struct ata_param *)addr; 368 device_t device = devclass_get_device(ata_devclass, parm->channel); 369 struct ata_softc *scp; 370 371 if (!device) 372 return ENXIO; 373 scp = device_get_softc(device); 374 if (!scp) 375 return ENXIO; 376 377 parm->type[MASTER] = 378 scp->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER); 379 parm->type[SLAVE] = 380 scp->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE); 381 382 if (scp->dev_name[MASTER]) 383 strcpy(parm->name[MASTER], scp->dev_name[MASTER]); 384 if (scp->dev_name[SLAVE]) 385 strcpy(parm->name[SLAVE], scp->dev_name[SLAVE]); 386 387 if (scp->dev_param[MASTER]) 388 bcopy(scp->dev_param[MASTER], &parm->params[MASTER], 389 sizeof(struct ata_params)); 390 if (scp->dev_param[SLAVE]) 391 bcopy(scp->dev_param[SLAVE], &parm->params[SLAVE], 392 sizeof(struct ata_params)); 393 break; 394 } 395 396 default: 397 error = ENOTTY; 398 } 399 return error; 400} 401 402static int |
403ata_getparam(struct ata_softc *scp, int device, u_int8_t command) 404{ 405 struct ata_params *ata_parm; 406 int8_t buffer[DEV_BSIZE]; 407 int retry = 0; 408 409 /* select drive */ 410 ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device); --- 339 unchanged lines hidden (view full) --- 750 ata_printf(scp, -1, "devices=%02x\n", scp->devices); 751} 752 753int 754ata_reinit(struct ata_softc *scp) 755{ 756 int devices, misdev, newdev; 757 |
758 if (!scp->r_io || !scp->r_altio || !scp->r_irq) 759 return ENXIO; |
760 scp->active = ATA_REINITING; 761 scp->running = NULL; 762 devices = scp->devices; 763 ata_printf(scp, -1, "resetting devices .. "); 764 ata_reset(scp); 765 766 if ((misdev = devices & ~scp->devices)) { |
767 if (misdev) 768 printf("\n"); |
769#ifdef DEV_ATADISK 770 if (misdev & ATA_ATA_MASTER && scp->dev_softc[MASTER]) 771 ad_detach(scp->dev_softc[MASTER], 0); 772 if (misdev & ATA_ATA_SLAVE && scp->dev_softc[SLAVE]) 773 ad_detach(scp->dev_softc[SLAVE], 0); 774#endif 775#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) 776 if (misdev & ATA_ATAPI_MASTER && scp->dev_softc[MASTER]) --- 18 unchanged lines hidden (view full) --- 795 if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY)) 796 newdev &= ~ATA_ATA_SLAVE; 797 if (newdev & ATA_ATAPI_MASTER) 798 if (ata_getparam(scp, ATA_MASTER, ATA_C_ATAPI_IDENTIFY)) 799 newdev &= ~ATA_ATAPI_MASTER; 800 if (newdev & ATA_ATAPI_SLAVE) 801 if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) 802 newdev &= ~ATA_ATAPI_SLAVE; |
803 } 804 scp->active = ATA_IDLE; |
805 if (!misdev && newdev) 806 printf("\n"); |
807#ifdef DEV_ATADISK 808 if (newdev & ATA_ATA_MASTER && !scp->dev_softc[MASTER]) 809 ad_attach(scp, ATA_MASTER); 810 else if (scp->devices & ATA_ATA_MASTER && scp->dev_softc[MASTER]) 811 ad_reinit((struct ad_softc *)scp->dev_softc[MASTER]); 812 if (newdev & ATA_ATA_SLAVE && !scp->dev_softc[SLAVE]) 813 ad_attach(scp, ATA_SLAVE); 814 else if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[SLAVE]) --- 161 unchanged lines hidden (view full) --- 976 active2str(flags)); 977 } 978 /* enable interrupt */ 979 if (scp->flags & ATA_QUEUED) 980 ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); 981 return error; 982} 983 |
984void 985ata_set_name(struct ata_softc *scp, int device, char *name) 986{ 987 scp->dev_name[ATA_DEV(device)] = malloc(strlen(name) + 1, M_ATA, M_NOWAIT); 988 if (scp->dev_name[ATA_DEV(device)]) 989 strcpy(scp->dev_name[ATA_DEV(device)], name); 990} 991 992void 993ata_free_name(struct ata_softc *scp, int device) 994{ 995 if (scp->dev_name[ATA_DEV(device)]) 996 free(scp->dev_name[ATA_DEV(device)], M_ATA); 997} 998 |
999int 1000ata_get_lun(u_int32_t *map) 1001{ 1002 int lun = ffs(~*map) - 1; 1003 1004 *map |= (1 << lun); 1005 return lun; 1006} --- 13 unchanged lines hidden (view full) --- 1020int 1021ata_printf(struct ata_softc *scp, int device, const char * fmt, ...) 1022{ 1023 va_list ap; 1024 int ret; 1025 1026 if (device == -1) 1027 ret = printf("ata%d: ", device_get_unit(scp->dev)); |
1028 else { 1029 if (scp->dev_name[ATA_DEV(device)]) 1030 ret = printf("%s: ", scp->dev_name[ATA_DEV(device)]); 1031 else 1032 ret = printf("ata%d-%s: ", device_get_unit(scp->dev), 1033 (device == ATA_MASTER) ? "master" : "slave"); 1034 } |
1035 va_start(ap, fmt); 1036 ret += vprintf(fmt, ap); 1037 va_end(ap); 1038 return ret; 1039} 1040 1041char * 1042ata_mode2str(int mode) --- 147 unchanged lines hidden (view full) --- 1190 } 1191 if (j < len) 1192 dst[j] = 0x00; 1193} 1194 1195static void 1196ata_change_mode(struct ata_softc *scp, int device, int mode) 1197{ |
1198 int umode, wmode, pmode; |
1199 int s = splbio(); 1200 1201 while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) 1202 tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); 1203 |
1204 umode = ata_umode(ATA_PARAM(scp, device)); 1205 wmode = ata_wmode(ATA_PARAM(scp, device)); 1206 pmode = ata_pmode(ATA_PARAM(scp, device)); 1207 1208 switch (mode & ATA_DMA_MASK) { 1209 case ATA_UDMA: 1210 if ((mode & ATA_MODE_MASK) < umode) 1211 umode = mode & ATA_MODE_MASK; 1212 break; 1213 case ATA_WDMA: 1214 if ((mode & ATA_MODE_MASK) < wmode) 1215 wmode = mode & ATA_MODE_MASK; 1216 umode = -1; 1217 break; 1218 default: 1219 if (((mode & ATA_MODE_MASK) - ATA_PIO0) < pmode) 1220 pmode = (mode & ATA_MODE_MASK) - ATA_PIO0; 1221 umode = -1; 1222 wmode = -1; 1223 } 1224 ata_dmainit(scp, device, pmode, wmode, umode); 1225 |
1226 scp->active = ATA_IDLE; 1227 ata_start(scp); 1228 splx(s); 1229} 1230 |
1231static void 1232ata_init(void) 1233{ |
1234 /* register controlling device */ 1235 make_dev(&ata_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0666, "ata"); 1236 |
1237 /* register boot attach to be run when interrupts are enabled */ 1238 if (!(ata_delayed_attach = (struct intr_config_hook *) 1239 malloc(sizeof(struct intr_config_hook), 1240 M_TEMP, M_NOWAIT | M_ZERO))) { 1241 printf("ata: malloc of delayed attach hook failed\n"); 1242 return; 1243 } 1244 1245 ata_delayed_attach->ich_func = (void*)ata_boot_attach; 1246 if (config_intrhook_establish(ata_delayed_attach) != 0) { 1247 printf("ata: config_intrhook_establish failed\n"); 1248 free(ata_delayed_attach, M_TEMP); 1249 } 1250} 1251SYSINIT(atadev, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL) |