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