Exemple #1
0
void scsi_print_driverbyte(int scsiresult)
{
	int dr = (driver_byte(scsiresult) & DRIVER_MASK);
	int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4);

	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
	printk("(%s,%s) ",
	       (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"),
	       (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid"));
}
Exemple #2
0
void scsi_show_result(int result)
{
	int hb = host_byte(result);
	int db = (driver_byte(result) & DRIVER_MASK);
	int su = ((driver_byte(result) & SUGGEST_MASK) >> 4);

	printk("Result: hostbyte=%s driverbyte=%s,%s\n",
	       (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb]     : "invalid"),
	       (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"),
	       (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid"));
}
Exemple #3
0
static int do_ioctl( void )
{
	int retries = IOCTL_RETRIES;
retry:     

	the_result = -1;

	scsi_do_cmd(scsi_CDs[target].device->host_no, scsi_CDs[target].device->id,
		    (void *) sr_cmd, (void *) data_buffer, 255, sr_ioctl_done, 
		    IOCTL_TIMEOUT, (void *) sense_buffer, 0);

	while (the_result < 0) sleep_on(&sr_cmd_wait);

	if(driver_byte(the_result) != 0 && 
	   (sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
	  scsi_CDs[target].changed = 1;
	  printk("Disc change detected.\n");
	};

	if (the_result && retries)
	        {
		retries--;
		goto retry;
		}

/* Minimal error checking.  Ignore cases we know about, and report the rest. */
	if(driver_byte(the_result) != 0)
	  switch(sense_buffer[2] & 0xf) {
	  case UNIT_ATTENTION:
	    scsi_CDs[target].changed = 1;
	    printk("Disc change detected.\n");
	    break;
	  case NOT_READY: /* This happens if there is no disc in drive */
	    printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
	    break;
	  case ILLEGAL_REQUEST:
	    printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
	    break;
	  default:
	    printk("SCSI CD error: host %d id %d lun %d return code = %03x\n", 
		   scsi_CDs[target].device->host_no, 
		   scsi_CDs[target].device->id,
		   scsi_CDs[target].device->lun,
		   the_result);
	    printk("\tSense class %x, sense error %x, extended sense %x\n",
		   sense_class(sense_buffer[0]), 
		   sense_error(sense_buffer[0]),
		   sense_buffer[2] & 0xf);
	    
	};
      	return the_result;
}
static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
				 struct bio *bio)
{
	int r, ret = 0;

	/*
	 * fill in all the output members
	 */
	hdr->status = rq->errors & 0xff;
	hdr->masked_status = status_byte(rq->errors);
	hdr->msg_status = msg_byte(rq->errors);
	hdr->host_status = host_byte(rq->errors);
	hdr->driver_status = driver_byte(rq->errors);
	hdr->info = 0;
	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
	hdr->resid = rq->resid_len;
	hdr->sb_len_wr = 0;

	if (rq->sense_len && hdr->sbp) {
		int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);

		if (!copy_to_user(hdr->sbp, rq->sense, len))
			hdr->sb_len_wr = len;
		else
			ret = -EFAULT;
	}

	r = blk_rq_unmap_user(bio);
	if (!ret)
		ret = r;
	blk_put_request(rq);

	return ret;
}
Exemple #5
0
void scsi_show_result(int result)
{
	int hb = host_byte(result);
	int db = driver_byte(result);

//	printk("Result: hostbyte=%s driverbyte=%s\n",
//	       (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb]     : "invalid"),
;
}
static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
				  int timeout, int retries)
{
	struct scsi_request *sreq;
	int result;

	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));

	sreq = scsi_allocate_request(sdev, GFP_KERNEL);
	if (!sreq) {
		printk("SCSI internal ioctl failed, no memory\n");
		return -ENOMEM;
	}

	sreq->sr_data_direction = DMA_NONE;
        scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);

	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));

	if (driver_byte(sreq->sr_result)) {
		switch (sreq->sr_sense_buffer[2] & 0xf) {
		case ILLEGAL_REQUEST:
			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
				sdev->lockable = 0;
			else
				printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
			break;
		case NOT_READY:	/* This happens if there is no disc in drive */
			if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
				printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
				break;
			}
		case UNIT_ATTENTION:
			if (sdev->removable) {
				sdev->changed = 1;
				sreq->sr_result = 0;	/* This is no longer considered an error */
				break;
			}
		default:	/* Fall through for non-removable media */
			printk("SCSI error: host %d id %d lun %d return code = %x\n",
			       sdev->host->host_no,
			       sdev->id,
			       sdev->lun,
			       sreq->sr_result);
			printk("\tSense class %x, sense error %x, extended sense %x\n",
			       sense_class(sreq->sr_sense_buffer[0]),
			       sense_error(sreq->sr_sense_buffer[0]),
			       sreq->sr_sense_buffer[2] & 0xf);

		}
	}

	result = sreq->sr_result;
	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
	scsi_release_request(sreq);
	return result;
}
void scsi_show_result(int result)
{
	int hb = host_byte(result);
	int db = driver_byte(result);

	printk("Result: hostbyte=%s driverbyte=%s\n",
	       (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb]     : "invalid"),
	       (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"));
}
Exemple #8
0
static int ioctl_internal_command(Scsi_Device *dev, char * cmd,
				  int timeout, int retries)
{
    int result;
    Scsi_Cmnd * SCpnt;
    
    SCpnt = allocate_device(NULL, dev, 1);
    {
	struct semaphore sem = MUTEX_LOCKED;
	SCpnt->request.sem = &sem;
	scsi_do_cmd(SCpnt,  cmd, NULL,  0, scsi_ioctl_done,  timeout, retries);
	down(&sem);
    }
    
    if(driver_byte(SCpnt->result) != 0)
	switch(SCpnt->sense_buffer[2] & 0xf) {
	case ILLEGAL_REQUEST:
	    if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
	    else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
	    break;
	case NOT_READY: /* This happens if there is no disc in drive */
	    if(dev->removable){
		printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
		break;
	    };
	case UNIT_ATTENTION:
	    if (dev->removable){
		dev->changed = 1;
		SCpnt->result = 0; /* This is no longer considered an error */
		printk(KERN_INFO "Disc change detected.\n");
		break;
	    };
	default: /* Fall through for non-removable media */
	    printk("SCSI error: host %d id %d lun %d return code = %x\n",
		   dev->host->host_no,
		   dev->id,
		   dev->lun,
		   SCpnt->result);
	    printk("\tSense class %x, sense error %x, extended sense %x\n",
		   sense_class(SCpnt->sense_buffer[0]),
		   sense_error(SCpnt->sense_buffer[0]),
		   SCpnt->sense_buffer[2] & 0xf);
	    
	};
    
    result = SCpnt->result;
    SCpnt->request.rq_status = RQ_INACTIVE;

    if (!SCpnt->device->was_reset && SCpnt->device->scsi_request_fn)
	(*SCpnt->device->scsi_request_fn)();

    wake_up(&SCpnt->device->device_wait);
    return result;
}
static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
{
	int host, result;
	Scsi_Cmnd * SCpnt;

	host = dev->host_no;

	SCpnt = allocate_device(NULL, dev->index, 1);
	scsi_do_cmd(SCpnt,  cmd, NULL,  0,
			scsi_ioctl_done,  MAX_TIMEOUT,
			MAX_RETRIES);

	if (SCpnt->request.dev != 0xfffe){
	  SCpnt->request.waiting = current;
	  current->state = TASK_UNINTERRUPTIBLE;
	  while (SCpnt->request.dev != 0xfffe) schedule();
	};

	if(driver_byte(SCpnt->result) != 0)
	  switch(SCpnt->sense_buffer[2] & 0xf) {
	  case ILLEGAL_REQUEST:
	    if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
	    else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
	    break;
	  case NOT_READY: /* This happens if there is no disc in drive */
	    if(dev->removable){
	      printk("Device not ready.  Make sure there is a disc in the drive.\n");
	      break;
	    };
	  case UNIT_ATTENTION:
	    if (dev->removable){
	      dev->changed = 1;
	      SCpnt->result = 0; /* This is no longer considered an error */
	      printk("Disc change detected.\n");
	      break;
	    };
	  default: /* Fall through for non-removable media */
	    printk("SCSI CD error: host %d id %d lun %d return code = %x\n",
		   dev->host_no,
		   dev->id,
		   dev->lun,
		   SCpnt->result);
	    printk("\tSense class %x, sense error %x, extended sense %x\n",
		   sense_class(SCpnt->sense_buffer[0]),
		   sense_error(SCpnt->sense_buffer[0]),
		   SCpnt->sense_buffer[2] & 0xf);

	  };

	result = SCpnt->result;
	SCpnt->request.dev = -1;  /* Mark as not busy */
	wake_up(&scsi_devices[SCpnt->index].device_wait);
	return result;
}
Exemple #10
0
static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned buflength)
{
    Scsi_Cmnd * SCpnt;
    int result;

    SCpnt = allocate_device(NULL, scsi_CDs[target].device->index, 1);
    scsi_do_cmd(SCpnt,
                (void *) sr_cmd, buffer, buflength, sr_ioctl_done,
                IOCTL_TIMEOUT, IOCTL_RETRIES);


    if (SCpnt->request.dev != 0xfffe) {
        SCpnt->request.waiting = current;
        current->state = TASK_UNINTERRUPTIBLE;
        while (SCpnt->request.dev != 0xfffe) schedule();
    };

    result = SCpnt->result;

    /* Minimal error checking.  Ignore cases we know about, and report the rest. */
    if(driver_byte(result) != 0)
        switch(SCpnt->sense_buffer[2] & 0xf) {
        case UNIT_ATTENTION:
            scsi_CDs[target].device->changed = 1;
            printk("Disc change detected.\n");
            break;
        case NOT_READY: /* This happens if there is no disc in drive */
            printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
            break;
        case ILLEGAL_REQUEST:
            printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
            break;
        default:
            printk("SCSI CD error: host %d id %d lun %d return code = %03x\n",
                   scsi_CDs[target].device->host_no,
                   scsi_CDs[target].device->id,
                   scsi_CDs[target].device->lun,
                   result);
            printk("\tSense class %x, sense error %x, extended sense %x\n",
                   sense_class(SCpnt->sense_buffer[0]),
                   sense_error(SCpnt->sense_buffer[0]),
                   SCpnt->sense_buffer[2] & 0xf);

        };

    result = SCpnt->result;
    SCpnt->request.dev = -1; /* Deallocate */
    wake_up(&scsi_devices[SCpnt->index].device_wait);
    /* Wake up a process waiting for device*/
    return result;
}
Exemple #11
0
static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
{
	struct bsg_job *job = blk_mq_rq_to_pdu(rq);
	int ret = 0;

	/*
	 * The assignments below don't make much sense, but are kept for
	 * bug by bug backwards compatibility:
	 */
	hdr->device_status = job->result & 0xff;
	hdr->transport_status = host_byte(job->result);
	hdr->driver_status = driver_byte(job->result);
	hdr->info = 0;
	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
	hdr->response_len = 0;

	if (job->result < 0) {
		/* we're only returning the result field in the reply */
		job->reply_len = sizeof(u32);
		ret = job->result;
	}

	if (job->reply_len && hdr->response) {
		int len = min(hdr->max_response_len, job->reply_len);

		if (copy_to_user(uptr64(hdr->response), job->reply, len))
			ret = -EFAULT;
		else
			hdr->response_len = len;
	}

	/* we assume all request payload was transferred, residual == 0 */
	hdr->dout_resid = 0;

	if (job->bidi_rq) {
		unsigned int rsp_len = job->reply_payload.payload_len;

		if (WARN_ON(job->reply_payload_rcv_len > rsp_len))
			hdr->din_resid = 0;
		else
			hdr->din_resid = rsp_len - job->reply_payload_rcv_len;
	} else {
		hdr->din_resid = 0;
	}

	return ret;
}
Exemple #12
0
static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
				  int timeout, int retries)
{
	int result;
	struct scsi_sense_hdr sshdr;

	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));

	result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
				  &sshdr, timeout, retries);

	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", result));

	if ((driver_byte(result) & DRIVER_SENSE) &&
	    (scsi_sense_valid(&sshdr))) {
		switch (sshdr.sense_key) {
		case ILLEGAL_REQUEST:
			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
				sdev->lockable = 0;
			else
				printk(KERN_INFO "ioctl_internal_command: "
				       "ILLEGAL REQUEST asc=0x%x ascq=0x%x\n",
				       sshdr.asc, sshdr.ascq);
			break;
		case NOT_READY:	/* This happens if there is no disc in drive */
			if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
				printk(KERN_INFO "Device not ready. Make sure"
				       " there is a disc in the drive.\n");
				break;
			}
		case UNIT_ATTENTION:
			if (sdev->removable) {
				sdev->changed = 1;
				result = 0;	/* This is no longer considered an error */
				break;
			}
		default:	/* Fall through for non-removable media */
			sdev_printk(KERN_INFO, sdev,
				    "ioctl_internal_command return code = %x\n",
				    result);
			scsi_print_sense_hdr("   ", &sshdr);
			break;
		}
	}

	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
	return result;
}
static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
				  int timeout, int retries)
{
	int result;
	struct scsi_sense_hdr sshdr;

	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));

	result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
				  &sshdr, timeout, retries, NULL);

	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", result));

	if ((driver_byte(result) & DRIVER_SENSE) &&
	    (scsi_sense_valid(&sshdr))) {
		switch (sshdr.sense_key) {
		case ILLEGAL_REQUEST:
			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
				sdev->lockable = 0;
			else
				printk(KERN_INFO "ioctl_internal_command: "
				       "ILLEGAL REQUEST asc=0x%x ascq=0x%x\n",
				       sshdr.asc, sshdr.ascq);
			break;
		case NOT_READY:	
			if (sdev->removable)
				break;
		case UNIT_ATTENTION:
			if (sdev->removable) {
				sdev->changed = 1;
				result = 0;	
				break;
			}
		default:	
			sdev_printk(KERN_INFO, sdev,
				    "ioctl_internal_command return code = %x\n",
				    result);
			scsi_print_sense_hdr("   ", &sshdr);
			break;
		}
	}

	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
	return result;
}
Exemple #14
0
/**
 * Issue a REPORT ZONES scsi command.
 */
