int sdgetinfo(struct sd_softc *ss) { struct scsipi_read_capacity_10 cdb; struct scsipi_read_capacity_10_data cap; struct sdminilabel *pi = &ss->sc_pinfo; struct next68k_disklabel *label; int error, i, blklen; char io_buf[NEXT68K_LABEL_SIZE+NEXT68K_LABEL_OFFSET]; int count; int sc_blkshift = 0; memset(&cdb, 0, sizeof(cdb)); cdb.opcode = READ_CAPACITY_10; count = sizeof(cap); error = scsiicmd(ss->sc_unit, ss->sc_lun, (u_char *)&cdb, sizeof(cdb), (char *)&cap, &count); if (error != 0) return error<0 ? EHER : error; blklen = (cap.length[0]<<24) + (cap.length[1]<<16) + (cap.length[2]<<8) + cap.length[3]; ss->sc_dev_bsize = blklen; ss->sc_pinfo.offset[ss->sc_part] = 0; /* read absolute sector */ error = sdstrategy(ss, F_READ, NEXT68K_LABEL_SECTOR, NEXT68K_LABEL_SIZE+NEXT68K_LABEL_OFFSET, io_buf, (unsigned int *)&i); if (error != 0) { DPRINTF(("sdgetinfo: sdstrategy error %d\n", error)); return(ERDLAB); } label = (struct next68k_disklabel *)(io_buf+NEXT68K_LABEL_OFFSET); if (!IS_DISKLABEL(label)) /* || (label->cd_flags & CD_UNINIT)!=0) */ return EUNLAB; /* bad magic */ /* XXX calculate checksum ... for now we rely on the magic number */ DPRINTF(("Disk is %s (%s, %s).\n", label->cd_label,label->cd_name, label->cd_type)); while (label->cd_secsize > blklen) { blklen <<= 1; ++sc_blkshift; } if (label->cd_secsize < blklen) { printf("bad label sectorsize (%d) or device blocksize (%d).\n", label->cd_secsize, blklen>>sc_blkshift); return ENXIO; }
/* * Load the label information on the named device. */ static int sdgetdisklabel(struct sd_softc *sd) { struct mbr_sector *mbr; struct mbr_partition *mp; struct disklabel *lp = &sd->sc_label; size_t rsize; int sector, i; char *msg; uint8_t buf[DEV_BSIZE]; sdgetdefaultlabel(sd, lp); if (lp->d_secpercyl == 0) { lp->d_secpercyl = 100; /* as long as it's not 0 - readdisklabel divides by it (?) */ } /* * Find NetBSD Partition in DOS partition table. */ sector = 0; if (sdstrategy(sd, F_READ, MBR_BBSECTOR, DEV_BSIZE, buf, &rsize)) return EOFFSET; mbr = (struct mbr_sector *)buf; if (mbr->mbr_magic == htole16(MBR_MAGIC)) { /* * Lookup NetBSD slice. If there is none, go ahead * and try to read the disklabel off sector #0. */ mp = mbr->mbr_parts; for (i = 0; i < MBR_PART_COUNT; i++) { if (mp[i].mbrp_type == MBR_PTYPE_NETBSD) { sector = le32toh(mp[i].mbrp_start); break; } } } if (sdstrategy(sd, F_READ, sector + LABELSECTOR, DEV_BSIZE, buf, &rsize)) return EOFFSET; msg = getdisklabel((const char *)buf + LABELOFFSET, &sd->sc_label); if (msg) printf("sd(%d,%d,%d,...): getdisklabel: %s\n", sd->sc_bus, sd->sc_target, sd->sc_lun, msg); /* check partition */ if ((sd->sc_part >= lp->d_npartitions) || (lp->d_partitions[sd->sc_part].p_fstype == FS_UNUSED)) { DPRINTF(("illegal partition\n")); return EPART; } DPRINTF(("label info: d_secsize %d, d_nsectors %d, d_ncylinders %d," " d_ntracks %d, d_secpercyl %d\n", sd->sc_label.d_secsize, sd->sc_label.d_nsectors, sd->sc_label.d_ncylinders, sd->sc_label.d_ntracks, sd->sc_label.d_secpercyl)); return 0; }