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

📄 aspi.c

📁 unix 下tar 执行程序的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  if ( (i=GetDeviceTyp( TARGET )) < 0 )  {
    ( void ) fprintf(stderr,
             "aspiinit: Can't determine type of device \"%s\"\n", tapeid);
    ( void ) fprintf(stderr,"aspiinit: GetDeviceTyp() returned errno %d\n", i);
    exit(EX_SYSTEM);
  } else if ( i != 1 )  {
    ( void ) fprintf(stderr,"aspiinit: device \"%s\" is not a streamer !\n",
                                                                   tapeid);
    ( void ) fprintf(stderr,"the typ returned by GetDeviceTyp was %d\n",i);
    exit(EX_SYSTEM);
  }

/*
 * Now get the max. and min. recordsize for the streamer
 */
  if ( (i=SCSIReadBlockLimits(TARGET, &lim, 0)) != E$NoErr )  {
    ( void ) fprintf(stderr,"aspiinit: Can't read blocklimits. errno %d\n", i);
    exit(EX_SYSTEM);
  }

/*
 * *** FIXME ***
 * I don't really know how to handle this. What I do is, check if we have
 * fixed record size (lim.max == lim.min), if this is not true, I don't
 * really know which record size I should take. For now I try 512 bytes,
 * and if 512 is not in range I try lim.min. This is probably not the
 * way to do it. Let me know if you know better.
 * chris@alderan.sdata.de
 */

  if ( lim.max == lim.min ) recsize = lim.max;
  else if ( (lim.min <= 512) && (lim.max>=512) ) recsize = 512;
  else recsize = lim.min;

  l = recsize; logrec = 0;
  while ( (l>>=1) ) ++logrec;   /* logrec = log2(recsize) */

#endif /* CTCTRL */

}

/*
 * This is the function that we call for all out aspi-requests.
 * The function simply takes our requestblock and hands it to
 * aspi() (the real aspi request function) and then it polls
 * and waits for the request to finish.
 */

int aspireq(srb)
void *srb;
{
  int cnt;

  struct _srbinquiry *s;
  s = ( struct _srbinquiry *) srb;
  aspi(s);
  cnt = 10;
  while ( cnt-- ) while ( ! s->h.status )  ;   /* POLL ! */
  if ( s->h.status == 1 ) return E$NoErr;
  return E$AspiErr;
}

/*
 * The following two commandos are supported directly by the ASPI module
 * and do not require the construction of a SCSI-CCB.
 */

int HostAdapterInquiry(inq)
aspiinquiry *inq;
{
  struct _srbinquiry *srb;
  int i;

  /* allocate a SCSI Request Block (SRB) in the lower 1 MB */

  if ( (srb=calloc(sizeof(struct _srbinquiry), 1)) == ( char *) 0 )
    return(E$NoMem);

  srb->h.cmd = 0;           /* Host Adapter Inquiry */
  srb->h.adapter = inq->adapter_num;

  /* issue the request */
  if ( (i=aspireq(srb)) )  {             /* if error status */
    free(srb);
    return(i);
  }

  inq->adapters = srb->adapters;   /* number of hostadapters */
  inq->target_id = srb->target_id;

  for(i=0; i<16; ++i) inq->manager_id[i] = srb->manager_id[i];
  inq->manager_id[16] = '\0';

  for(i=0; i<16; ++i) inq->adapter_id[i] = srb->adapter_id[i];
  inq->adapter_id[16] = '\0';

  free(srb);
  return(E$NoErr);
}

/*
 * GetDeviceTyp: The returned typ corresponds to the typ of an
 *               SCSI-Inquiry command.
 */