static int sd_zbc_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
			       unsigned int buflen, sector_t lba)
{
	struct scsi_device *sdp = sdkp->device;
	const int timeout = sdp->request_queue->rq_timeout;
	struct scsi_sense_hdr sshdr;
	unsigned char cmd[16];
	unsigned int rep_len;
	int result;

	memset(cmd, 0, 16);
	cmd[0] = ZBC_IN;
	cmd[1] = ZI_REPORT_ZONES;
	put_unaligned_be64(lba, &cmd[2]);
	put_unaligned_be32(buflen, &cmd[10]);
	memset(buf, 0, buflen);

	result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
				  buf, buflen, &sshdr,
				  timeout, SD_MAX_RETRIES, NULL);
	if (result) {
		sd_printk(KERN_ERR, sdkp,
			  "REPORT ZONES lba %llu failed with %d/%d\n",
			  (unsigned long long)lba,
			  host_byte(result), driver_byte(result));
		return -EIO;
	}

	rep_len = get_unaligned_be32(&buf[0]);
	if (rep_len < 64) {
		sd_printk(KERN_ERR, sdkp,
			  "REPORT ZONES report invalid length %u\n",
			  rep_len);
		return -EIO;
	}

	return 0;
}
Exemple #15
0
void scsi_print_driverbyte(int scsiresult)
{
	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
}
Exemple #16
0
int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
{
	struct scsi_device *SDev;
	struct scsi_sense_hdr sshdr;
	int result, err = 0, retries = 0;
	struct request_sense *sense = cgc->sense;

	SDev = cd->device;

	if (!sense) {
		sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
		if (!sense) {
			err = -ENOMEM;
			goto out;
		}
	}

      retry:
	if (!scsi_block_when_processing_errors(SDev)) {
		err = -ENODEV;
		goto out;
	}

	memset(sense, 0, sizeof(*sense));
	result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
			      cgc->buffer, cgc->buflen, (char *)sense,
			      cgc->timeout, IOCTL_RETRIES, 0, NULL);

	scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr);

	/* Minimal error checking.  Ignore cases we know about, and report the rest. */
	if (driver_byte(result) != 0) {
		switch (sshdr.sense_key) {
		case UNIT_ATTENTION:
			SDev->changed = 1;
			if (!cgc->quiet)
				sr_printk(KERN_INFO, cd,
					  "disc change detected.\n");
			if (retries++ < 10)
				goto retry;
			err = -ENOMEDIUM;
			break;
		case NOT_READY:	/* This happens if there is no disc in drive */
			if (sshdr.asc == 0x04 &&
			    sshdr.ascq == 0x01) {
				/* sense: Logical unit is in process of becoming ready */
				if (!cgc->quiet)
					sr_printk(KERN_INFO, cd,
						  "CDROM not ready yet.\n");
				if (retries++ < 10) {
					/* sleep 2 sec and try again */
					ssleep(2);
					goto retry;
				} else {
					/* 20 secs are enough? */
					err = -ENOMEDIUM;
					break;
				}
			}
			if (!cgc->quiet)
				sr_printk(KERN_INFO, cd,
					  "CDROM not ready.  Make sure there "
					  "is a disc in the drive.\n");
			err = -ENOMEDIUM;
			break;
		case ILLEGAL_REQUEST:
			err = -EIO;
			if (sshdr.asc == 0x20 &&
			    sshdr.ascq == 0x00)
				/* sense: Invalid command operation code */
				err = -EDRIVE_CANT_DO_THIS;
			break;
		default:
			err = -EIO;
		}
	}

	/* Wake up a process waiting for device */
      out:
	if (!cgc->sense)
		kfree(sense);
	cgc->stat = err;
	return err;
}
Exemple #17
0
/*
 * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
 * @sdev: the device to be evaluated.
 * @wait_for_transition: if nonzero, wait ALUA_FAILOVER_TIMEOUT seconds for device to exit transitioning state
 *
 * Evaluate the Target Port Group State.
 * Returns SCSI_DH_DEV_OFFLINED if the path is
 * found to be unusable.
 */
