1 /* $NetBSD: dsk.c,v 1.7 2011/06/20 19:48:05 jdc 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 #include <dev/raidframe/raidframevar.h> 48 49 #include <machine/bootinfo.h> 50 #include <machine/stdarg.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) *(volatile uint8_t *)(r) 60 #define CSR_WRITE_1(r,v) *(volatile uint8_t *)(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 int lba_read(struct disk *, int64_t, int, void *); 81 static void issue48(struct dvata_chan *, int64_t, int); 82 static void issue28(struct dvata_chan *, int64_t, int); 83 static struct disk *lookup_disk(int); 84 85 #define MAX_UNITS 8 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 disk_scan(pci->drv); 106 return 1; 107 } 108 109 static void 110 disk_scan(void *drv) 111 { 112 struct dkdev_ata *l = drv; 113 struct disk *d; 114 static int ndrive = 0; 115 int n; 116 117 for (n = 0; n < 4 && ndrive < MAX_UNITS; n++) { 118 if (l->presense[n] == 0) 119 continue; 120 if (probe_drive(l, n) == 0) { 121 l->presense[n] = 0; 122 continue; 123 } 124 d = &ldisk[ndrive]; 125 d->dvops = l; 126 d->unittag = ndrive; 127 snprintf(d->xname, sizeof(d->xname), "wd%d", d->unittag); 128 set_xfermode(l, n); 129 drive_ident(d, l->iobuf); 130 decode_dlabel(d, l->iobuf); 131 ndrive += 1; 132 } 133 } 134 135 int 136 spinwait_unbusy(struct dkdev_ata *l, int n, int milli, const char **err) 137 { 138 struct dvata_chan *chan = &l->chan[n]; 139 int sts; 140 const char *msg; 141 142 /* 143 * For best compatibility it is recommended to wait 400ns and 144 * read the alternate status byte four times before the status 145 * is valid. 146 */ 147 delay(1); 148 (void)CSR_READ_1(chan->alt); 149 (void)CSR_READ_1(chan->alt); 150 (void)CSR_READ_1(chan->alt); 151 (void)CSR_READ_1(chan->alt); 152 153 sts = CSR_READ_1(chan->cmd + _STS); 154 while (milli-- > 0 155 && sts != 0xff 156 && (sts & (ATA_STS_BUSY|ATA_STS_DRDY)) != ATA_STS_DRDY) { 157 delay(1000); 158 sts = CSR_READ_1(chan->cmd + _STS); 159 } 160 161 msg = NULL; 162 if (sts == 0xff) 163 msg = "returned 0xff"; 164 else if (sts & ATA_STS_ERR) 165 msg = "returned ERR"; 166 else if (sts & ATA_STS_BUSY) 167 msg = "remains BUSY"; 168 else if ((sts & ATA_STS_DRDY) == 0) 169 msg = "no DRDY"; 170 171 if (err != NULL) 172 *err = msg; 173 return msg == NULL; 174 } 175 176 int 177 perform_atareset(struct dkdev_ata *l, int n) 178 { 179 struct dvata_chan *chan = &l->chan[n]; 180 181 CSR_WRITE_1(chan->ctl, ATA_DREQ); 182 delay(10); 183 CSR_WRITE_1(chan->ctl, ATA_SRST|ATA_DREQ); 184 delay(10); 185 CSR_WRITE_1(chan->ctl, ATA_DREQ); 186 187 return spinwait_unbusy(l, n, 150, NULL); 188 } 189 190 int 191 satapresense(struct dkdev_ata *l, int n) 192 { 193 #define VND_CH(n) (((n&02)<<8)+((n&01)<<7)) 194 #define VND_SC(n) (0x100+VND_CH(n)) 195 #define VND_SS(n) (0x104+VND_CH(n)) 196 197 uint32_t sc = l->bar[5] + VND_SC(n); 198 uint32_t ss = l->bar[5] + VND_SS(n); 199 unsigned val; 200 201 val = (00 << 4) | (03 << 8); /* any speed, no pwrmgt */ 202 CSR_WRITE_4(sc, val | 01); /* perform init */ 203 delay(50 * 1000); 204 CSR_WRITE_4(sc, val); 205 delay(50 * 1000); 206 val = CSR_READ_4(ss); /* has completed */ 207 return ((val & 03) == 03); /* active drive found */ 208 } 209 210 static int 211 probe_drive(struct dkdev_ata *l, int n) 212 { 213 struct dvata_chan *chan = &l->chan[n]; 214 uint16_t *p; 215 int i; 216 217 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_IDENT); 218 (void)CSR_READ_1(chan->alt); 219 delay(10 * 1000); 220 if (spinwait_unbusy(l, n, 1000, NULL) == 0) 221 return 0; 222 223 p = (uint16_t *)l->iobuf; 224 for (i = 0; i < 512; i += 2) { 225 /* need to have bswap16 */ 226 *p++ = iole16toh(chan->cmd + _DAT); 227 } 228 (void)CSR_READ_1(chan->cmd + _STS); 229 return 1; 230 } 231 232 static void 233 drive_ident(struct disk *d, char *ident) 234 { 235 uint16_t *p; 236 uint64_t huge; 237 238 p = (uint16_t *)ident; 239 DPRINTF(("[49]%04x [82]%04x [83]%04x [84]%04x " 240 "[85]%04x [86]%04x [87]%04x [88]%04x\n", 241 p[49], p[82], p[83], p[84], 242 p[85], p[86], p[87], p[88])); 243 huge = 0; 244 printf("%s: ", d->xname); 245 printf("<%s> ", mkident((char *)ident + 54, 40)); 246 if (p[49] & (1 << 8)) 247 printf("DMA "); 248 if (p[49] & (1 << 9)) { 249 printf("LBA "); 250 huge = p[60] | (p[61] << 16); 251 } 252 if ((p[83] & 0xc000) == 0x4000 && (p[83] & (1 << 10))) { 253 printf("LBA48 "); 254 huge = p[100] | (p[101] << 16); 255 huge |= (uint64_t)p[102] << 32; 256 huge |= (uint64_t)p[103] << 48; 257 } 258 huge >>= (1 + 10); 259 printf("%d MB\n", (int)huge); 260 261 memcpy(d->ident, ident, sizeof(d->ident)); 262 d->nsect = huge; 263 d->lba_read = lba_read; 264 } 265 266 static char * 267 mkident(char *src, int len) 268 { 269 static char local[40]; 270 char *dst, *end, *last; 271 272 if (len > sizeof(local)) 273 len = sizeof(local); 274 dst = last = local; 275 end = src + len - 1; 276 277 /* reserve space for '\0' */ 278 if (len < 2) 279 goto out; 280 /* skip leading white space */ 281 while (*src != '\0' && src < end && *src == ' ') 282 ++src; 283 /* copy string, omitting trailing white space */ 284 while (*src != '\0' && src < end) { 285 *dst++ = *src; 286 if (*src++ != ' ') 287 last = dst; 288 } 289 out: 290 *last = '\0'; 291 return local; 292 } 293 294 static void 295 decode_dlabel(struct disk *d, char *iobuf) 296 { 297 struct mbr_partition *mp, *bsdp; 298 struct disklabel *dlp; 299 struct partition *pp; 300 char *dp; 301 int i, first, rf_offset; 302 303 bsdp = NULL; 304 (*d->lba_read)(d, 0, 1, iobuf); 305 if (bswap16(*(uint16_t *)(iobuf + MBR_MAGIC_OFFSET)) != MBR_MAGIC) 306 goto skip; 307 mp = (struct mbr_partition *)(iobuf + MBR_PART_OFFSET); 308 for (i = 0; i < MBR_PART_COUNT; i++, mp++) { 309 if (mp->mbrp_type == MBR_PTYPE_NETBSD) { 310 bsdp = mp; 311 break; 312 } 313 } 314 skip: 315 rf_offset = 0; 316 first = (bsdp) ? bswap32(bsdp->mbrp_start) : 0; 317 (*d->lba_read)(d, first + LABELSECTOR, 1, iobuf); 318 dp = iobuf /* + LABELOFFSET */; 319 for (i = 0; i < 512 - sizeof(struct disklabel); i++, dp += 4) { 320 dlp = (struct disklabel *)dp; 321 if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC) { 322 if (dlp->d_partitions[0].p_fstype == FS_RAID) { 323 printf("%s%c: raid\n", d->xname, i + 'a'); 324 snprintf(d->xname, sizeof(d->xname), "raid."); 325 rf_offset = dlp->d_partitions[0].p_offset + 326 RF_PROTECTED_SECTORS; 327 (*d->lba_read)(d, rf_offset + LABELSECTOR, 1, 328 iobuf); 329 dp = iobuf /* + LABELOFFSET */; 330 for (i = 0; i < 512 - sizeof(struct disklabel); i++, dp += 4) { 331 dlp = (struct disklabel *)dp; 332 if (dlp->d_magic == DISKMAGIC && 333 dlp->d_magic2 == DISKMAGIC) 334 goto found; 335 } 336 } else /* Not RAID */ 337 goto found; 338 } 339 } 340 d->dlabel = NULL; 341 printf("%s: no disklabel\n", d->xname); 342 return; 343 found: 344 for (i = 0; i < dlp->d_npartitions; i += 1) { 345 const char *type; 346 pp = &dlp->d_partitions[i]; 347 pp->p_offset += rf_offset; 348 type = NULL; 349 switch (pp->p_fstype) { 350 case FS_SWAP: /* swap */ 351 type = "swap"; 352 break; 353 case FS_BSDFFS: 354 type = "ffs"; 355 break; 356 case FS_EX2FS: 357 type = "ext2fs"; 358 break; 359 } 360 if (type != NULL) 361 printf("%s%c: %s\t(%u)\n", d->xname, i + 'a', type, 362 pp->p_offset); 363 } 364 d->dlabel = allocaligned(sizeof(struct disklabel), 4); 365 memcpy(d->dlabel, dlp, sizeof(struct disklabel)); 366 } 367 368 static void 369 set_xfermode(struct dkdev_ata *l, int n) 370 { 371 struct dvata_chan *chan = &l->chan[n]; 372 373 CSR_WRITE_1(chan->cmd + _FEA, ATA_XFER); 374 CSR_WRITE_1(chan->cmd + _NSECT, XFER_PIO0); 375 CSR_WRITE_1(chan->cmd + _DEV, ATA_DEV_OBS); /* ??? */ 376 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_SETF); 377 378 spinwait_unbusy(l, n, 1000, NULL); 379 } 380 381 static int 382 lba_read(struct disk *d, int64_t bno, int bcnt, void *buf) 383 { 384 struct dkdev_ata *l; 385 struct dvata_chan *chan; 386 void (*issue)(struct dvata_chan *, int64_t, int); 387 int n, rdcnt, i, k; 388 uint16_t *p; 389 const char *err; 390 int error; 391 392 l = d->dvops; 393 n = d->unittag; 394 p = (uint16_t *)buf; 395 chan = &l->chan[n]; 396 error = 0; 397 for ( ; bcnt > 0; bno += rdcnt, bcnt -= rdcnt) { 398 issue = (bno < (1ULL<<28)) ? issue28 : issue48; 399 rdcnt = (bcnt > 255) ? 255 : bcnt; 400 (*issue)(chan, bno, rdcnt); 401 for (k = 0; k < rdcnt; k++) { 402 if (spinwait_unbusy(l, n, 1000, &err) == 0) { 403 printf("%s blk %lld %s\n", d->xname, bno, err); 404 error = EIO; 405 break; 406 } 407 for (i = 0; i < 512; i += 2) { 408 /* arrives in native order */ 409 *p++ = *(uint16_t *)(chan->cmd + _DAT); 410 } 411 /* clear irq if any */ 412 (void)CSR_READ_1(chan->cmd + _STS); 413 } 414 } 415 return error; 416 } 417 418 static void 419 issue48(struct dvata_chan *chan, int64_t bno, int nblk) 420 { 421 422 CSR_WRITE_1(chan->cmd + _NSECT, 0); /* always less than 256 */ 423 CSR_WRITE_1(chan->cmd + _LBAL, (bno >> 24) & 0xff); 424 CSR_WRITE_1(chan->cmd + _LBAM, (bno >> 32) & 0xff); 425 CSR_WRITE_1(chan->cmd + _LBAH, (bno >> 40) & 0xff); 426 CSR_WRITE_1(chan->cmd + _NSECT, nblk); 427 CSR_WRITE_1(chan->cmd + _LBAL, (bno >> 0) & 0xff); 428 CSR_WRITE_1(chan->cmd + _LBAM, (bno >> 8) & 0xff); 429 CSR_WRITE_1(chan->cmd + _LBAH, (bno >> 16) & 0xff); 430 CSR_WRITE_1(chan->cmd + _DEV, ATA_DEV_LBA); 431 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_READ_EXT); 432 } 433 434 static void 435 issue28(struct dvata_chan *chan, int64_t bno, int nblk) 436 { 437 438 CSR_WRITE_1(chan->cmd + _NSECT, nblk); 439 CSR_WRITE_1(chan->cmd + _LBAL, (bno >> 0) & 0xff); 440 CSR_WRITE_1(chan->cmd + _LBAM, (bno >> 8) & 0xff); 441 CSR_WRITE_1(chan->cmd + _LBAH, (bno >> 16) & 0xff); 442 CSR_WRITE_1(chan->cmd + _DEV, ((bno >> 24) & 0xf) | ATA_DEV_LBA); 443 CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_READ); 444 } 445 446 static struct disk * 447 lookup_disk(int unit) 448 { 449 450 return &ldisk[unit]; 451 } 452 453 int 454 dsk_open(struct open_file *f, ...) 455 { 456 va_list ap; 457 int unit, part; 458 const char *name; 459 struct disk *d; 460 struct disklabel *dlp; 461 struct fs_ops *fs; 462 int error; 463 extern struct btinfo_bootpath bi_path; 464 extern struct btinfo_rootdevice bi_rdev; 465 extern struct fs_ops fs_ffsv2, fs_ffsv1; 466 467 va_start(ap, f); 468 unit = va_arg(ap, int); 469 part = va_arg(ap, int); 470 name = va_arg(ap, const char *); 471 va_end(ap); 472 473 if ((d = lookup_disk(unit)) == NULL) 474 return ENXIO; 475 f->f_devdata = d; 476 if ((dlp = d->dlabel) == NULL || part >= dlp->d_npartitions) 477 return ENXIO; 478 d->part = part; 479 480 snprintf(bi_path.bootpath, sizeof(bi_path.bootpath), name); 481 if (dlp->d_partitions[part].p_fstype == FS_BSDFFS) { 482 if ((error = ffsv2_open(name, f)) == 0) { 483 fs = &fs_ffsv2; 484 goto found; 485 } 486 if (error == EINVAL && (error = ffsv1_open(name, f)) == 0) { 487 fs = &fs_ffsv1; 488 goto found; 489 } 490 return error; 491 } 492 return ENXIO; 493 found: 494 d->fsops = fs; 495 f->f_devdata = d; 496 497 /* build btinfo to identify disk device */ 498 snprintf(bi_rdev.devname, sizeof(bi_rdev.devname), "wd"); 499 bi_rdev.cookie = d->unittag; /* disk unit number */ 500 return 0; 501 } 502 503 int 504 dsk_close(struct open_file *f) 505 { 506 struct disk *d = f->f_devdata; 507 struct fs_ops *fs = d->fsops; 508 509 (*fs->close)(f); 510 d->fsops = NULL; 511 f->f_devdata = NULL; 512 return 0; 513 } 514 515 int 516 dsk_strategy(void *devdata, int rw, daddr_t dblk, size_t size, 517 void *p, size_t *rsize) 518 { 519 struct disk *d = devdata; 520 struct disklabel *dlp; 521 int64_t bno; 522 523 if (size == 0) 524 return 0; 525 if (rw != F_READ) 526 return EOPNOTSUPP; 527 528 bno = dblk; 529 if ((dlp = d->dlabel) != NULL) 530 bno += dlp->d_partitions[d->part].p_offset; 531 (*d->lba_read)(d, bno, size / 512, p); 532 if (rsize != NULL) 533 *rsize = size; 534 return 0; 535 } 536 537 struct fs_ops * 538 dsk_fsops(struct open_file *f) 539 { 540 struct disk *d = f->f_devdata; 541 542 return d->fsops; 543 } 544