Esempio n. 1
0
File: sd.c Progetto: ryo/netbsd-src
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;
    }
Esempio n. 2
0
/*
 * 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;
}