static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_for_transition)
{
	struct scsi_sense_hdr sense_hdr;
	int len, k, off, valid_states = 0;
	unsigned char *ucp;
	unsigned err, retval;
	unsigned long expiry, interval = 0;
	unsigned int tpg_desc_tbl_off;
	unsigned char orig_transition_tmo;

	if (!h->transition_tmo)
		expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT * HZ);
	else
		expiry = round_jiffies_up(jiffies + h->transition_tmo * HZ);

 retry:
	retval = submit_rtpg(sdev, h);
	if (retval) {
		if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
					  &sense_hdr)) {
			sdev_printk(KERN_INFO, sdev,
				    "%s: rtpg failed, result %d\n",
				    ALUA_DH_NAME, retval);
			if (driver_byte(retval) == DRIVER_BUSY)
				return SCSI_DH_DEV_TEMP_BUSY;
			return SCSI_DH_IO;
		}

		/*
		 * submit_rtpg() has failed on existing arrays
		 * when requesting extended header info, and
		 * the array doesn't support extended headers,
		 * even though it shouldn't according to T10.
		 * The retry without rtpg_ext_hdr_req set
		 * handles this.
		 */
		if (!(h->flags & ALUA_RTPG_EXT_HDR_UNSUPP) &&
		    sense_hdr.sense_key == ILLEGAL_REQUEST &&
		    sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) {
			h->flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
			goto retry;
		}
		/*
		 * Retry on ALUA state transition or if any
		 * UNIT ATTENTION occurred.
		 */
		if (sense_hdr.sense_key == NOT_READY &&
		    sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
			err = SCSI_DH_RETRY;
		else if (sense_hdr.sense_key == UNIT_ATTENTION)
			err = SCSI_DH_RETRY;
		if (err == SCSI_DH_RETRY && time_before(jiffies, expiry)) {
			sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n",
				    ALUA_DH_NAME);
			scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
			goto retry;
		}
		sdev_printk(KERN_ERR, sdev, "%s: rtpg failed\n",
			    ALUA_DH_NAME);
		scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
		return SCSI_DH_IO;
	}

	len = get_unaligned_be32(&h->buff[0]) + 4;

	if (len > h->bufflen) {
		/* Resubmit with the correct length */
		if (realloc_buffer(h, len)) {
			sdev_printk(KERN_WARNING, sdev,
				    "%s: kmalloc buffer failed\n",__func__);
			/* Temporary failure, bypass */
			return SCSI_DH_DEV_TEMP_BUSY;
		}
		goto retry;
	}

	orig_transition_tmo = h->transition_tmo;
	if ((h->buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR && h->buff[5] != 0)
		h->transition_tmo = h->buff[5];
	else
		h->transition_tmo = ALUA_FAILOVER_TIMEOUT;

	if (wait_for_transition && (orig_transition_tmo != h->transition_tmo)) {
		sdev_printk(KERN_INFO, sdev,
			    "%s: transition timeout set to %d seconds\n",
			    ALUA_DH_NAME, h->transition_tmo);
		expiry = jiffies + h->transition_tmo * HZ;
	}

	if ((h->buff[4] & RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR)
		tpg_desc_tbl_off = 8;
	else
		tpg_desc_tbl_off = 4;

	for (k = tpg_desc_tbl_off, ucp = h->buff + tpg_desc_tbl_off;
	     k < len;
	     k += off, ucp += off) {

		if (h->group_id == get_unaligned_be16(&ucp[2])) {
			h->state = ucp[0] & 0x0f;
			h->pref = ucp[0] >> 7;
			valid_states = ucp[1];
		}
		off = 8 + (ucp[7] * 4);
	}
Exemple #18
0
static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
				  int timeout, int retries)
{
	int result;
	Scsi_Request *SRpnt;
	Scsi_Device *SDpnt;


	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0]));
	if (NULL == (SRpnt = scsi_allocate_request(dev))) {
		printk("SCSI internal ioctl failed, no memory\n");
		return -ENOMEM;
	}

	SRpnt->sr_data_direction = SCSI_DATA_NONE;
        scsi_wait_req(SRpnt, cmd, NULL, 0, timeout, retries);

	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", SRpnt->sr_result));

	if (driver_byte(SRpnt->sr_result) != 0)
		switch (SRpnt->sr_sense_buffer[2] & 0xf) {
		case ILLEGAL_REQUEST:
			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
				dev->lockable = 0;
			else
				printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
			break;
		case NOT_READY:	/* This happens if there is no disc in drive */
			if (dev->removable && (cmd[0] != TEST_UNIT_READY)) {
				printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
				break;
			}
		case UNIT_ATTENTION:
			if (dev->removable) {
				dev->changed = 1;
				SRpnt->sr_result = 0;	/* This is no longer considered an error */
				/* gag this error, VFS will log it anyway /axboe */
				/* printk(KERN_INFO "Disc change detected.\n"); */
				break;
			};
		default:	/* Fall through for non-removable media */
			printk("SCSI error: host %d id %d lun %d return code = %x\n",
			       dev->host->host_no,
			       dev->id,
			       dev->lun,
			       SRpnt->sr_result);
			printk("\tSense class %x, sense error %x, extended sense %x\n",
			       sense_class(SRpnt->sr_sense_buffer[0]),
			       sense_error(SRpnt->sr_sense_buffer[0]),
			       SRpnt->sr_sense_buffer[2] & 0xf);

		};

	result = SRpnt->sr_result;

	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
	SDpnt = SRpnt->sr_device;
	scsi_release_request(SRpnt);
	SRpnt = NULL;

	return result;
}
void scsi_show_result(int result)
{
	printk("Result: hostbyte=0x%02x driverbyte=0x%02x\n",
	       host_byte(result), driver_byte(result));
}
Exemple #20
0
/* Convert the result to success code */
static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
{
	char *name = tape_name(STp);
	int result = SRpnt->result;
	u8 * sense = SRpnt->sense, scode;
#if DEBUG
	const char *stp;
#endif
	struct st_cmdstatus *cmdstatp;

	if (!result)
		return 0;

	cmdstatp = &STp->buffer->cmdstat;
	osst_analyze_sense(SRpnt, cmdstatp);

	if (cmdstatp->have_sense)
		scode = STp->buffer->cmdstat.sense_hdr.sense_key;
	else
		scode = 0;
#if DEBUG
	if (debugging) {
		printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
		   name, result,
		   SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
		   SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
		if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
			       	name, scode, sense[12], sense[13]);
		if (cmdstatp->have_sense)
			__scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
	}
	else
