1 /* $NetBSD: dsk.c,v 1.16 2012/04/26 19:59:37 phx Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Tohru Nishimura. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * assumptions; 34 * - up to 4 IDE/SATA drives. 35 * - a single (master) drive in each IDE channel. 36 * - all drives are up and spinning. 37 */ 38 39 #include <sys/types.h> 40 41 #include <lib/libsa/stand.h> 42 #include <lib/libsa/ufs.h> 43 44 #include <sys/disklabel.h> 45 #include <sys/bootblock.h> 46 #include <sys/param.h> 47 48 #include <dev/raidframe/raidframevar.h> 49 50 #include <machine/bootinfo.h> 51 52 #include "globals.h" 53 54 /* 55 * - no vtophys() translation, vaddr_t == paddr_t. 56 */ 57 #define CSR_READ_4(r) in32rb(r) 58 #define CSR_WRITE_4(r,v) out32rb(r,v) 59 #define CSR_READ_1(r) in8(r) 60 #define CSR_WRITE_1(r,v) out8(r,v) 61 62 struct dskdv { 63 char *name; 64 int (*match)(unsigned, void *); 65 void *(*init)(unsigned, void *); 66 }; 67 68 static struct dskdv ldskdv[] = { 69 { "pciide", pciide_match, pciide_init }, 70 { "siisata", siisata_match, siisata_init }, 71 }; 72 static int ndskdv = sizeof(ldskdv)/sizeof(ldskdv[0]); 73 74 static void disk_scan(void *); 75 static int probe_drive(struct dkdev_ata *, int); 76 static void drive_ident(struct disk *, char *); 77 static char *mkident(char *, int); 78 static void set_xfermode(struct dkdev_ata *, int); 79 static void decode_dlabel(struct disk *, char *); 80 static struct disklabel *search_dmagic(char *); 81 static int lba_read(struct disk *, int64_t, int, void *); 82 static void issue48(struct dvata_chan *, int64_t, int); 83 static void issue28(struct dvata_chan *, int64_t, int); 84 static struct disk *lookup_disk(int); 85 86 static struct disk ldisk[MAX_UNITS]; 87 88 int 89 dskdv_init(void *self) 90 { 91 struct pcidev *pci = self; 92 struct dskdv *dv; 93 unsigned tag; 94 int n; 95 96 tag = pci->bdf; 97 for (n = 0; n < ndskdv; n++) { 98 dv = &ldskdv[n]; 99 if ((*dv->match)(tag, NULL) > 0) 100 goto found; 101 } 102 return 0; 103 found: 104 pci->drv = (*dv->init)(tag, NULL); 105 if (pci->drv == NULL) 106 return 0; 107 disk_scan(pci->drv); 108 return 1; 109 } 110 111 static void 112 disk_scan(void *drv) 113 { 114 struct dkdev_ata *l = drv; 115 struct disk *d; 116 static int ndrive = 0; 117 int n; 118 119 for (n = 0; n < 4 && ndrive < MAX_UNITS; n++) { 120 if (l->presense[n] == 0) 121 continue; 122 if (probe_drive(l, n) == 0) { 123 l->presense[n] = 0; 124 continue; 125 } 126 d = &ldisk[ndrive]; 127 d->dvops = l; 128 d->unittag = ndrive; 129 snprintf(d->xname, sizeof(d->xname), "wd%d", d->unittag); 130 set_xfermode(l, n); 131 drive_ident(d, l->iobuf); 132 decode_dlabel(d, l->iobuf); 133 ndrive += 1; 134 } 135 } 136 137 int 138 spinwait_unbusy(struct dkdev_ata *l, int n, int milli, const char **err) 139 { 140 struct dvata_chan *chan = &l->chan[n]; 141 int sts; 142 const char *msg; 143 144 /* 145 * For best compatibility it is recommended to wait 400ns and 146 * read the alternate status byte four times before the status 147 * is valid. 148 */ 149 delay(1); 150 (void)CSR_READ_1(chan->alt); 151 (void)CSR_READ_1(chan->alt); 152 (void)CSR_READ_1(chan->alt); 153 (void)CSR_READ_1(chan->alt); 154 155 sts = CSR_READ_1(chan->cmd + _STS); 156 while (milli-- > 0 157 && sts != 0xff 158 && (sts & (ATA_STS_BUSY|ATA_STS_DRDY)) != ATA_STS_DRDY) { 159 delay(1000); 160 sts = CSR_READ_1(chan->cmd + _STS); 161 } 162 163 msg = NULL; 164 if (sts == 0xff) 165 msg = "returned 0xff"; 166 else if (sts & ATA_STS_ERR) 167 msg = "returned ERR"; 168 else if (sts & ATA_STS_BUSY) 169 msg = "remains BUSY"; 170 else if ((sts & ATA_STS_DRDY) == 0) 171 msg = "no DRDY"; 172 173 if (err != NULL) 174 *err = msg; 175 return msg == NULL; 176 } 177 178 int 179 perform_atareset(struct dkdev_ata *l, int n) 180 { 181 struct dvata_chan *chan = &l->chan[n]; 182 183 CSR_WRITE_1(chan->ctl, ATA_DREQ); 184 delay(10); 185 CSR_WRITE_1(chan->ctl, ATA_SRST|ATA_DREQ); 186 delay(10); 187 CSR_WRITE_1(chan->ctl, ATA_DREQ); 188 189 return spinwait_unbusy(l, n, 1000, NULL); 190 } 191 192 /* clear idle and standby timers to spin up the drive */ 193 void 194 wakeup_drive(struct dkdev_ata *l, int n) 195 { 196 struct dvata_chan *chan = &l->chan[n]; 197 198 CSR_WRITE_1(chan->cmd + _NSECT, 0); 199 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_IDLE); 200 (void)CSR_READ_1(chan->alt); 201 delay(10 * 1000); 202 CSR_WRITE_1(chan->cmd + _NSECT, 0); 203 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_STANDBY); 204 (void)CSR_READ_1(chan->alt); 205 delay(10 * 1000); 206 } 207 208 int 209 atachkpwr(struct dkdev_ata *l, int n) 210 { 211 struct dvata_chan *chan = &l->chan[n]; 212 213 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_CHKPWR); 214 (void)CSR_READ_1(chan->alt); 215 delay(10 * 1000); 216 return CSR_READ_1(chan->cmd + _NSECT); 217 } 218 219 static int 220 probe_drive(struct dkdev_ata *l, int n) 221 { 222 struct dvata_chan *chan = &l->chan[n]; 223 uint16_t *p; 224 int i; 225 226 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_IDENT); 227 (void)CSR_READ_1(chan->alt); 228 delay(10 * 1000); 229 if (spinwait_unbusy(l, n, 1000, NULL) == 0) 230 return 0; 231 232 p = (uint16_t *)l->iobuf; 233 for (i = 0; i < 512; i += 2) { 234 /* need to have bswap16 */ 235 *p++ = iole16toh(chan->cmd + _DAT); 236 } 237 (void)CSR_READ_1(chan->cmd + _STS); 238 return 1; 239 } 240 241 static void 242 drive_ident(struct disk *d, char *ident) 243 { 244 uint16_t *p; 245 uint64_t huge; 246 247 p = (uint16_t *)ident; 248 DPRINTF(("[49]%04x [82]%04x [83]%04x [84]%04x " 249 "[85]%04x [86]%04x [87]%04x [88]%04x\n", 250 p[49], p[82], p[83], p[84], 251 p[85], p[86], p[87], p[88])); 252 huge = 0; 253 printf("%s: ", d->xname); 254 printf("<%s> ", mkident((char *)ident + 54, 40)); 255 if (p[49] & (1 << 8)) 256 printf("DMA "); 257 if (p[49] & (1 << 9)) { 258 printf("LBA "); 259 huge = p[60] | (p[61] << 16); 260 } 261 if ((p[83] & 0xc000) == 0x4000 && (p[83] & (1 << 10))) { 262 printf("LBA48 "); 263 huge = p[100] | (p[101] << 16); 264 huge |= (uint64_t)p[102] << 32; 265 huge |= (uint64_t)p[103] << 48; 266 } 267 huge >>= (1 + 10); 268 printf("%d MB\n", (int)huge); 269 270 memcpy(d->ident, ident, sizeof(d->ident)); 271 d->nsect = huge; 272 d->lba_read = lba_read; 273 } 274 275 static char * 276 mkident(char *src, int len) 277 { 278 static char local[40]; 279 char *dst, *end, *last; 280 281 if (len > sizeof(local)) 282 len = sizeof(local); 283 dst = last = local; 284 end = src + len - 1; 285 286 /* reserve space for '\0' */ 287 if (len < 2) 288 goto out; 289 /* skip leading white space */ 290 while (*src != '\0' && src < end && *src == ' ') 291 ++src; 292 /* copy string, omitting trailing white space */ 293 while (*src != '\0' && src < end) { 294 *dst++ = *src; 295 if (*src++ != ' ') 296 last = dst; 297 } 298 out: 299 *last = '\0'; 300 return local; 301 } 302 303 static void 304 decode_dlabel(struct disk *d, char *iobuf) 305 { 306 struct mbr_partition *mp, *bsdp; 307 struct disklabel *dlp; 308 struct partition *pp; 309 int i, first, rf_offset; 310 311 bsdp = NULL; 312 (*d->lba_read)(d, 0, 1, iobuf); 313 if (bswap16(*(uint16_t *)(iobuf + MBR_MAGIC_OFFSET)) != MBR_MAGIC) 314 goto skip; 315 mp = (struct mbr_partition *)(iobuf + MBR_PART_OFFSET); 316 for (i = 0; i < MBR_PART_COUNT; i++, mp++) { 317 if (mp->mbrp_type == MBR_PTYPE_NETBSD) { 318 bsdp = mp; 319 break; 320 } 321 } 322 skip: 323 rf_offset = 0; 324 first = (bsdp) ? bswap32(bsdp->mbrp_start) : 0; 325 (*d->lba_read)(d, first + LABELSECTOR, 1, iobuf); 326 dlp = search_dmagic(iobuf); 327 if (dlp == NULL) 328 goto notfound; 329 if (dlp->d_partitions[0].p_fstype == FS_RAID) { 330 printf("%s%c: raid\n", d->xname, 0 + 'a'); 331 snprintf(d->xname, sizeof(d->xname), "raid."); 332 rf_offset 333 = dlp->d_partitions[0].p_offset + RF_PROTECTED_SECTORS; 334 (*d->lba_read)(d, rf_offset + LABELSECTOR, 1, iobuf); 335 dlp = search_dmagic(iobuf); 336 if (dlp == NULL) 337 goto notfound; 338 } 339 for (i = 0; i < dlp->d_npartitions; i += 1) { 340 const char *type; 341 pp = &dlp->d_partitions[i]; 342 pp->p_offset += rf_offset; 343 type = NULL; 344 switch (pp->p_fstype) { 345 case FS_SWAP: 346 type = "swap"; 347 break; 348 case FS_BSDFFS: 349 type = "ffs"; 350 break; 351 case FS_EX2FS: 352 type = "ext2fs"; 353 break; 354 } 355 if (type != NULL) 356 printf("%s%c: %s\t(%u)\n", d->xname, i + 'a', type, 357 pp->p_offset); 358 } 359 d->dlabel = allocaligned(sizeof(struct disklabel), 4); 360 memcpy(d->dlabel, dlp, sizeof(struct disklabel)); 361 return; 362 notfound: 363 d->dlabel = NULL; 364 printf("%s: no disklabel\n", d->xname); 365 return; 366 } 367 368 struct disklabel * 369 search_dmagic(char *dp) 370 { 371 int i; 372 struct disklabel *dlp; 373 374 for (i = 0; i < 512 - sizeof(struct disklabel); i += 4, dp += 4) { 375 dlp = (struct disklabel *)dp; 376 if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC) 377 return dlp; 378 } 379 return NULL; 380 } 381 382 static void 383 set_xfermode(struct dkdev_ata *l, int n) 384 { 385 struct dvata_chan *chan = &l->chan[n]; 386 387 CSR_WRITE_1(chan->cmd + _FEA, ATA_XFER); 388 CSR_WRITE_1(chan->cmd + _NSECT, XFER_PIO0); 389 CSR_WRITE_1(chan->cmd + _DEV, ATA_DEV_OBS); /* ??? */ 390 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_SETF); 391 392 spinwait_unbusy(l, n, 1000, NULL); 393 } 394 395 static int 396 lba_read(struct disk *d, int64_t bno, int bcnt, void *buf) 397 { 398 struct dkdev_ata *l; 399 struct dvata_chan *chan; 400 void (*issue)(struct dvata_chan *, int64_t, int); 401 int n, rdcnt, i, k; 402 uint16_t *p; 403 const char *err; 404 int error; 405 406 l = d->dvops; 407 n = d->unittag; 408 p = (uint16_t *)buf; 409 chan = &l->chan[n]; 410 error = 0; 411 for ( ; bcnt > 0; bno += rdcnt, bcnt -= rdcnt) { 412 issue = (bno < (1ULL<<28)) ? issue28 : issue48; 413 rdcnt = (bcnt > 255) ? 255 : bcnt; 414 (*issue)(chan, bno, rdcnt); 415 for (k = 0; k < rdcnt; k++) { 416 if (spinwait_unbusy(l, n, 1000, &err) == 0) { 417 printf("%s blk %lld %s\n", d->xname, bno, err); 418 error = EIO; 419 break; 420 } 421 for (i = 0; i < 512; i += 2) { 422 /* arrives in native order */ 423 *p++ = *(uint16_t *)(chan->cmd + _DAT); 424 } 425 /* clear irq if any */ 426 (void)CSR_READ_1(chan->cmd + _STS); 427 } 428 } 429 return error; 430 } 431 432 static void 433 issue48(struct dvata_chan *chan, int64_t bno, int nblk) 434 { 435 436 CSR_WRITE_1(chan->cmd + _NSECT, 0); /* always less than 256 */ 437 CSR_WRITE_1(chan->cmd + _LBAL, (bno >> 24) & 0xff); 438 CSR_WRITE_1(chan->cmd + _LBAM, (bno >> 32) & 0xff); 439 CSR_WRITE_1(chan->cmd + _LBAH, (bno >> 40) & 0xff); 440 CSR_WRITE_1(chan->cmd + _NSECT, nblk); 441 CSR_WRITE_1(chan->cmd + _LBAL, (bno >> 0) & 0xff); 442 CSR_WRITE_1(chan->cmd + _LBAM, (bno >> 8) & 0xff); 443 CSR_WRITE_1(chan->cmd + _LBAH, (bno >> 16) & 0xff); 444 CSR_WRITE_1(chan->cmd + _DEV, ATA_DEV_LBA); 445 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_READ_EXT); 446 } 447 448 static void 449 issue28(struct dvata_chan *chan, int64_t bno, int nblk) 450 { 451 452 CSR_WRITE_1(chan->cmd + _NSECT, nblk); 453 CSR_WRITE_1(chan->cmd + _LBAL, (bno >> 0) & 0xff); 454 CSR_WRITE_1(chan->cmd + _LBAM, (bno >> 8) & 0xff); 455 CSR_WRITE_1(chan->cmd + _LBAH, (bno >> 16) & 0xff); 456 CSR_WRITE_1(chan->cmd + _DEV, ((bno >> 24) & 0xf) | ATA_DEV_LBA); 457 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_READ); 458 } 459 460 static struct disk * 461 lookup_disk(int unit) 462 { 463 464 return (unit >= 0 && unit < MAX_UNITS) ? &ldisk[unit] : NULL; 465 } 466 467 int 468 dlabel_valid(int unit) 469 { 470 struct disk *dsk; 471 472 dsk = lookup_disk(unit); 473 if (dsk == NULL) 474 return NULL; 475 return dsk->dlabel != NULL; 476 } 477 478 int 479 dsk_open(struct open_file *f, ...) 480 { 481 va_list ap; 482 int unit, part; 483 const char *name; 484 struct disk *d; 485 struct disklabel *dlp; 486 struct fs_ops *fs; 487 int error; 488 extern struct btinfo_bootpath bi_path; 489 extern struct btinfo_rootdevice bi_rdev; 490 extern struct fs_ops fs_ffsv2, fs_ffsv1; 491 492 va_start(ap, f); 493 unit = va_arg(ap, int); 494 part = va_arg(ap, int); 495 name = va_arg(ap, const char *); 496 va_end(ap); 497 498 if ((d = lookup_disk(unit)) == NULL) 499 return ENXIO; 500 if ((dlp = d->dlabel) == NULL || part >= dlp->d_npartitions) 501 return ENXIO; 502 d->part = part; 503 f->f_devdata = d; 504 505 snprintf(bi_path.bootpath, sizeof(bi_path.bootpath), name); 506 if (dlp->d_partitions[part].p_fstype == FS_BSDFFS) { 507 if ((error = ffsv2_open(name, f)) == 0) { 508 fs = &fs_ffsv2; 509 goto found; 510 } 511 if (error == EINVAL && (error = ffsv1_open(name, f)) == 0) { 512 fs = &fs_ffsv1; 513 goto found; 514 } 515 return error; 516 } 517 return ENXIO; 518 found: 519 d->fsops = fs; 520 f->f_devdata = d; 521 522 /* build btinfo to identify disk device */ 523 snprintf(bi_rdev.devname, sizeof(bi_rdev.devname), "wd"); 524 bi_rdev.cookie = (d->unittag << 8) | d->part; 525 return 0; 526 } 527 528 int 529 dsk_close(struct open_file *f) 530 { 531 struct disk *d = f->f_devdata; 532 struct fs_ops *fs = d->fsops; 533 534 (*fs->close)(f); 535 d->fsops = NULL; 536 f->f_devdata = NULL; 537 return 0; 538 } 539 540 int 541 dsk_strategy(void *devdata, int rw, daddr_t dblk, size_t size, 542 void *p, size_t *rsize) 543 { 544 struct disk *d = devdata; 545 struct disklabel *dlp; 546 int64_t bno; 547 548 if (size == 0) 549 return 0; 550 if (rw != F_READ) 551 return EOPNOTSUPP; 552 553 bno = dblk; 554 if ((dlp = d->dlabel) != NULL) 555 bno += dlp->d_partitions[d->part].p_offset; 556 (*d->lba_read)(d, bno, size / 512, p); 557 if (rsize != NULL) 558 *rsize = size; 559 return 0; 560 } 561 562 struct fs_ops * 563 dsk_fsops(struct open_file *f) 564 { 565 struct disk *d = f->f_devdata; 566 567 return d->fsops; 568 } 569