📄 rf_camlayer.c
字号:
* in the kernel, we ignore the op. */int rf_SCSI_DoTUR( RF_DiskOp_t *op, u_char bus_id, u_char targ_id, u_char lun, dev_t dev){ int retcode = 0; #ifndef KERNEL UAGT_CAM_CCB *ua_ccb = (UAGT_CAM_CCB *) op; CCB_SCSIIO *ccb = (CCB_SCSIIO *) ua_ccb->uagt_ccb; ALL_TUR_CDB *tur = (ALL_TUR_CDB *) &(ccb->cam_cdb_io.cam_cdb_bytes[0]); ccb->cam_ch.cam_path_id = bus_id; ccb->cam_ch.cam_target_id = targ_id; ccb->cam_ch.cam_target_lun = lun; tur->lun = lun; /* allow five retries on TUR */ retcode = rf_do_scsi_op(dev, ua_ccb, "TEST UNIT READY", 5);#else /* KERNEL */ PDRV_DEVICE *pdrv_ptr; u_char sense_size; CCB_SCSIIO *ccb; pdrv_ptr = GET_PDRV_PTR(dev); sense_size = GET_SENSE_SIZE(pdrv_ptr); if ((ccb=ccmn_tur(pdrv_ptr, sense_size, (u_long) CAM_DIR_NONE, rf_done, (u_char) NULL, (u_long) 0)) == NULL) return(EIO); if (CAM_STATUS(ccb) != CAM_REQ_CMP) { printf("RAIDFRAME: TUR failure\n"); } ccmn_rem_ccb(pdrv_ptr, ccb); ccmn_rel_ccb((CCB_HEADER *) ccb); #endif /* KERNEL */ return(retcode);}#ifndef KERNEL/* * Takes a file descriptor, which should be open on * a raw disk device, and returns the maximum allowable * offset on that device. Do a binary search for said * offset. */static off_t raw_disk_len(int fd){ off_t max, min, pos, val; int i, rc; max = (off_t) ~((off_t)0x80<<((sizeof(max)-1)*CHAR_BIT)); min = 0; val = min + ((max - min) >> 1);/* XXX should this be max? */ do { pos = lseek(fd, val, SEEK_END); if (pos < 0) { max = min + ((max - min) >> 1); } else { rc = read(fd, &i, 1); if (rc == 0 || ((rc < 0) && (errno == ENOSPC))) max = val; else min = val; } val = min + ((max - min) >> 1); } while (max > min + 1); return(val+1);}#endif /* !KERNEL *//* do a READ CAPACITY and return the pertinent information in numBlk and blkSize. * bus, target, lun is actually redundant since we have dev. */int rf_SCSI_DoReadCapacity( RF_DiskOp_t *op, u_char bus_id, u_char targ_id, u_char lun, dev_t dev, RF_SectorCount_t *numBlk, int *blkSize, char *devname){ int retcode = 0;#ifndef KERNEL off_t len; int fd; UAGT_CAM_CCB *ua_ccb = (UAGT_CAM_CCB *) op; CCB_SCSIIO *ccb = (CCB_SCSIIO *) ua_ccb->uagt_ccb; DIR_READ_CAP_CDB10 *rdcap = (DIR_READ_CAP_CDB10 *) &(ccb->cam_cdb_io.cam_cdb_bytes[0]); DIR_READ_CAP_DATA *dat = (DIR_READ_CAP_DATA *) ua_ccb->uagt_buffer; ccb->cam_ch.cam_path_id = bus_id; ccb->cam_ch.cam_target_id = targ_id; ccb->cam_ch.cam_target_lun = lun; rdcap->lun = lun; retcode = rf_do_scsi_op(dev, ua_ccb, "READ CAPACITY", 0); if (retcode) return(retcode); *blkSize= rf_get_big_endian(&(dat->block_len3), 4);#if 0 *numBlk = (long) rf_get_big_endian(&(dat->lbn3), 4) - rf_protectedSectors;#endif fd = open(devname, O_RDWR); if (fd < 0) { perror(devname); return(errno); } len = raw_disk_len(fd); close(fd); *numBlk = len / (*blkSize);#else /* KERNEL */ PDRV_DEVICE *pd; DISK_SPECIFIC *dsp; DIR_READ_CAP_DATA data_buf, *dat = &data_buf; struct disklabel *label; DIR_READ_CAP_CDB10 *cdb; CCB_SCSIIO *ccb; int s, part; pd = GET_PDRV_PTR(dev); dsp = (DISK_SPECIFIC *)pd->pd_specific;#if LABELS > 0 if (dsp->ds_openpart == 0) { extern void cdisk_strategy(); part = 0; /* ??? */ cdisk_read_label(dev, pd, dsp, cdisk_strategy, part); } label = &dsp->ds_label; *blkSize = label->d_secsize; *numBlk = label->d_nsectors;#else /* LABELS > 0 */ ccb = ccmn_io_ccb_bld(pd->pd_dev, (u_char *) dat, (U32) sizeof(DIR_READ_CAP_DATA), GET_SENSE_SIZE(pd), (pd->pd_cam_flags | CAM_DIR_IN), rf_done, pd->pd_tag_action, (u_long) 0, (struct buf *)NULL); cdb = (DIR_READ_CAP_CDB10 *)ccb->cam_cdb_io.cam_cdb_bytes; cdb->opcode = DIR_READCAP_OP; ccb->cam_cdb_len = sizeof(DIR_READ_CAP_CDB10); PDRV_IPLSMP_LOCK(pd, LK_RETRY, s); (void) ccmn_send_ccb_wait(pd, (CCB_HEADER *)ccb, NOT_RETRY, PZERO); PDRV_IPLSMP_UNLOCK(pd, s); if (CAM_STATUS(ccb) != CAM_REQ_CMP) retcode = EIO; CHK_RELEASE_QUEUE(pd, ccb); ccmn_rem_ccb(pd, ccb); /* as in cdisk_read_capacity, rem is also done in rf_done. why? */ ccmn_rel_ccb((CCB_HEADER *) ccb); if (retcode) return(retcode); *numBlk = (long) rf_get_big_endian(&(dat->lbn3), 4) - rf_protectedSectors; *blkSize= rf_get_big_endian(&(dat->block_len3), 4);#endif /* LABELS > 0 */#endif /* KERNEL */ /* * Don't count the protectedSectors at the start of the disk */ *numBlk -= rf_protectedSectors; if (rf_camlayerDebug) { printf("RF_CAM: %d/%d/%d set cap to %ld blocksize %d\n", (int)bus_id, (int)targ_id, (int)lun, (long)*numBlk, (int)*blkSize); } return(0);}/* open the disk device in non-exclusive mode */int rf_SCSI_OpenUnit(dev) dev_t dev;{ int retcode = 0;#ifdef KERNEL /* from sys/conf.h, args are: major, dev, mode, flag, retcode, cred, priv */ /* cred and priv are ignored by cdisk_open */ BDEVSW_OPEN(major(dev), dev, 0, S_IFBLK, retcode, NULL, NULL);#endif /* KERNEL */ return(retcode);}#ifndef KERNEL/******************************************************************************** * When an error occurs, OSF/1 often freezes the queue associated with that device, * and refuses to do any more I/O on that device until the queue has been * explicitly unfrozen. *******************************************************************************/static void rf_release_sim_queue(ccb) CCB_SCSIIO *ccb;{ UAGT_CAM_CCB ua_ccb_sim_rel; CCB_RELSIM ccb_sim_rel; (void) bzero( (char *) &ua_ccb_sim_rel, sizeof(ua_ccb_sim_rel) ); (void) bzero( (char *) &ccb_sim_rel, sizeof(ccb_sim_rel) ); ccb_sim_rel.cam_ch.my_addr = (struct ccb_header *) &ccb_sim_rel; ccb_sim_rel.cam_ch.cam_ccb_len = sizeof(CCB_RELSIM); ccb_sim_rel.cam_ch.cam_func_code = XPT_REL_SIMQ; ccb_sim_rel.cam_ch.cam_flags = CAM_DIR_NONE; ccb_sim_rel.cam_ch.cam_path_id = ccb->cam_ch.cam_path_id; ccb_sim_rel.cam_ch.cam_target_id = ccb->cam_ch.cam_target_id; ccb_sim_rel.cam_ch.cam_target_lun= ccb->cam_ch.cam_target_lun; ua_ccb_sim_rel.uagt_ccb = (CCB_HEADER *) &ccb_sim_rel; ua_ccb_sim_rel.uagt_ccblen = sizeof(CCB_RELSIM); printf("RAIDFRAME: Releasing SIM Queue after error.\n"); if (ioctl(camfd, UAGT_CAM_IO, (caddr_t) &ua_ccb_sim_rel) < 0) { perror("Error on CAM Uagt Release SIM Queue ioctl"); RF_PANIC(); }}#endif /* KERNEL *//*************************************************************************** * * code used to print out the status of the CAM after an error * **************************************************************************/struct cam_statustable { u_char cam_status; caddr_t status_msg;} cam_statustable[] = { { CAM_REQ_INPROG, "CCB request is in progress"}, { CAM_REQ_CMP, "CCB request completed without error"}, { CAM_REQ_ABORTED, "CCB request aborted by the host"}, { CAM_UA_ABORT, "Unable to abort CCB request"}, { CAM_REQ_CMP_ERR, "CCB request completed with an error"}, { CAM_BUSY, "CAM subsystem is busy"}, { CAM_REQ_INVALID, "CCB request is invalid"}, { CAM_PATH_INVALID, "Bus ID supplied is invalid"}, { CAM_DEV_NOT_THERE, "Device not installed/there"}, { CAM_UA_TERMIO, "Unable to terminate I/O CCB req"}, { CAM_SEL_TIMEOUT, "Target selection timeout"}, { CAM_CMD_TIMEOUT, "Command timeout"}, { CAM_MSG_REJECT_REC, "Reject received"}, { CAM_SCSI_BUS_RESET, "Bus reset sent/received"}, { CAM_UNCOR_PARITY, "Parity error occurred"}, { CAM_AUTOSENSE_FAIL, "Request sense command fail"}, { CAM_NO_HBA, "No HBA detected Error"}, { CAM_DATA_RUN_ERR, "Overrun/underrun error"}, { CAM_UNEXP_BUSFREE, "Bus free"}, { CAM_SEQUENCE_FAIL, "Bus phase sequence failure"}, { CAM_CCB_LEN_ERR, "CCB length supplied is inadequate"}, { CAM_PROVIDE_FAIL, "To provide requested capability"}, { CAM_BDR_SENT, "A SCSI BDR message was sent to target"}, { CAM_REQ_TERMIO, "CCB request terminated bythe host"}, { CAM_LUN_INVALID, "LUN supplied is invalid"}, { CAM_TID_INVALID, "Target ID supplied is invalid"}, { CAM_FUNC_NOTAVAIL, "Requested function is not available"}, { CAM_NO_NEXUS, "Nexus is not established"}, { CAM_IID_INVALID, "The initiator ID is invalid"}, { CAM_CDB_RECVD, "The SCSI CDB has been received"}, { CAM_SCSI_BUSY, "SCSI bus busy"}};static int cam_statusentries = sizeof(cam_statustable) / sizeof(cam_statustable[0]);static char *rf_camstatus(u_char cam_status){ register struct cam_statustable *cst = &cam_statustable[0]; register entries; for (entries = 0; entries < cam_statusentries; entries++,cst++) { if (cst->cam_status == cam_status) return(cst->status_msg); } return("Unknown CAM Status");}static void rf_print_ccb_status(cp) CCB_HEADER *cp;{ char msgbuf[200]; sprintf(msgbuf,"cam_status = 0x%x\t (%s%s%s)\n", cp->cam_status, ((cp->cam_status & CAM_AUTOSNS_VALID) ? "Autosns valid-" : "\0"), ((cp->cam_status & CAM_SIM_QFRZN) ? "Sim Q frozen-" : "\0"), rf_camstatus(cp->cam_status & CAM_STATUS_MASK)); RF_ERRORMSG(msgbuf);}#ifndef KERNELvoid rf_SCSI_setup_rw_handle( RF_IoType_t type, void *handle, int bus, int target, int lun){ UAGT_CAM_CCB *ua_ccb = &(((CamIOHandle *) handle)->ua_ccb); CCB_SCSIIO *ccb = &(((CamIOHandle *) handle)->ccb); unsigned char *snsbuf = ((CamIOHandle *) handle)->snsBuf; DIR_READ_CDB10 *read10 = (DIR_READ_CDB10 *) &(ccb->cam_cdb_io.cam_cdb_bytes[0]); DIR_WRITE_CDB10 *writ10 = (DIR_WRITE_CDB10 *) &(ccb->cam_cdb_io.cam_cdb_bytes[0]); RF_ASSERT(RF_IO_IS_R_OR_W(type)); bzero((char *)ccb, sizeof(CCB_SCSIIO)); ccb->cam_ch.my_addr = (struct ccb_header *) ccb; ccb->cam_ch.cam_ccb_len = sizeof(CCB_SCSIIO); ccb->cam_ch.cam_func_code = XPT_SCSI_IO; ccb->cam_ch.cam_path_id = bus; ccb->cam_ch.cam_target_id = target; ccb->cam_ch.cam_target_lun = lun; ccb->cam_ch.cam_flags = (type == RF_IO_TYPE_READ) ? CAM_DIR_IN : CAM_DIR_OUT; ccb->cam_cdb_len = 10; ccb->cam_timeout = CAM_TIME_DEFAULT; ccb->cam_tag_action = CAM_SIMPLE_QTAG; ccb->cam_sense_ptr = (u_char *) snsbuf; ccb->cam_sense_len = RF_CAM_SENSEDATALEN; bzero((caddr_t) ua_ccb, sizeof(UAGT_CAM_CCB)); ua_ccb->uagt_ccb = (CCB_HEADER *) ccb; ua_ccb->uagt_ccblen = sizeof(CCB_SCSIIO); ua_ccb->uagt_snsbuf = (u_char *) snsbuf; ua_ccb->uagt_snslen = RF_CAM_SENSEDATALEN; ua_ccb->uagt_cdb = (CDB_UN *) NULL; ua_ccb->uagt_cdblen = 0; /* overkill, really */ if (type==RF_IO_TYPE_READ) { (void) bzero((char *) read10, sizeof(DIR_READ_CDB10)); read10->opcode = DIR_READ10_OP; } else { (void) bzero((char *) writ10, sizeof(DIR_WRITE_CDB10)); writ10->opcode = DIR_WRITE10_OP; }}int rf_SCSI_do_write(blockshift, handle, sectoffset, numsect, buf) int blockshift; void *handle; RF_SectorNum_t sectoffset; int numsect; char *buf;{ UAGT_CAM_CCB *ua_ccb = &(((CamIOHandle *) handle)->ua_ccb); CCB_SCSIIO *ccb = &(((CamIOHandle *) handle)->ccb); DIR_WRITE_CDB10 *writ10 = (DIR_WRITE_CDB10 *) &(ccb->cam_cdb_io.cam_cdb_bytes[0]); ccb->cam_data_ptr = (u_char *) buf; ccb->cam_dxfer_len = numsect<<blockshift; ua_ccb->uagt_buffer = (u_char *) buf; ua_ccb->uagt_buflen = numsect<<blockshift; writ10->fua = 0; writ10->lun = ccb->cam_ch.cam_target_lun; writ10->lbn3 = (sectoffset>>24)&0xFF; writ10->lbn2 = (sectoffset>>16)&0xFF; writ10->lbn1 = (sectoffset>> 8)&0xFF; writ10->lbn0 = (sectoffset )&0xFF; writ10->tran_len1 = (numsect>>8)&0xFF; writ10->tran_len0 = (numsect )&0xFF; if (ioctl(camfd, UAGT_CAM_IO, (caddr_t) ua_ccb) < 0) { perror("Error on CAM UAGT ioctl (WRITE)"); exit(1); } if (ccb->cam_ch.cam_status != CAM_REQ_CMP) { printf("RAIDFRAME: SCSI CAM error on WRITE\n"); rf_print_ccb_status( &(ccb->cam_ch) ); return(1); } return(0);}int rf_SCSI_do_read(blockshift, handle, sectoffset, numsect, buf) int blockshift; void *handle; RF_SectorNum_t sectoffset; int numsect; char *buf;{ UAGT_CAM_CCB *ua_ccb = &(((CamIOHandle *) handle)->ua_ccb); CCB_SCSIIO *ccb = &(((CamIOHandle *) handle)->ccb); DIR_READ_CDB10 *read10 = (DIR_READ_CDB10 *) &(ccb->cam_cdb_io.cam_cdb_bytes[0]); ccb->cam_data_ptr = (u_char *) buf; ccb->cam_dxfer_len = numsect<<blockshift; ua_ccb->uagt_buffer = (u_char *) buf; ua_ccb->uagt_buflen = numsect << blockshift; read10->fua = 0; read10->lun = ccb->cam_ch.cam_target_lun; read10->lbn3 = (sectoffset>>24)&0xFF; read10->lbn2 = (sectoffset>>16)&0xFF; read10->lbn1 = (sectoffset>> 8)&0xFF; read10->lbn0 = (sectoffset )&0xFF; read10->tran_len1 = (numsect>>8)&0xFF; read10->tran_len0 = (numsect )&0xFF; if (ioctl(camfd, UAGT_CAM_IO, (caddr_t) ua_ccb) < 0) { perror("Error on CAM UAGT ioctl (READ)"); exit(1); } if (ccb->cam_ch.cam_status != CAM_REQ_CMP) { printf("RAIDFRAME: SCSI CAM error on READ\n"); rf_print_ccb_status( &(ccb->cam_ch) ); return(1); } return(0);}#endif /* !KERNEL */#endif /* __osf__ */#ifdef AIX#include "rf_types.h"#include "rf_sys.h"#include "rf_ccmn.h"#include "rf_raid.h"#include "rf_general.h"#include "rf_camlayer.h"#include "rf_shutdown.h"#include "rf_options.h"int rf_ConfigureCamLayer(listp) RF_ShutdownList_t **listp;{ /* * Nothing to do here. Return success. */ return(0);}#endif /* AIX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -