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