#endif
	if (cmdstatp->have_sense && (
		 scode != NO_SENSE &&
		 scode != RECOVERED_ERROR &&
/*      	 scode != UNIT_ATTENTION && */
		 scode != BLANK_CHECK &&
		 scode != VOLUME_OVERFLOW &&
		 SRpnt->cmd[0] != MODE_SENSE &&
		 SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
		if (cmdstatp->have_sense) {
			printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
			__scsi_print_sense("osst ", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
		}
		else {
			static	int	notyetprinted = 1;

			printk(KERN_WARNING
			     "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
			     name, result, driver_byte(result),
			     host_byte(result));
			if (notyetprinted) {
				notyetprinted = 0;
				printk(KERN_INFO
					"%s:I: This warning may be caused by your scsi controller,\n", name);
				printk(KERN_INFO
					"%s:I: it has been reported with some Buslogic cards.\n", name);
			}
		}
	}
	STp->pos_unknown |= STp->device->was_reset;

	if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
		STp->recover_count++;
		STp->recover_erreg++;
#if DEBUG
		if (debugging) {
			if (SRpnt->cmd[0] == READ_6)
				stp = "read";
			else if (SRpnt->cmd[0] == WRITE_6)
				stp = "write";
			else
				stp = "ioctl";
			printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
					     STp->recover_count);
		}
#endif
		if ((sense[2] & 0xe0) == 0)
			return 0;
	}
	return (-EIO);
}
static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
				  int timeout, int retries)
{
	struct scsi_request *sreq;
	int result;
	struct scsi_sense_hdr sshdr;

	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));

	sreq = scsi_allocate_request(sdev, GFP_KERNEL);
	if (!sreq) {
		printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n");
		return -ENOMEM;
	}

	sreq->sr_data_direction = DMA_NONE;
        scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);

	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));

	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
	    (scsi_request_normalize_sense(sreq, &sshdr))) {
		switch (sshdr.sense_key) {
		case ILLEGAL_REQUEST:
			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
				sdev->lockable = 0;
			else
				printk(KERN_INFO "ioctl_internal_command: "
				       "ILLEGAL REQUEST asc=0x%x ascq=0x%x\n",
				       sshdr.asc, sshdr.ascq);
			break;
		case NOT_READY:	/* This happens if there is no disc in drive */
			if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
				printk(KERN_INFO "Device not ready. Make sure"
				       " there is a disc in the drive.\n");
				break;
			}
		case UNIT_ATTENTION:
			if (sdev->removable) {
				sdev->changed = 1;
				sreq->sr_result = 0;	/* This is no longer considered an error */
				break;
			}
		default:	/* Fall through for non-removable media */
			printk(KERN_INFO "ioctl_internal_command: <%d %d %d "
			       "%d> return code = %x\n",
			       sdev->host->host_no,
			       sdev->channel,
			       sdev->id,
			       sdev->lun,
			       sreq->sr_result);
			scsi_print_req_sense("   ", sreq);
			break;
		}
	}

	result = sreq->sr_result;
	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
	scsi_release_request(sreq);
	return result;
}
Exemple #22
0
static void rw_intr (Scsi_Cmnd *SCpnt)
{
  int result = SCpnt->result;
  int this_count = SCpnt->bufflen >> 9;

#ifdef DEBUG
  printk("sd%d : rw_intr(%d, %x)\n", MINOR(SCpnt->request.dev), SCpnt->host, result);
#endif

/*
  First case : we assume that the command succeeded.  One of two things will
  happen here.  Either we will be finished, or there will be more
  sectors that we were unable to read last time.
*/

  if (!result) {

#ifdef DEBUG
    printk("sd%d : %d sectors remain.\n", MINOR(SCpnt->request.dev), SCpnt->request.nr_sectors);
    printk("use_sg is %d\n ",SCpnt->use_sg);
#endif
    if (SCpnt->use_sg) {
      struct scatterlist * sgpnt;
      int i;
      sgpnt = (struct scatterlist *) SCpnt->buffer;
      for(i=0; i<SCpnt->use_sg; i++) {
#ifdef DEBUG
	printk(":%x %x %d\n",sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
#endif
	if (sgpnt[i].alt_address) {
	  if (SCpnt->request.cmd == READ)
	    memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
	  scsi_free(sgpnt[i].address, sgpnt[i].length);
	};
      };
      scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
    } else {
      if (SCpnt->buffer != SCpnt->request.buffer) {
#ifdef DEBUG
	printk("nosg: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
		   SCpnt->bufflen);
#endif	
	  if (SCpnt->request.cmd == READ)
	    memcpy(SCpnt->request.buffer, SCpnt->buffer,
		   SCpnt->bufflen);
	  scsi_free(SCpnt->buffer, SCpnt->bufflen);
      };
    };
/*
 * 	If multiple sectors are requested in one buffer, then
 *	they will have been finished off by the first command.  If
 *	not, then we have a multi-buffer command.
 */
    if (SCpnt->request.nr_sectors > this_count)
      {
	SCpnt->request.errors = 0;
	
	if (!SCpnt->request.bh)
	  {
#ifdef DEBUG
	    printk("sd%d : handling page request, no buffer\n",
		   MINOR(SCpnt->request.dev));
#endif
/*
  The SCpnt->request.nr_sectors field is always done in 512 byte sectors,
  even if this really isn't the case.
*/
	    printk("sd.c: linked page request. (%x %x)",
		  SCpnt->request.sector, this_count);
	    panic("Aiiiiiiiiiiiieeeeeeeee");
	  }
      }
    end_scsi_request(SCpnt, 1, this_count);
    requeue_sd_request(SCpnt);
    return;
  }

/* Free up any indirection buffers we allocated for DMA purposes. */
    if (SCpnt->use_sg) {
      struct scatterlist * sgpnt;
      int i;
      sgpnt = (struct scatterlist *) SCpnt->buffer;
      for(i=0; i<SCpnt->use_sg; i++) {
#ifdef DEBUG
	printk("err: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
		   SCpnt->bufflen);
#endif
	if (sgpnt[i].alt_address) {
	  scsi_free(sgpnt[i].address, sgpnt[i].length);
	};
      };
      scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
    } else {
#ifdef DEBUG
      printk("nosgerr: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
		   SCpnt->bufflen);
#endif
      if (SCpnt->buffer != SCpnt->request.buffer)
	scsi_free(SCpnt->buffer, SCpnt->bufflen);
    };

/*
	Now, if we were good little boys and girls, Santa left us a request
	sense buffer.  We can extract information from this, so we
	can choose a block to remap, etc.
*/

        if (driver_byte(result) != 0) {
	  {
	    int i;
	    printk("Dumping sense buffer: ");
	    for(i=0;i<10;i++) printk(" %d",SCpnt->sense_buffer[i]);
	  };
Exemple #23
0
static int sg_io(struct file *file, request_queue_t *q,
		struct gendisk *bd_disk, struct sg_io_hdr *hdr)
{
	unsigned long start_time, timeout;
	int writing = 0, ret = 0;
	struct request *rq;
	char sense[SCSI_SENSE_BUFFERSIZE];
	unsigned char cmd[BLK_MAX_CDB];
	struct bio *bio;

	if (hdr->interface_id != 'S')
		return -EINVAL;
	if (hdr->cmd_len > BLK_MAX_CDB)
		return -EINVAL;
	if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len))
		return -EFAULT;
	if (verify_command(file, cmd))
		return -EPERM;

	if (hdr->dxfer_len > (q->max_hw_sectors << 9))
		return -EIO;

	if (hdr->dxfer_len)
		switch (hdr->dxfer_direction) {
		default:
			return -EINVAL;
		case SG_DXFER_TO_DEV:
			writing = 1;
			break;
		case SG_DXFER_TO_FROM_DEV:
		case SG_DXFER_FROM_DEV:
			break;
		}

	rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
	if (!rq)
		return -ENOMEM;

	/*
	 * fill in request structure
	 */
	rq->cmd_len = hdr->cmd_len;
	memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
	memcpy(rq->cmd, cmd, hdr->cmd_len);

	memset(sense, 0, sizeof(sense));
	rq->sense = sense;
	rq->sense_len = 0;

	rq->cmd_type = REQ_TYPE_BLOCK_PC;

	timeout = msecs_to_jiffies(hdr->timeout);
	rq->timeout = (timeout < INT_MAX) ? timeout : INT_MAX;
	if (!rq->timeout)
		rq->timeout = q->sg_timeout;
	if (!rq->timeout)
		rq->timeout = BLK_DEFAULT_TIMEOUT;

	if (hdr->iovec_count) {
		const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
		struct sg_iovec *iov;

		iov = kmalloc(size, GFP_KERNEL);
		if (!iov) {
			ret = -ENOMEM;
			goto out;
		}

		if (copy_from_user(iov, hdr->dxferp, size)) {
			kfree(iov);
			ret = -EFAULT;
			goto out;
		}

		ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
					  hdr->dxfer_len);
		kfree(iov);
	} else if (hdr->dxfer_len)
		ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);

	if (ret)
		goto out;

	bio = rq->bio;
	rq->retries = 0;

	start_time = jiffies;

	/* ignore return value. All information is passed back to caller
	 * (if he doesn't check that is his problem).
	 * N.B. a non-zero SCSI status is _not_ necessarily an error.
	 */
	blk_execute_rq(q, bd_disk, rq, 0);

	/* write to all output members */
	hdr->status = 0xff & rq->errors;
	hdr->masked_status = status_byte(rq->errors);
	hdr->msg_status = msg_byte(rq->errors);
	hdr->host_status = host_byte(rq->errors);
	hdr->driver_status = driver_byte(rq->errors);
	hdr->info = 0;
	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
	hdr->resid = rq->data_len;
	hdr->duration = ((jiffies - start_time) * 1000) / HZ;
	hdr->sb_len_wr = 0;

	if (rq->sense_len && hdr->sbp) {
		int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);

		if (!copy_to_user(hdr->sbp, rq->sense, len))
			hdr->sb_len_wr = len;
	}

	if (blk_rq_unmap_user(bio))
		ret = -EFAULT;

	/* may not have succeeded, but output values written to control
	 * structure (struct sg_io_hdr).  */
