- sectors /= disk_parms->cyls;
- sectors /= disk_parms->heads;
- disk_parms->sectors = sectors; /* dubious on SCSI*/
- }
-
- sd->flags |= SDVALID;
- return(0);
-}
-
-/*******************************************************\
-* close the device.. only called if we are the LAST *
-* occurence of an open device *
-\*******************************************************/
-sdclose(dev)
-dev_t dev;
-{
- unsigned char unit, part;
- unsigned int old_priority;
-
- unit = UNIT(dev);
- part = PARTITION(dev);
- sd_data[unit].partflags[part] &= ~SDOPEN;
- sd_data[unit].openparts &= ~(1 << part);
- if(sd_data[unit].openparts == 0) /* if all partitions closed */
- {
- sd_prevent(unit,PR_ALLOW,SCSI_SILENT|SCSI_ERR_OK);
- }
- return(0);
-}
-
-/*******************************************************\
-* ask the scsi driver to perform a command for us. *
-* Call it through the switch table, and tell it which *
-* sub-unit we want, and what target and lu we wish to *
-* talk to. Also tell it where to find the command *
-* how long int is. *
-* Also tell it where to read/write the data, and how *
-* long the data is supposed to be *
-\*******************************************************/
-int sd_scsi_cmd(unit,scsi_cmd,cmdlen,data_addr,datalen,timeout,flags)
-
-int unit,flags;
-struct scsi_generic *scsi_cmd;
-int cmdlen;
-int timeout;
-u_char *data_addr;
-int datalen;
-{
- struct scsi_xfer *xs;
- int retval;
- int s;
- struct sd_data *sd = sd_data + unit;
-
- if(scsi_debug & PRINTROUTINES) printf("\nsd_scsi_cmd%d ",unit);
- if(sd->sc_sw) /* If we have a scsi driver */
- {
- xs = sd_get_xs(unit,flags); /* should wait unless booting */
- if(!xs)
- {
- printf("sd_scsi_cmd%d: controller busy"
- " (this should never happen)\n",unit);
- return(EBUSY);
- }
- xs->flags |= INUSE;
- /*******************************************************\
- * Fill out the scsi_xfer structure *
- \*******************************************************/
- xs->flags |= flags;
- xs->adapter = sd->ctlr;
- xs->targ = sd->targ;
- xs->lu = sd->lu;
- xs->retries = SD_RETRIES;
- xs->timeout = timeout;
- xs->cmd = scsi_cmd;
- xs->cmdlen = cmdlen;
- xs->data = data_addr;
- xs->datalen = datalen;
- xs->resid = datalen;
- xs->when_done = (flags & SCSI_NOMASK)
- ?(int (*)())0
- :sd_done;
- xs->done_arg = unit;
- xs->done_arg2 = (int)xs;
-retry: xs->error = XS_NOERROR;
- xs->bp = 0;
- retval = (*(sd->sc_sw->scsi_cmd))(xs);
- switch(retval)
- {
- case SUCCESSFULLY_QUEUED:
- s = splbio();
- while(!(xs->flags & ITSDONE))
- sleep(xs,PRIBIO+1);
- splx(s);
-
- case HAD_ERROR:
- /*printf("err = %d ",xs->error);*/
- switch(xs->error)
- {
- case XS_NOERROR:
- retval = ESUCCESS;
- break;
- case XS_SENSE:
- retval = (sd_interpret_sense(unit,xs));
- break;
- case XS_DRIVER_STUFFUP:
- retval = EIO;
- break;
- case XS_TIMEOUT:
- if(xs->retries-- )
- {
- xs->flags &= ~ITSDONE;
- goto retry;
- }
- retval = EIO;
- break;
- case XS_BUSY:
- if(xs->retries-- )
- {
- xs->flags &= ~ITSDONE;
- goto retry;
- }
- retval = EIO;
- break;
- default:
- retval = EIO;
- printf("sd%d: unknown error category from scsi driver\n"
- ,unit);
- }
- break;
- case COMPLETE:
- retval = ESUCCESS;
- break;
- case TRY_AGAIN_LATER:
- if(xs->retries-- )
- {
- xs->flags &= ~ITSDONE;
- goto retry;
- }
- retval = EIO;
- break;
- default:
- retval = EIO;
- }
- sd_free_xs(unit,xs,flags);
- sdstart(unit); /* check if anything is waiting fr the xs */
- }
- else
- {
- printf("sd%d: not set up\n",unit);
- return(EINVAL);
- }
- return(retval);
-}
-/***************************************************************\
-* Look at the returned sense and act on the error and detirmine *
-* The unix error number to pass back... (0 = report no error) *
-\***************************************************************/
-
-int sd_interpret_sense(unit,xs)
-int unit;
-struct scsi_xfer *xs;
-{
- struct scsi_sense_data *sense;
- int key;
- int silent;
-
- /***************************************************************\
- * If the flags say errs are ok, then always return ok. *
- \***************************************************************/
- if (xs->flags & SCSI_ERR_OK) return(ESUCCESS);
- silent = (xs->flags & SCSI_SILENT);
-
- sense = &(xs->sense);
- switch(sense->error_class)
- {
- case 7:
- {
- key=sense->ext.extended.sense_key;
- switch(key)
- {
- case 0x0:
- return(ESUCCESS);
- case 0x1:
- if(!silent)
- {
- printf("sd%d: soft error(corrected) ", unit);
- if(sense->valid)
- {
- printf("block no. %d (decimal)",
- (sense->ext.extended.info[0] <<24)|
- (sense->ext.extended.info[1] <<16)|
- (sense->ext.extended.info[2] <<8)|
- (sense->ext.extended.info[3] ));
- }
- printf("\n");
- }
- return(ESUCCESS);
- case 0x2:
- if(!silent)printf("sd%d: not ready\n ",
- unit);
- return(ENODEV);
- case 0x3:
- if(!silent)
- {
- printf("sd%d: medium error ", unit);
- if(sense->valid)
- {
- printf("block no. %d (decimal)",
- (sense->ext.extended.info[0] <<24)|
- (sense->ext.extended.info[1] <<16)|
- (sense->ext.extended.info[2] <<8)|
- (sense->ext.extended.info[3] ));
- }
- printf("\n");
- }
- return(EIO);
- case 0x4:
- if(!silent)printf("sd%d: non-media hardware failure\n ",
- unit);
- return(EIO);
- case 0x5:
- if(!silent)printf("sd%d: illegal request\n ",
- unit);
- return(EINVAL);
- case 0x6:
- /***********************************************\
- * If we are not open, then this is not an error *
- * as we don't have state yet. Either way, make *
- * sure that we don't have any residual state *
- \***********************************************/
- if(!silent)printf("sd%d: Unit attention.\n ", unit);
- sd_data[unit].flags &= ~(SDVALID | SDHAVELABEL);
- if (sd_data[unit].openparts)
- {
- return(EIO);
- }
- return(ESUCCESS); /* not an error if nothing's open */
- case 0x7:
- if(!silent)
- {
- printf("sd%d: attempted protection violation ",
- unit);
- if(sense->valid)
- {
- printf("block no. %d (decimal)\n",
- (sense->ext.extended.info[0] <<24)|
- (sense->ext.extended.info[1] <<16)|
- (sense->ext.extended.info[2] <<8)|
- (sense->ext.extended.info[3] ));
- }
- printf("\n");
- }
- return(EACCES);
- case 0x8:
- if(!silent)
- {
- printf("sd%d: block wrong state (worm)\n ",
- unit);
- if(sense->valid)
- {
- printf("block no. %d (decimal)\n",
- (sense->ext.extended.info[0] <<24)|
- (sense->ext.extended.info[1] <<16)|
- (sense->ext.extended.info[2] <<8)|
- (sense->ext.extended.info[3] ));
- }
- printf("\n");
- }
- return(EIO);
- case 0x9:
- if(!silent)printf("sd%d: vendor unique\n",
- unit);
- return(EIO);
- case 0xa:
- if(!silent)printf("sd%d: copy aborted\n ",
- unit);
- return(EIO);
- case 0xb:
- if(!silent)printf("sd%d: command aborted\n ",
- unit);
- return(EIO);
- case 0xc:
- if(!silent)
- {
- printf("sd%d: search returned\n ",
- unit);
- if(sense->valid)
- {
- printf("block no. %d (decimal)\n",
- (sense->ext.extended.info[0] <<24)|
- (sense->ext.extended.info[1] <<16)|
- (sense->ext.extended.info[2] <<8)|
- (sense->ext.extended.info[3] ));
- }
- printf("\n");
- }
- return(ESUCCESS);
- case 0xd:
- if(!silent)printf("sd%d: volume overflow\n ",
- unit);
- return(ENOSPC);
- case 0xe:
- if(!silent)
- {
- printf("sd%d: verify miscompare\n ",
- unit);
- if(sense->valid)
- {
- printf("block no. %d (decimal)\n",
- (sense->ext.extended.info[0] <<24)|
- (sense->ext.extended.info[1] <<16)|
- (sense->ext.extended.info[2] <<8)|
- (sense->ext.extended.info[3] ));
- }
- printf("\n");
- }
- return(EIO);
- case 0xf:
- if(!silent)printf("sd%d: unknown error key\n ",
- unit);
- return(EIO);