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

📄 mscp_disk.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
mscp_recovnext( event, rp )    u_long			event;    register REQB		*rp;{    register UNITB		*up = rp->unitb;    register CONNB		*cp = rp->connb;    register u_long		new_event = EV_NULL;	    /* If this routine was entered as a result of successful completion     * of the BBR algorithm or of the GTUNT command, set the unit online     */    if( event == EV_ERRECOV || event == EV_ONLCOMPLETE ) {	up->flags.online = 1;	up->flags.online_ip = 0;    }    /* Find the next unit that was online when the connection dropped.     */    for( up = up->flink;	 up != ( UNITB * )&cp->unit.flink && !up->flags.online;	 up = up->flink )	{}        /* If we found another previously online unit, mark it offline with     * online in progress, store the unit block pointer in the request     * block and redispatch to bring the unit online.     */    if( up != ( UNITB * )&cp->unit.flink ) {	up->flags.online = 0;	up->flags.online_ip = 1;	rp->unitb = up;	new_event = EV_ONLDONEXT;    /* No more units were online.  Attempt to start the first request on     * the restart queue, deallocate the resources held by the request     * block and terminate the thread.     */    } else {	mscp_restart_next( cp );	mscp_dealloc_all( rp );    }    return( new_event );}/**//* * *   Name:	mscp_strategy - rtn description * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_strategy( bp )    register struct buf		*bp;{    register UNITB		*up;    register int		px;    register int		psize;    register daddr_t		pstart;    register int		errno = 0;    /* Check to make sure that the unit corresponding to the device number     * exists and is online.  If not, return an error to the user.     */    up = Dev_to_unitb( bp->b_dev );    if( up == NULL || !up->flags.online ) 	errno = ENXIO;    /* If the partition table for the unit is not valid, panic.     */    else if( up->part_info.pt_valid != PT_VALID )	panic( "mscp_strategy: invalid partition table\n" );	    /* Get the partition offset and size from the current partition     * table in the unit block.  If the partition size is specified     * as -1, calculate the partition size as the number of blocks     * from the start of the partition to the end of the user area.     */    else {	px = Px( bp->b_dev );	pstart = up->part_info.pt_part[ px ].pi_blkoff;	if(( psize = up->part_info.pt_part[ px ].pi_nblocks ) == -1 )	    psize = up->unt_size - pstart;	/* Ensure that the transfer lies entirely within the bounds of 	 * the partition.  If so, allocate a request block and start the	 * data transfer.  Otherwise return an error to the user.  (Note	 * that the process sleeps until the request block is allocated.)	 */	if( pstart >= 0 &&	    bp->b_blkno + (( bp->b_bcount + 511 ) >> 9 ) <= psize )	    ( void )mscp_alloc_reqb( up,				     bp,				     mscp_xfr_states,				     pstart + bp->b_blkno,				     0 );	else 	    errno = ENOSPC;    }    /* If an error has been detected, set the error indicator and error     * number in the buf structure and terminate the I/O operation.     */     if( errno ) {	bp->b_error = errno;	bp->b_flags |= B_ERROR;	( void )iodone( bp );    }    return;}/**//* * *   Name:	mscp_bopen - Block mode open routine * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_bopen( dev, flag )    dev_t			dev;    int				flag;{    return( mscp_open( dev, flag, 0 ));}/**//* * *   Name:	mscp_copen - Raw (character) mode open routine * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_copen( dev, flag )    dev_t			dev;    int				flag;{    return( mscp_open( dev, flag, 1 ));}/**//* * *   Name:	mscp_open	- Open Disk Unit * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */intmscp_open(dev, flag, raw)    dev_t			dev;    int				flag;    int				raw;{    register UNITB		*up;    REQB			*rp;    int				errno = 0;    int				s;    /* If there is no unit block corresponding to the device number,     * wait for the system devices to be configured.  If the unit     * still cannot be found, return an error.     */    if(( up = Dev_to_unitb( dev )) == NULL  &&       ( up = mscp_check_sysdev( dev )) == NULL ) {	    errno = ENXIO;    /* If the unit is not online, start a thread to bring it online     * and wait for the thread to complete.     */    } else {	while( 1 ) {    	    s = Splscs();	    if( !up->flags.busy ) {		up->flags.busy = 1;    		( void )splx( s );		break;	    }	    else {    		( void )splx( s );		( void )sleep(( caddr_t )up, PSWP+1 );	    }	}	if( !up->flags.online ) {	    if( !up->flags.online_ip ) {		up->flags.online_ip = 1;		rp = ( REQB * )mscp_alloc_reqb( up,						NULL,						mscp_onl_states,						0,						0 );	    }	    while( up->flags.online_ip ) {		timeout( wakeup, ( caddr_t )up, 3 * hz );		( void )sleep(( caddr_t )up, PSWP+1 );		untimeout( wakeup, ( caddr_t )up );	    }	}	/* If the device is now online, bump the open count and update	 * the partition information if necessary.	 */	if( up->flags.online ) {	    up->part_mask |= ( 1 << (( raw ? 8 : 0 ) + Px( dev )));	    if( !up->part_info.pt_valid ) {		mscp_getdefpt( up->media_id, ( struct pt * )&up->part_info );		up->part_info.pt_valid = 1;		( void )rsblk( mscp_strategy,			       dev,			       ( struct pt * )&up->part_info );	    }	/* If the device could not be brought online and the NDELAY 	 * flag is not set, return an error.	 */	}	else if(( flag & O_NDELAY ) == 0 ) {	    errno = ENXIO;	}        up->flags.busy = 0;	wakeup(( caddr_t )up );    }        /* Return status to the caller.     */    return( errno );}/**//* * *   Name:	mscp_bclose - Block mode close routine * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_bclose( dev, flag )    dev_t			dev;    int				flag;{    return( mscp_close( dev, flag, 0 ));}/**//* * *   Name:	mscp_cclose - Raw (character) mode close routine * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_cclose( dev, flag )    dev_t			dev;    int				flag;{    return( mscp_close( dev, flag, 1 ));}/**//* * *   Name:	mscp_close	- Close Disk Unit * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_close(dev, flag, raw )    dev_t			dev;    int				flag;    int				raw;{    UNITB			*up;    REQB			*rp;    int				s;    struct uba_device		*ui;    /* If there is no known unit corresponding to the device     * number, return an error.     */    if(( up = Dev_to_unitb( dev )) == NULL ) {	return( ENXIO );    }    while( 1 ) {        s = Splscs();	if( !up->flags.busy ) {	    up->flags.busy = 1;    	    ( void )splx( s );	    break;	}	else {    	    ( void )splx( s );	    ( void )sleep(( caddr_t )up, PSWP+1 );	}    }    /* Overwrite default throughput constant so it reflects the     * correct number of sectors per track     */    if(up->track){	ui = up->ubdev;        if ((ui->ui_dk >= 0) && (up->track != 0))        {   /* assume 60 revs */#ifdef vax	    dk_mspw[ui->ui_dk] = 1.0 / ( 60 * up->track * 256); #else	    dk_mspw[ui->ui_dk] = ( 60 * up->track * 256); #endif	}    }    /* Reduce the open outstanding counter.  If no     * active partitions remain, and the unit is online, set the unit     * available.     */    up->part_mask &= ~( 1 << (( raw ? 8 : 0 ) + Px( dev )));    if( up->part_mask == 0 && up->flags.online ) {	up->flags.close_ip = 1;	rp = ( REQB * )mscp_alloc_reqb( up,					NULL,					mscp_avl_states,					0,					0 );	while( up->flags.close_ip ) {    	    timeout( wakeup, ( caddr_t )rp, 3 * hz );    	    ( void )sleep(( caddr_t )rp, PSWP+1 ); 	    untimeout( wakeup, ( caddr_t )rp );	}	up->part_info.pt_valid = 0;    }    up->flags.busy = 0;    wakeup(( caddr_t )up );    return( 0 );}/**//* * *   Name:	mscp_read -  * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_read( dev, uio )    dev_t		dev;    struct uio		*uio;{    register UNITB	*up;    int			status;    /* If there is no known unit corresponding to the device     * number, return an error.     */    if(( up = Dev_to_unitb( dev )) == NULL ) {	return( ENXIO );    }    /* Invoke physio to fire off the strategy routine and return     * the resulting status.     */    status = physio( mscp_strategy, &up->rawbuf, dev, B_READ, minphys, uio );    return( status );}/**//* * *   Name:	mscp_write -  * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */int mscp_write( dev, uio )    dev_t	dev;    struct	uio *uio;{    register UNITB	*up;    int			status;    /* If there is no known unit corresponding to the device     * number, return an error.     */    if(( up = Dev_to_unitb( dev )) == NULL ) {	return( ENXIO );    }    /* Invoke physio to fire off the strategy routine and return     * the resulting status.     */    status = physio( mscp_strategy, &up->rawbuf, dev, B_WRITE, minphys, uio );    return( status );}/**//* * *   Name:	mscp_ioctl	- Process I/O Control Functions * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: *//* TODO - check for possible races between get/set partition tables * and a unit becoming available or online. */intmscp_ioctl(dev, cmd, data, flag)    dev_t		dev;

⌨️ 快捷键说明

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