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

📄 rf_camlayer.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
 * 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 + -