⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mscp_disk.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
    int			cmd;    caddr_t		data;    int			flag;{    register UNITB	*up;    /* If there is no known unit corresponding to the device     * number, return an error.     */    if(( up = Dev_to_unitb( dev )) == NULL ) {	return( ENXIO );    }    switch( cmd ) {    /* Get the current or default partition table values for the device     * 'dev' and store them in the buffer pointed to by 'data'.     */    case DIOCGETPT:    case DIOCDGTPT:	{	    register struct pt	*ptp = ( struct pt * )data;	    register int	i;	    /* If the current partition table values are wanted, use a structure	     * copy to get them into the user buffer.	     */	    if( cmd == DIOCGETPT ) {		*ptp = up->part_info;	    }	    /* Get the default partition table values based on the storage	     * medium currently loaded in the device.	     */	    else {		mscp_getdefpt( up->media_id, ptp );	    }	    /* Go through the user buffer, changing any partition sizes that	     * were specified as -1 to the actual partition size, calculated as	     * the size of the user-accessible portion of the disk minus the	     * starting LBN of the partition.	     */	    for( i = 0; i <= 7; i++ )		if( ptp->pt_part[ i ].pi_nblocks == -1 )		    ptp->pt_part[ i ].pi_nblocks = 			up->unt_size - ptp->pt_part[ i ].pi_blkoff;	    return( 0 );	}	        /* Replace the current partition table for the device with the contents     * of the user supplied buffer (after appropriate checking).     */    case DIOCSETPT:	{	    register struct pt	*ptp = ( struct pt * )data;	    int			error;	    /* If the caller is not the super-user, return a permission	     * denied (EACCES) error.	     */	    if( !suser() )		return( EACCES );	    /* If the user-supplied partition values conflict with the	     * active partition table, return an error.	     */	    if( ( error = ptcmp( dev, &up->part_info, ptp )) != 0 )		return( error );	    	    /* Set the partition tables in the UNITB using the data in the	     * user's buffer, update the superblock in the 'a' partition	     * if necessary, set the partition table valid bit, and return	     * success to the caller.	     */	    up->part_info = *ptp;	    ( void )ssblk( dev, ptp );	    up->part_info.pt_valid = PT_VALID;	    return( 0 );	}        case DEVIOCGET:	{	    register struct devget	*dp = ( struct devget * )data;	    register struct uba_device	*ui = up->ubdev;	    register CONNB		*cp = up->connb;	    bzero( dp, sizeof( struct devget ));	    dp->category = DEV_DISK;	    dp->bus = cp->bus_type;	    bcopy( cp->model_name, dp->interface, strlen( cp->model_name ));	    mscp_media_to_ascii( up->media_id, dp->device );	    dp->adpt_num = ui->ui_adpt;	    dp->nexus_num = ui->ui_nexus;	    dp->bus_num = ui->ui_ubanum;	    dp->rctlr_num = ui->ui_rctlr;	    dp->ctlr_num = ui->ui_ctlr;	    dp->slave_num = up->unit;	    bcopy( ui->ui_devname, dp->dev_name, strlen( ui->ui_devname ));	    dp->unit_num = ui->ui_unit;	    dp->soft_count = 0;	    dp->hard_count = 0;	    dp->stat = 0;	    if( up->flags.online == 0 )		dp->stat |= DEV_OFFLINE;	    if( up->flags.wrtp == 1 )		dp->stat |= DEV_WRTLCK;	    dp->category_stat = DEV_DISKPART;	    return( 0 );	}    /* Ioctl to obtain device geometry information.     */    case DEVGETGEOM:	{	    DEVGEOMST	*devgeom = ( DEVGEOMST * )data;	    register int calcs, ncyl;	    bzero( devgeom, sizeof( DEVGEOMST ));	    calcs = up->group * up->cylinder;	    devgeom->geom_info.dev_size = up->unt_size;	    devgeom->geom_info.ntracks = calcs;	    devgeom->geom_info.nsectors = up->track;	    calcs *= up->track;	    if (calcs > 0) {	    	ncyl = up->unt_size / calcs;	    	if (up->unt_size % calcs)			ncyl++;   /* round up */	    }	    else {		ncyl = 0;	    }	    devgeom->geom_info.ncylinders = ncyl;	    if (up->unt_flgs & MSCP_UF_RMVBL)		devgeom->geom_info.attributes |= DEVGEOM_REMOVE;	    return( 0 );	}    /* Ioctl used by radisk(8) to scan the disk or force a replacement     */  case DKIOCACC:	{	struct dkacc *dkacc = (struct dkacc *)data;        register REQB	*rp;        long 	totbytes;        long	length;        long	lbn;	/* Only super users can beat on the pack	 */	if ( !suser() )		return(EACCES);	switch (dkacc->dk_opcode){	case ACC_REVEC:	    /* Return if the controller does the work	     */            if(( up->unt_flgs & MSCP_UF_REPLC ||	           up->flags.wrtp ))		{			return(0);		}	    if (up->flags.force_scan_ip == 1)	            return(EBUSY);	    up->flags.force_scan_ip = 1;	    /* Force LBN  to be re-vectored	     */	    rp = (REQB *)mscp_alloc_reqb( up,			     		  NULL,			     		  mscp_repl_states,			     		  dkacc->dk_lbn,			     		  0 );	    while( up->flags.force_scan_ip ) {    		timeout( wakeup, ( caddr_t )rp, 5 * hz );    		( void )sleep(( caddr_t )rp, PSWP+1 ); 		untimeout( wakeup, ( caddr_t )rp );	    }	    dkacc->dk_status = 0;		    break;	case ACC_SCAN:	    if (dkacc->dk_lbn > up->unt_size)		    return(EINVAL);	    lbn = dkacc->dk_lbn;	    totbytes = 0;	    if (up->connb->max_bcnt == 0)	        up->connb->max_bcnt = 16777216;	    if (up->flags.force_scan_ip == 1)	            return(EBUSY);	    while (dkacc->dk_length ) {	        up->flags.force_scan_ip = 1;		length = (dkacc->dk_length > up->connb->max_bcnt)	         	? up->connb->max_bcnt : dkacc->dk_length;	        rp = (REQB *)mscp_alloc_reqb( up, NULL, 				mscp_accscan_states, lbn, length);	        while( up->flags.force_scan_ip ) {    		    timeout( wakeup, ( caddr_t )rp, 5 * hz );    		    ( void )sleep(( caddr_t )rp, PSWP+1 );    		    untimeout( wakeup, ( caddr_t )rp );	        }		totbytes += up->acc_bytecnt;		if (up->acc_status != MSCP_ST_SUCC) 		    break;				lbn += btodb(up->acc_bytecnt);		dkacc->dk_length -= up->acc_bytecnt;	    }    	    dkacc->dk_status = up->acc_status;    	    dkacc->dk_flags = up->acc_flags;    	    dkacc->dk_lbn = up->acc_badlbn;    	    dkacc->dk_length  = totbytes;	    break;	default:	    break;	  	}	return( 0 );	}    /* Ioctl used by radisk(8) to control the exclusive access attribute.     */  case DKIOCEXCL:	{	    int *action = (int *)data;            register REQB	*rp;	    /* Only super users can modify this attribute.	     */	    if ( !suser() ) {		return(EACCES);	    }	    /* Set the up->flags.excl_acc flag to be the specified mode of	     * exclusive access.  Next call the set unit characteristics state	     * table.  When that completes if the value of excl_acc changes it	     * means that the operation failed.	     */	    if ( *data == 0 ) {	/* clear */		if ( up->flags.excl_acc == 0 ) {		    return(EIO);		}		up->flags.excl_acc = 0;	    }	    else {		/* set */		up->flags.excl_acc = 1;	    }	    /* Force a set unit characteristics to set exclusive mode.	     */	    if ( up->flags.mscp_wait == 1 )	        return(EBUSY);	    up->flags.mscp_wait = 1;	    rp = (REQB *)mscp_alloc_reqb( up, NULL, mscp_stu_states, 0, 0);	    while( up->flags.mscp_wait ) {    	 	timeout( wakeup, ( caddr_t )rp, 5 * hz );    	 	( void )sleep(( caddr_t )rp, PSWP+1 ); 	 	untimeout( wakeup, ( caddr_t )rp );	    }	    if ( *data == 0 ) {			/* clear failed */		if ( up->flags.excl_acc ) {			return(EIO);		}	    }	    else {		if ( up->flags.excl_acc == 0 ) {			return(EIO);		}	    }	    return( 0 );	}    default:	return( 0 );    }}/**//* * *   Name:	mscp_forcecm - Start a forced replace * *   Abstract:	This function calls the bbr_force() routine *		to force a replacement.  This function is entered *		as a result of an radisk(8) request. * * *   Inputs:	event			Event code. *		rp			Request block pointer. * *   Outputs:	NONE * * *   Return	NONE. *   Values: */u_longmscp_forcecm( event, rp )    u_long			event;    register REQB		*rp;{    register MSCP		*mp = rp->msgptr;		mp->mscp_lbn = rp->p1;	mp->mscp_status = 0;	return( mscp_bbr_force( rp ) );}/**//* * *   Name:	mscp_forceem - Cleanup afer a forced replace * *   Abstract:	This function deallocates the resources allocated for *		the replacement and clears the force_scan_ip bit to indicate *		the replacement is complete.  The ioctl() function is *		spinning on this bit. The access scan function is also *		spinning on this bit after a bad block replace. * * *   Inputs:	event			Event code. *		rp			Request block pointer. * *   Outputs:	NONE * * *   Return	NONE. *   Values: */u_longmscp_forceem( event, rp )    u_long			event;    register REQB		*rp;{    register UNITB		*up = rp->unitb;    up->flags.force_scan_ip = 0;    mscp_dealloc_reqb( rp );    return( EV_NULL);	}/**//* * *   Name:	mscp_size - Find the size of a partition. * *   Abstract:	This routine returns the size of the partition specified *		by a given device number. * *   Inputs:	dev			Device number. * *   Outputs:	NONE * * *   Return	Size of partition specified by dev. *   Values: */int mscp_size( dev )    dev_t		dev;{    register int	part_size;    register UNITB	*up;    register int	px = Px( dev );    /* If the unit index is greater than the assembled-in maximum,     * or if there is no unit in the configuration corresponding to     * the unit index, return -1.     */    up = Dev_to_unitb( dev );    if( up == NULL || !up->flags.online ) 	return( -1 );    /* As a sanity check, panic if the partition table information     * is not marked valid.     */    if( up->part_info.pt_valid != PT_VALID )	panic( "mscp_size: invalid partition table\n" );    /* If the actual size of the partition is specified (not -1), return it     * to the caller.  Otherwise, calculate the partition size as the size of     * the user-accessible area of the disk minus the starting LBN of the     * partition, and return it to the caller.     */    if(( part_size = up->part_info.pt_part[ px ].pi_nblocks ) != -1 )	return( part_size );    else	return( up->unt_size - up->part_info.pt_part[ px ].pi_blkoff );}/**//* * *   Name:	mscp_getdefpt - get default partition information. * *   Abstract:	Find the partition information corresponding to the *		input media ID and store it in a user-provided *		partition structure. * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */void mscp_getdefpt( media_id, ptp )    u_long		media_id;    struct pt		*ptp;{    register int	i;    register PART_SIZE	*psp;    /* Look up the media ID in the disk media table.  If it isn't found, use     * reserved entry 0 as the default media type.     */    for( i = dmscp_media_ct - 1;	 i > 0 && dmscp_media[ i ].media_id != media_id;	 i-- )	;    /* Move the default partition values for the device (medium) into     * the user's partition structure.     */    psp = dmscp_media[ i ].part_sizes;    for( i = 0; i <= 7; i++, psp++ ) {	ptp->pt_part[ i ].pi_nblocks = psp->p_nblocks;	ptp->pt_part[ i ].pi_blkoff = psp->p_blkoff;    }    return;}/**//* * *   Name:	mscp_check_sysdev - check/wait for system device availability. * *   Abstract:	A requested device has been found to be unconfigured. *		Check to see if the device is the root, swap or dump *		device specified in the configuration file and if so, *		wait for the device to become available.  If the device *		is none of the foregoing, return an ENXIO error. * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */UNITB *mscp_check_sysdev( dev )    dev_t			dev;{    register UNITB		*up = NULL;    register struct swdevt	*sp;    register int		retries = 120;    dev_t			dev_min,dev_maj;    /* If the given device is one of the swap devices or is     * the root or dump device, wait for it to be configured.     */    for( sp = &swdevt[ 0 ]; 	 ( dev_t )sp->sw_dev != 0 &&	 ( dev_t )dev != ( dev_t )sp->sw_dev;	 sp++ )	 ;    if( ( dev_t )dev == ( dev_t )sp->sw_dev ||	( dev_t )dev == ( dev_t )rootdev ||         ( dev_t )dev == ( dev_t )dumpdev )	while(( up = Dev_to_unitb( dev )) == NULL && ( --retries >= 0 )) {	    /* if we're half way through the wait give some status	     */	    if( retries == 60 ) {	        dev_maj = major(dev);	        dev_min = minor(dev);                if( ( dev_t )dev == ( dev_t )sp->sw_dev )                    printf("Waiting up to 1 more minute for swap device \(%d,%d\) to become available\n", dev_maj,dev_min);	        else if( ( dev_t )dev == ( dev_t )rootdev )                    printf("Waiting up to 1 more minute for root device \(%d,%d\) to become available\n", dev_maj,dev_min);	        else if( ( dev_t )dev == ( dev_t )dumpdev )                    printf("Waiting up to 1 more minute for dump device \(%d,%d\) to become available\n", dev_maj,dev_min);            }	    timeout( wakeup, ( caddr_t )dev, 1*hz );	    ( void )sleep(( caddr_t )dev, PSWP+1 );	}    return( up );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -