📄 mscp_disk.c
字号:
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 + -