int GetDeviceTyp(adapter, target_id, lun)
int adapter;
int target_id;
int lun;
{
  struct _srbgettyp *srb;
  int i;

  /* allocate a SCSI Request Block (SRB) */

  if ( (srb=calloc(sizeof( struct _srbgettyp), 1)) == 0 ) return(E$NoMem);

  srb->h.cmd = 1;
  srb->h.adapter = adapter;
  srb->target_id = target_id;
  srb->lun = lun;

  /* Issue the request */
  if ( (i=aspireq(srb)) ) {
    switch ( srb->h.status )  {
    case 0x82:
      i = E$NoDevice;
      break;
    case 0x80:
      i = E$AspiInval;
      break;
    case 0x81:
      i = E$NoAdapter;
      break;
    case 0x02:
      i = E$Abort;
      break;
    }
  } else i = srb->typ;

  ( void ) free(srb);
  return(i);
}


/*
 * The ScsiIoError function is used to generate an unique errorcode
 * from the three different errorcode sources.
 * The errorcode sources are:
 *   - The exit status of the aspi request
 *   - The host adapter status
 *   - The scsi target status
 *   - The sense data structure
 *
 * Ahhmm ..... actually this makes FOUR different sources not three :-)
 * The function is local to this module and called by all the SCSI-IO
 * functions upon exit.
 */

static int ScsiIoError(aspi_status, adapter_status, target_status, sense)
int aspi_status;
int adapter_status;
int target_status;
unsigned char *sense;
{
  int i;

  switch ( aspi_status )  {   /* check the aspi status */
  case 0x82:
    i = E$NoDevice;
    break;
  case 0x80:
    i = E$AspiInval;
    break;
  case 0x81:
    i = E$NoAdapter;
    break;
  case 0x02:
    i = E$Abort;
    break;
  case 0x04:
    /*
     * Ok, this means scsi-io-error, so we see if
     * we can find more details about the error.
     */
    i = E$IOErr;
    if ( adapter_status )  {
      switch ( adapter_status )  {
      case 0x11:
	i = E$SelTimeout;
	break;
      case 0x12:
	i = E$DataOverrun;
	break;
      case 0x13:
	i = E$BusFree;
	break;
      case 0x14:
	i = E$BusFail;
	break;
      }
    } else switch ( target_status )  {
        /*
         * If the adapter didn't show any errors
         * we going to check the target to see if
         * the target was the source of the error.
         */
    case 0x08:                         
      i = E$TargetBusy;
      break;
    case 0x18:
      i = E$Reservation;
      break;
    case 0x02:
        /* 
         * Allright, the target has send
         * sense data to the sense-data allocation
         * area at the end of the srb.
	 */
      if ( sense != ( unsigned char *) 0 ) switch ( sense[2] & 0x0f )  {
      case 0x00:  /* This means "no sense", but we check for End of Medium */
        if ( sense[2] & 0x40 ) i = E$EndOfMedium;
        break;
      case 0x01:
        i = E$NoErr;/* this would be pretty stupid to report, but anyway */
	break;
      case 0x02:
	i = E$NotReady;
	break;
      case 0x03:
	i = E$Medium;
	break;
      case 0x04:
	i = E$Hardware;
	break;
      case 0x05:
	i = E$IllegalReq;
	break;
      case 0x06:
        i = E$UnitAttention;
	break;
      case 0x07:
        i = E$DataProtect;
	break;
      case 0x08:
	i = E$BlankCheck;
	break;
      case 0x0b:
	i = E$TargetAbort;
	break;
      case 0x0d:
	i = E$VolOverflow;
	break;
      }
      break;
    }
    break;
  }
  return(i);
}