out:
	blk_put_request(rq);
	return ret;
}
Exemple #24
0
int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
{
	struct scsi_request *SRpnt;
	struct scsi_device *SDev;
        struct request *req;
	int result, err = 0, retries = 0;

	SDev = cd->device;
	SRpnt = scsi_allocate_request(SDev, GFP_KERNEL);
        if (!SRpnt) {
                printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl");
		err = -ENOMEM;
		goto out;
        }
	SRpnt->sr_data_direction = cgc->data_direction;

      retry:
	if (!scsi_block_when_processing_errors(SDev)) {
		err = -ENODEV;
		goto out_free;
	}

	scsi_wait_req(SRpnt, cgc->cmd, cgc->buffer, cgc->buflen,
		      cgc->timeout, IOCTL_RETRIES);

	req = SRpnt->sr_request;
	if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) {
		memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen);
		kfree(SRpnt->sr_buffer);
		SRpnt->sr_buffer = req->buffer;
        }

	result = SRpnt->sr_result;

	/* Minimal error checking.  Ignore cases we know about, and report the rest. */
	if (driver_byte(result) != 0) {
		switch (SRpnt->sr_sense_buffer[2] & 0xf) {
		case UNIT_ATTENTION:
			SDev->changed = 1;
			if (!cgc->quiet)
				printk(KERN_INFO "%s: disc change detected.\n", cd->cdi.name);
			if (retries++ < 10)
				goto retry;
			err = -ENOMEDIUM;
			break;
		case NOT_READY:	/* This happens if there is no disc in drive */
			if (SRpnt->sr_sense_buffer[12] == 0x04 &&
			    SRpnt->sr_sense_buffer[13] == 0x01) {
				/* sense: Logical unit is in process of becoming ready */
				if (!cgc->quiet)
					printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name);
				if (retries++ < 10) {
					/* sleep 2 sec and try again */
					ssleep(2);
					goto retry;
				} else {
					/* 20 secs are enough? */
					err = -ENOMEDIUM;
					break;
				}
			}
			if (!cgc->quiet)
				printk(KERN_INFO "%s: CDROM not ready.  Make sure there is a disc in the drive.\n", cd->cdi.name);
#ifdef DEBUG
			scsi_print_req_sense("sr", SRpnt);
#endif
			err = -ENOMEDIUM;
			break;
		case ILLEGAL_REQUEST:
			err = -EIO;
			if (SRpnt->sr_sense_buffer[12] == 0x20 &&
			    SRpnt->sr_sense_buffer[13] == 0x00)
				/* sense: Invalid command operation code */
				err = -EDRIVE_CANT_DO_THIS;
#ifdef DEBUG
			__scsi_print_command(cgc->cmd);
			scsi_print_req_sense("sr", SRpnt);
#endif
			break;
		default:
			printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name);
			__scsi_print_command(cgc->cmd);
			scsi_print_req_sense("sr", SRpnt);
			err = -EIO;
		}
	}

	if (cgc->sense)
		memcpy(cgc->sense, SRpnt->sr_sense_buffer, sizeof(*cgc->sense));

	/* Wake up a process waiting for device */
      out_free:
	scsi_release_request(SRpnt);
	SRpnt = NULL;
      out:
	cgc->stat = err;
	return err;
}
Exemple #25
0
static int ioctl_internal_command(Scsi_Device *dev, char * cmd,
				  int timeout, int retries)
{
    unsigned long flags;
    int result;
    Scsi_Cmnd * SCpnt;
    Scsi_Device * SDpnt;

    spin_lock_irqsave(&io_request_lock, flags);

    SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0]));
    SCpnt = scsi_allocate_device(NULL, dev, 1);
    {
	struct semaphore sem = MUTEX_LOCKED;
	SCpnt->request.sem = &sem;
	scsi_do_cmd(SCpnt,  cmd, NULL,  0, scsi_ioctl_done,  timeout, retries);
	spin_unlock_irqrestore(&io_request_lock, flags);
	down(&sem);
        spin_lock_irqsave(&io_request_lock, flags);
        SCpnt->request.sem = NULL;
    }
    
    SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", SCpnt->result));

    if(driver_byte(SCpnt->result) != 0)
	switch(SCpnt->sense_buffer[2] & 0xf) {
	case ILLEGAL_REQUEST:
	    if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
	    else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
	    break;
	case NOT_READY: /* This happens if there is no disc in drive */
	    if(dev->removable && (cmd[0] != TEST_UNIT_READY)){
		printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
		break;
	    }
	case UNIT_ATTENTION:
	    if (dev->removable){
		dev->changed = 1;
		SCpnt->result = 0; /* This is no longer considered an error */
		/* gag this error, VFS will log it anyway /axboe */
		/* printk(KERN_INFO "Disc change detected.\n"); */
		break;
	    };
	default: /* Fall through for non-removable media */
	    printk("SCSI error: host %d id %d lun %d return code = %x\n",
		   dev->host->host_no,
		   dev->id,
		   dev->lun,
		   SCpnt->result);
	    printk("\tSense class %x, sense error %x, extended sense %x\n",
		   sense_class(SCpnt->sense_buffer[0]),
		   sense_error(SCpnt->sense_buffer[0]),
		   SCpnt->sense_buffer[2] & 0xf);
	    
	};
    
    result = SCpnt->result;

    SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
    SDpnt = SCpnt->device;
    scsi_release_command(SCpnt);
    SCpnt = NULL;

    if (!SDpnt->was_reset && SDpnt->scsi_request_fn)
	(*SDpnt->scsi_request_fn)();

    wake_up(&SDpnt->device_wait);
    spin_unlock_irqrestore(&io_request_lock, flags);
    return result;
}