int SCSIInquiry(adapter, target_id, lun, inq, sense)
int adapter;
int target_id;
int lun;
scsiinquiry far *inq;
unsigned char *sense;
{
  struct _srbio *srb;
  int i,j;

  /* allocate a SCSI Request Block (SRB) */
  if ( (srb=calloc(sizeof(struct _srbio), 1)) == 0 ) return(E$NoMem);

  srb->h.cmd = 2;
  srb->h.adapter = adapter;
  srb->h.flags = (1<<3);
  srb->target_id = target_id;
  srb->lun = lun;
  srb->buf_seg = FP_SEG(inq);
  srb->buf_off = FP_OFF(inq);
  srb->alloc_len = sizeof( scsiinquiry );
  srb->sense_len = 14;
  srb->cdb_len = 6;
  srb->ccb.inq.cmd = 0x12;
  srb->ccb.inq.lun = lun;
  srb->ccb.inq.len = sizeof( scsiinquiry );

  if ( (i=aspireq(srb)) ) {
    i = ScsiIoError(srb->h.status, srb->adapter_status,
                    srb->target_status, srb->ccb.inq.sense);
  }

  if ( sense ) for(j=0; j<14; ++j) sense[j] = srb->ccb.inq.sense[j];

  ( void ) free(srb);
  return(i);
}


int SCSIResetDevice(adapter, target_id, lun)
int adapter;
int target_id;
int lun;
{
  struct _srbreset *srb;
  int i;


  /* allocate a SCSI Request Block (SRB) */

  if ( (srb=calloc(sizeof(struct _srbreset), 1)) == 0 ) return(E$NoMem);

  srb->h.cmd = 4;
  srb->h.adapter = 0;
  srb->target_id = target_id;
  srb->lun = lun;

  if ( (i=aspireq(srb)) )
    i = ScsiIoError(srb->h.status, srb->adapter_status,
		    srb->target_status, ( unsigned char far * ) 0);

  ( void ) free (srb);
  return(i);
}

/*
 * The following commands are "Sequencial-Access Device" specific.
 */

int SCSIErase(adapter, target_id, lun, immediate, lng, sense)
int adapter;
int target_id;
int lun;
int immediate;
int lng;
unsigned char *sense;
{
  struct _srbio *srb;
  int i;

  /* allocate a SCSI Request Block (SRB) */
  if ( (srb=calloc(sizeof(struct _srbio), 1)) == 0 ) return(E$NoMem);

  srb->h.cmd = 2;
  srb->h.adapter = adapter;
  srb->target_id = target_id;
  srb->lun = lun;
  srb->sense_len = 14;
  srb->cdb_len = 6;
  srb->ccb.c6.cmd = 0x19;
  srb->ccb.c6.flag0 = lng;
  srb->ccb.c6.flag1 = immediate;
  srb->ccb.c6.lun = lun;

  if ( (i=aspireq(srb)) ) {
    if ( sense ) for(i=0; i<14; ++i) sense[i] = srb->ccb.c6.sense[i];
    i = ScsiIoError(srb->h.status, srb->adapter_status,
                    srb->target_status, srb->ccb.c6.sense);
  }

  ( void ) free(srb);

  return(i);
}


int SCSILoad(adapter, target_id, lun, immediate, load, retention, eot, sense)
int adapter;
int target_id;
int lun;
int immediate;
int load;
int retention;
int eot;
unsigned char *sense;
{
  struct _srbio *srb;
  int i;


  /* allocate a SCSI Request Block (SRB) */
  if ( (srb=calloc(sizeof(struct _srbio), 1)) == 0 ) return(E$NoMem);

  srb->h.cmd = 2;
  srb->h.adapter = adapter;
  srb->target_id = target_id;
  srb->lun = lun;
  srb->sense_len = 14;
  srb->cdb_len = 6;
  srb->ccb.ld.cmd = 0x1b;
  srb->ccb.ld.immediate = immediate;
  srb->ccb.ld.lun = lun;
  srb->ccb.ld.load = load;
  srb->ccb.ld.retention = retention;
  srb->ccb.ld.eot = eot;

  if ( (i=aspireq(srb)) )  {
    if ( sense ) for(i=0; i<14; ++i) sense[i] = srb->ccb.ld.sense[i];
    i = ScsiIoError(srb->h.status, srb->adapter_status,
                    srb->target_status, srb->ccb.ld.sense);
  }

  ( void ) free(srb);

  return(i);
}

⌨️ 快捷键说明

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