Changeset View
Standalone View
sys/dev/smartpqi/smartpqi_cam.c
/*- | /*- | ||||
* Copyright (c) 2018 Microsemi Corporation. | * Copyright (c) 2016-2019 Microsemi Corporation. | ||||
yuripv: also, s/it's/its/ ? | |||||
* Copyright (c) 2020 Microchip Technology Inc. and it's subsidiaries. | |||||
Done Inline ActionsThis could likely be just Copyright 2016-2021 Microchip Technology Inc. and it's subsidiaries. since microsemi is now owned by microchip technologies, iirc. But that's a question for your legal department. imp: This could likely be just
```
Copyright 2016-2021 Microchip Technology Inc. and it's… | |||||
* | |||||
* All rights reserved. | * All rights reserved. | ||||
Not Done Inline ActionsThese two lines likely can just be removed, unless your legal department insists on the language. In which case it should be put on the same line as each of the prior copyright line(s). imp: These two lines likely can just be removed, unless your legal department insists on the… | |||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
Context not available. | |||||
cpi->max_target = 1088; | cpi->max_target = 1088; | ||||
cpi->maxio = (softs->pqi_cap.max_sg_elem - 1) * PAGE_SIZE; | cpi->maxio = (softs->pqi_cap.max_sg_elem - 1) * PAGE_SIZE; | ||||
cpi->initiator_id = 255; | cpi->initiator_id = 255; | ||||
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); | strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN-1); | ||||
strncpy(cpi->hba_vid, "Microsemi", HBA_IDLEN); | cpi->sim_vid[sizeof(cpi->sim_vid)-1] = '\0'; | ||||
mavUnsubmitted Done Inline ActionsThere is strlcpy() to be safe without this. mav: There is strlcpy() to be safe without this. | |||||
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); | strncpy(cpi->hba_vid, "Microsemi", HBA_IDLEN-1); | ||||
cpi->hba_vid[sizeof(cpi->hba_vid)-1] = '\0'; | |||||
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN-1); | |||||
cpi->dev_name[sizeof(cpi->dev_name)-1] = '\0'; | |||||
cpi->unit_number = cam_sim_unit(sim); | cpi->unit_number = cam_sim_unit(sim); | ||||
cpi->bus_id = cam_sim_bus(sim); | cpi->bus_id = cam_sim_bus(sim); | ||||
cpi->base_transfer_speed = 1200000; /* Base bus speed in KB/sec */ | cpi->base_transfer_speed = 1200000; /* Base bus speed in KB/sec */ | ||||
Context not available. | |||||
/* | /* | ||||
* Add the target to CAM layer and rescan, when a new device is found | * Add the target to CAM layer and rescan, when a new device is found | ||||
*/ | */ | ||||
void os_add_device(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device) { | void os_add_device(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device) | ||||
union ccb *ccb; | { | ||||
union ccb *ccb; | |||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
Context not available. | |||||
} | } | ||||
xpt_async(AC_LOST_DEVICE, tmppath, NULL); | xpt_async(AC_LOST_DEVICE, tmppath, NULL); | ||||
xpt_free_path(tmppath); | xpt_free_path(tmppath); | ||||
softs->device_list[device->target][device->lun] = NULL; | |||||
pqisrc_free_device(softs, device); | pqisrc_free_device(softs, device); | ||||
} | } | ||||
Context not available. | |||||
/* | /* | ||||
* Function to release the frozen simq | * Function to release the frozen simq | ||||
*/ | */ | ||||
static void pqi_release_camq( rcb_t *rcb ) | static void pqi_release_camq(rcb_t *rcb) | ||||
mavUnsubmitted Done Inline ActionsIf you are fixing style, then according to style(9) function name should start on a new line. mav: If you are fixing style, then according to style(9) function name should start on a new line. | |||||
{ | { | ||||
pqisrc_softstate_t *softs; | pqisrc_softstate_t *softs; | ||||
struct ccb_scsiio *csio; | struct ccb_scsiio *csio; | ||||
Context not available. | |||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
/* | static void pqi_synch_request(rcb_t *rcb) | ||||
* Function to dma-unmap the completed request | |||||
*/ | |||||
static void pqi_unmap_request(void *arg) | |||||
{ | { | ||||
pqisrc_softstate_t *softs; | pqisrc_softstate_t *softs = rcb->softs; | ||||
rcb_t *rcb; | |||||
DBG_IO("IN rcb = %p\n", arg); | |||||
rcb = (rcb_t *)arg; | DBG_IO("IN rcb = %p\n", rcb); | ||||
softs = rcb->softs; | |||||
if (!(rcb->cm_flags & PQI_CMD_MAPPED)) | if (!(rcb->cm_flags & PQI_CMD_MAPPED)) | ||||
return; | return; | ||||
Context not available. | |||||
if(rcb->sgt && rcb->nseg) | if(rcb->sgt && rcb->nseg) | ||||
os_mem_free(rcb->softs, (void*)rcb->sgt, | os_mem_free(rcb->softs, (void*)rcb->sgt, | ||||
rcb->nseg*sizeof(sgt_t)); | rcb->nseg*sizeof(sgt_t)); | ||||
DBG_IO("OUT\n"); | |||||
} | |||||
/* | |||||
* Function to dma-unmap the completed request | |||||
*/ | |||||
static inline void pqi_unmap_request(rcb_t *rcb) | |||||
{ | |||||
DBG_IO("IN rcb = %p\n", rcb); | |||||
pqisrc_put_tag(&softs->taglist, rcb->tag); | pqi_synch_request(rcb); | ||||
pqisrc_put_tag(&rcb->softs->taglist, rcb->tag); | |||||
DBG_IO("OUT\n"); | DBG_IO("OUT\n"); | ||||
} | } | ||||
Context not available. | |||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (pqisrc_ctrl_offline(softs)) | |||||
return; | |||||
cdb = (csio->ccb_h.flags & CAM_CDB_POINTER) ? | cdb = (csio->ccb_h.flags & CAM_CDB_POINTER) ? | ||||
(uint8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes; | (uint8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes; | ||||
if(cdb[0] == INQUIRY && | if(cdb[0] == INQUIRY && | ||||
(cdb[1] & SI_EVPD) == 0 && | (cdb[1] & SI_EVPD) == 0 && | ||||
(csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN && | (csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN && | ||||
csio->dxfer_len >= SHORT_INQUIRY_LENGTH) { | csio->dxfer_len >= SHORT_INQUIRY_LENGTH) { | ||||
Context not available. | |||||
return; | return; | ||||
} | } | ||||
strncpy(inq->vendor, "MSCC", | strncpy(inq->vendor, device->vendor, | ||||
SID_VENDOR_SIZE); | SID_VENDOR_SIZE-1); | ||||
strncpy(inq->product, | inq->vendor[sizeof(inq->vendor)-1] = '\0'; | ||||
mavUnsubmitted Done Inline ActionsI was going to mention strlcpy() again, but IIRC strings in SCSI INQUIRY are not required to be NULL-terminated, so strncpy() should be just fine there. mav: I was going to mention strlcpy() again, but IIRC strings in SCSI INQUIRY are not required to be… | |||||
pqisrc_raidlevel_to_string(device->raid_level), | strncpy(inq->product, | ||||
SID_PRODUCT_SIZE); | pqisrc_raidlevel_to_string(device->raid_level), | ||||
SID_PRODUCT_SIZE-1); | |||||
inq->product[sizeof(inq->product)-1] = '\0'; | |||||
strncpy(inq->revision, device->volume_offline?"OFF":"OK", | strncpy(inq->revision, device->volume_offline?"OFF":"OK", | ||||
SID_REVISION_SIZE); | SID_REVISION_SIZE-1); | ||||
inq->revision[sizeof(inq->revision)-1] = '\0'; | |||||
} | } | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
static void pqi_complete_scsi_io(struct ccb_scsiio *csio, rcb_t *rcb) | |||||
{ | |||||
uint32_t release_tag; | |||||
pqisrc_softstate_t *softs = rcb->softs; | |||||
DBG_IO("IN scsi io = %p\n", csio); | |||||
pqi_synch_request(rcb); | |||||
smartpqi_fix_ld_inquiry(rcb->softs, csio); | |||||
pqi_release_camq(rcb); | |||||
release_tag = rcb->tag; | |||||
os_reset_rcb(rcb); | |||||
pqisrc_put_tag(&softs->taglist, release_tag); | |||||
xpt_done((union ccb *)csio); | |||||
DBG_FUNC("OUT\n"); | |||||
} | |||||
/* | /* | ||||
* Handle completion of a command - pass results back through the CCB | * Handle completion of a command - pass results back through the CCB | ||||
*/ | */ | ||||
void | void os_io_response_success(rcb_t *rcb) | ||||
os_io_response_success(rcb_t *rcb) | |||||
{ | { | ||||
struct ccb_scsiio *csio; | struct ccb_scsiio *csio; | ||||
DBG_IO("IN rcb = %p\n", rcb); | DBG_IO("IN rcb = %p\n", rcb); | ||||
if (rcb == NULL) | if (rcb == NULL) | ||||
panic("rcb is null"); | panic("rcb is null"); | ||||
csio = (struct ccb_scsiio *)&rcb->cm_ccb->csio; | csio = (struct ccb_scsiio *)&rcb->cm_ccb->csio; | ||||
if (csio == NULL) | if (csio == NULL) | ||||
panic("csio is null"); | panic("csio is null"); | ||||
rcb->status = REQUEST_SUCCESS; | rcb->status = REQUEST_SUCCESS; | ||||
csio->ccb_h.status = CAM_REQ_CMP; | csio->ccb_h.status = CAM_REQ_CMP; | ||||
smartpqi_fix_ld_inquiry(rcb->softs, csio); | pqi_complete_scsi_io(csio, rcb); | ||||
pqi_release_camq(rcb); | |||||
pqi_unmap_request(rcb); | DBG_IO("OUT\n"); | ||||
xpt_done((union ccb *)csio); | } | ||||
static void copy_sense_data_to_csio(struct ccb_scsiio *csio, | |||||
uint8_t *sense_data, uint16_t sense_data_len) | |||||
{ | |||||
DBG_IO("IN csio = %p\n", csio); | |||||
memset(&csio->sense_data, 0, csio->sense_len); | |||||
sense_data_len = (sense_data_len > csio->sense_len) ? | |||||
csio->sense_len : sense_data_len; | |||||
if (sense_data) | |||||
memcpy(&csio->sense_data, sense_data, sense_data_len); | |||||
if (csio->sense_len > sense_data_len) | |||||
csio->sense_resid = csio->sense_len - sense_data_len; | |||||
else | |||||
csio->sense_resid = 0; | |||||
DBG_IO("OUT\n"); | DBG_IO("OUT\n"); | ||||
} | } | ||||
Context not available. | |||||
softs = rcb->softs; | softs = rcb->softs; | ||||
ASSERT(err_info != NULL); | |||||
csio->scsi_status = err_info->status; | |||||
csio->ccb_h.status = CAM_REQ_CMP_ERR; | csio->ccb_h.status = CAM_REQ_CMP_ERR; | ||||
if (!err_info || !rcb->dvp) { | |||||
DBG_ERR("couldn't be accessed! error info = %p, rcb->dvp = %p\n", | |||||
err_info, rcb->dvp); | |||||
goto error_out; | |||||
} | |||||
csio->scsi_status = err_info->status; | |||||
if (csio->ccb_h.func_code == XPT_SCSI_IO) { | if (csio->ccb_h.func_code == XPT_SCSI_IO) { | ||||
/* | /* | ||||
* Handle specific SCSI status values. | * Handle specific SCSI status values. | ||||
Context not available. | |||||
switch(csio->scsi_status) { | switch(csio->scsi_status) { | ||||
case PQI_RAID_STATUS_QUEUE_FULL: | case PQI_RAID_STATUS_QUEUE_FULL: | ||||
csio->ccb_h.status = CAM_REQ_CMP; | csio->ccb_h.status = CAM_REQ_CMP; | ||||
DBG_ERR("Queue Full error"); | DBG_ERR("Queue Full error\n"); | ||||
break; | break; | ||||
/* check condition, sense data included */ | /* check condition, sense data included */ | ||||
case PQI_RAID_STATUS_CHECK_CONDITION: | case PQI_RAID_STATUS_CHECK_CONDITION: | ||||
{ | { | ||||
uint16_t sense_data_len = | uint16_t sense_data_len = | ||||
LE_16(err_info->sense_data_len); | LE_16(err_info->sense_data_len); | ||||
uint8_t *sense_data = NULL; | uint8_t *sense_data = NULL; | ||||
if (sense_data_len) | if (sense_data_len) | ||||
sense_data = err_info->data; | sense_data = err_info->data; | ||||
memset(&csio->sense_data, 0, csio->sense_len); | copy_sense_data_to_csio(csio, sense_data, sense_data_len); | ||||
sense_data_len = (sense_data_len > | csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | ||||
csio->sense_len) ? | |||||
csio->sense_len : | |||||
sense_data_len; | |||||
if (sense_data) | |||||
memcpy(&csio->sense_data, sense_data, | |||||
sense_data_len); | |||||
if (csio->sense_len > sense_data_len) | |||||
csio->sense_resid = csio->sense_len | |||||
- sense_data_len; | |||||
else | |||||
csio->sense_resid = 0; | |||||
csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | |||||
| CAM_AUTOSNS_VALID | | CAM_AUTOSNS_VALID | ||||
| CAM_REQ_CMP_ERR; | | CAM_REQ_CMP_ERR; | ||||
Context not available. | |||||
case PQI_RAID_DATA_IN_OUT_UNDERFLOW: | case PQI_RAID_DATA_IN_OUT_UNDERFLOW: | ||||
{ | { | ||||
uint32_t resid = 0; | uint32_t resid = 0; | ||||
resid = rcb->bcount-err_info->data_out_transferred; | resid = rcb->bcount-err_info->data_out_transferred; | ||||
csio->resid = resid; | csio->resid = resid; | ||||
csio->ccb_h.status = CAM_REQ_CMP; | csio->ccb_h.status = CAM_REQ_CMP; | ||||
break; | |||||
} | } | ||||
break; | |||||
default: | default: | ||||
csio->ccb_h.status = CAM_REQ_CMP; | csio->ccb_h.status = CAM_REQ_CMP; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (softs->os_specific.pqi_flags & PQI_FLAG_BUSY) { | error_out: | ||||
softs->os_specific.pqi_flags &= ~PQI_FLAG_BUSY; | pqi_complete_scsi_io(csio, rcb); | ||||
if (csio->ccb_h.status & CAM_RELEASE_SIMQ) | |||||
xpt_release_simq(xpt_path_sim(csio->ccb_h.path), 0); | |||||
else | |||||
csio->ccb_h.status |= CAM_RELEASE_SIMQ; | |||||
} | |||||
pqi_unmap_request(rcb); | |||||
xpt_done((union ccb *)csio); | |||||
DBG_IO("OUT\n"); | DBG_IO("OUT\n"); | ||||
} | } | ||||
/* | /* | ||||
* Error response handling for aio. | * Error response handling for aio. | ||||
*/ | */ | ||||
Context not available. | |||||
DBG_IO("IN\n"); | DBG_IO("IN\n"); | ||||
if (rcb == NULL) | if (rcb == NULL) | ||||
panic("rcb is null"); | panic("rcb is null"); | ||||
rcb->status = REQUEST_SUCCESS; | rcb->status = REQUEST_SUCCESS; | ||||
Context not available. | |||||
softs = rcb->softs; | softs = rcb->softs; | ||||
if (!err_info || !rcb->dvp) { | |||||
csio->ccb_h.status = CAM_REQ_CMP_ERR; | |||||
DBG_ERR("couldn't be accessed! error info = %p, rcb->dvp = %p\n", | |||||
err_info, rcb->dvp); | |||||
goto error_out; | |||||
} | |||||
switch (err_info->service_resp) { | switch (err_info->service_resp) { | ||||
case PQI_AIO_SERV_RESPONSE_COMPLETE: | case PQI_AIO_SERV_RESPONSE_COMPLETE: | ||||
csio->ccb_h.status = err_info->status; | csio->ccb_h.status = err_info->status; | ||||
Context not available. | |||||
break; | break; | ||||
case PQI_AIO_STATUS_AIO_PATH_DISABLED: | case PQI_AIO_STATUS_AIO_PATH_DISABLED: | ||||
DBG_WARN_BTL(rcb->dvp,"AIO Path Disabled\n"); | DBG_WARN_BTL(rcb->dvp,"AIO Path Disabled\n"); | ||||
/* Timed out TMF response comes here */ | |||||
if (rcb->tm_req) { | |||||
rcb->req_pending = false; | |||||
rcb->status = REQUEST_SUCCESS; | |||||
DBG_ERR("AIO Disabled for TMF\n"); | |||||
return; | |||||
} | |||||
rcb->dvp->aio_enabled = false; | |||||
rcb->dvp->offload_enabled = false; | rcb->dvp->offload_enabled = false; | ||||
csio->ccb_h.status |= CAM_REQUEUE_REQ; | csio->ccb_h.status |= CAM_REQUEUE_REQ; | ||||
break; | break; | ||||
Context not available. | |||||
break; | break; | ||||
case PQI_AIO_SERV_RESPONSE_TMF_COMPLETE: | case PQI_AIO_SERV_RESPONSE_TMF_COMPLETE: | ||||
case PQI_AIO_SERV_RESPONSE_TMF_SUCCEEDED: | case PQI_AIO_SERV_RESPONSE_TMF_SUCCEEDED: | ||||
csio->ccb_h.status = CAM_REQ_CMP; | DBG_ERR("PQI_AIO_SERV_RESPONSE_TMF %s\n", | ||||
break; | (err_info->service_resp == PQI_AIO_SERV_RESPONSE_TMF_COMPLETE) ? "COMPLETE" : "SUCCEEDED"); | ||||
rcb->status = REQUEST_SUCCESS; | |||||
rcb->req_pending = false; | |||||
return; | |||||
case PQI_AIO_SERV_RESPONSE_TMF_REJECTED: | case PQI_AIO_SERV_RESPONSE_TMF_REJECTED: | ||||
case PQI_AIO_SERV_RESPONSE_TMF_INCORRECT_LUN: | case PQI_AIO_SERV_RESPONSE_TMF_INCORRECT_LUN: | ||||
DBG_WARN_BTL(rcb->dvp,"TMF rejected/Incorrect Lun\n"); | DBG_ERR("PQI_AIO_SERV_RESPONSE_TMF %s\n", | ||||
csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; | (err_info->service_resp == PQI_AIO_SERV_RESPONSE_TMF_REJECTED) ? "REJECTED" : "INCORRECT LUN"); | ||||
break; | rcb->status = REQUEST_FAILED; | ||||
rcb->req_pending = false; | |||||
return; | |||||
default: | default: | ||||
DBG_WARN_BTL(rcb->dvp,"Scsi Status Error\n"); | DBG_WARN_BTL(rcb->dvp,"Scsi Status Error\n"); | ||||
csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; | csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; | ||||
break; | break; | ||||
} | } | ||||
if(err_info->data_pres == DATA_PRESENT_SENSE_DATA ) { | if(err_info->data_pres == DATA_PRESENT_SENSE_DATA ) { | ||||
csio->scsi_status = PQI_AIO_STATUS_CHECK_CONDITION; | csio->scsi_status = PQI_AIO_STATUS_CHECK_CONDITION; | ||||
uint8_t *sense_data = NULL; | uint8_t *sense_data = NULL; | ||||
Context not available. | |||||
sense_data = err_info->data; | sense_data = err_info->data; | ||||
DBG_ERR_BTL(rcb->dvp, "SCSI_STATUS_CHECK_COND sense size %u\n", | DBG_ERR_BTL(rcb->dvp, "SCSI_STATUS_CHECK_COND sense size %u\n", | ||||
sense_data_len); | sense_data_len); | ||||
memset(&csio->sense_data, 0, csio->sense_len); | copy_sense_data_to_csio(csio, sense_data, sense_data_len); | ||||
if (sense_data) | |||||
memcpy(&csio->sense_data, sense_data, ((sense_data_len > | |||||
csio->sense_len) ? csio->sense_len : sense_data_len)); | |||||
if (csio->sense_len > sense_data_len) | |||||
csio->sense_resid = csio->sense_len - sense_data_len; | |||||
else | |||||
csio->sense_resid = 0; | |||||
csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; | csio->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; | ||||
} | } | ||||
smartpqi_fix_ld_inquiry(softs, csio); | error_out: | ||||
pqi_release_camq(rcb); | pqi_complete_scsi_io(csio, rcb); | ||||
pqi_unmap_request(rcb); | |||||
xpt_done((union ccb *)csio); | |||||
DBG_IO("OUT\n"); | DBG_IO("OUT\n"); | ||||
} | } | ||||
static void | static void pqi_freeze_ccb(union ccb *ccb) | ||||
mavUnsubmitted Done Inline ActionsI suppose this is your local style and consistency within a file is good, but for note this change contradicts FreeBSD style(9). mav: I suppose this is your local style and consistency within a file is good, but for note this… | |||||
pqi_freeze_ccb(union ccb *ccb) | |||||
{ | { | ||||
if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { | if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { | ||||
ccb->ccb_h.status |= CAM_DEV_QFRZN; | ccb->ccb_h.status |= CAM_DEV_QFRZN; | ||||
Context not available. | |||||
static void | static void | ||||
pqi_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) | pqi_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) | ||||
{ | { | ||||
pqisrc_softstate_t *softs; | rcb_t *rcb = (rcb_t *)arg; | ||||
rcb_t *rcb; | pqisrc_softstate_t *softs = rcb->softs; | ||||
union ccb *ccb; | |||||
rcb = (rcb_t *)arg; | |||||
softs = rcb->softs; | |||||
if( error || nseg > softs->pqi_cap.max_sg_elem ) | if(error || nseg > softs->pqi_cap.max_sg_elem) | ||||
mavUnsubmitted Done Inline ActionsIf you are fixing style, there should be a space after "if". mav: If you are fixing style, there should be a space after "if". | |||||
{ | { | ||||
rcb->cm_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; | DBG_ERR_BTL(rcb->dvp, "map failed err = %d or nseg(%d) > sgelem(%d)\n", | ||||
pqi_freeze_ccb(rcb->cm_ccb); | |||||
DBG_ERR_BTL(rcb->dvp, "map failed err = %d or nseg(%d) > sgelem(%d)\n", | |||||
error, nseg, softs->pqi_cap.max_sg_elem); | error, nseg, softs->pqi_cap.max_sg_elem); | ||||
pqi_unmap_request(rcb); | goto error_io; | ||||
xpt_done((union ccb *)rcb->cm_ccb); | |||||
return; | |||||
} | } | ||||
rcb->sgt = os_mem_alloc(softs, nseg * sizeof(rcb_t)); | rcb->sgt = os_mem_alloc(softs, nseg * sizeof(sgt_t)); | ||||
if (rcb->sgt == NULL) { | |||||
rcb->cm_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; | if (!rcb->sgt) { | ||||
pqi_freeze_ccb(rcb->cm_ccb); | |||||
DBG_ERR_BTL(rcb->dvp, "os_mem_alloc() failed; nseg = %d\n", nseg); | DBG_ERR_BTL(rcb->dvp, "os_mem_alloc() failed; nseg = %d\n", nseg); | ||||
pqi_unmap_request(rcb); | goto error_io; | ||||
xpt_done((union ccb *)rcb->cm_ccb); | |||||
return; | |||||
} | } | ||||
rcb->nseg = nseg; | rcb->nseg = nseg; | ||||
Context not available. | |||||
if (error) { | if (error) { | ||||
rcb->req_pending = false; | rcb->req_pending = false; | ||||
rcb->cm_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; | |||||
pqi_freeze_ccb(rcb->cm_ccb); | |||||
DBG_ERR_BTL(rcb->dvp, "Build IO failed, error = %d\n", error); | DBG_ERR_BTL(rcb->dvp, "Build IO failed, error = %d\n", error); | ||||
pqi_unmap_request(rcb); | } else { | ||||
xpt_done((union ccb *)rcb->cm_ccb); | /* Successfully IO was submitted to the device. */ | ||||
return; | return; | ||||
} | } | ||||
error_io: | |||||
ccb = rcb->cm_ccb; | |||||
ccb->ccb_h.status = CAM_RESRC_UNAVAIL; | |||||
pqi_freeze_ccb(ccb); | |||||
pqi_unmap_request(rcb); | |||||
xpt_done(ccb); | |||||
return; | |||||
} | } | ||||
/* | /* | ||||
* Function to dma-map the request buffer | * Function to dma-map the request buffer | ||||
*/ | */ | ||||
static int pqi_map_request( rcb_t *rcb ) | static int pqi_map_request(rcb_t *rcb) | ||||
{ | { | ||||
pqisrc_softstate_t *softs = rcb->softs; | pqisrc_softstate_t *softs = rcb->softs; | ||||
int error = PQI_STATUS_SUCCESS; | int bsd_error, pqi_error; | ||||
union ccb *ccb = rcb->cm_ccb; | union ccb *ccb = rcb->cm_ccb; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
/* check that mapping is necessary */ | /* check that mapping is necessary */ | ||||
if (rcb->cm_flags & PQI_CMD_MAPPED) | if (rcb->cm_flags & PQI_CMD_MAPPED) | ||||
return(0); | return BSD_SUCCESS; | ||||
rcb->cm_flags |= PQI_CMD_MAPPED; | rcb->cm_flags |= PQI_CMD_MAPPED; | ||||
if (rcb->bcount) { | if (rcb->bcount) { | ||||
error = bus_dmamap_load_ccb(softs->os_specific.pqi_buffer_dmat, | bsd_error = bus_dmamap_load_ccb(softs->os_specific.pqi_buffer_dmat, | ||||
rcb->cm_datamap, ccb, pqi_request_map_helper, rcb, 0); | rcb->cm_datamap, ccb, pqi_request_map_helper, rcb, 0); | ||||
if (error != 0){ | if (bsd_error != BSD_SUCCESS && bsd_error != EINPROGRESS) { | ||||
DBG_ERR_BTL(rcb->dvp, "bus_dmamap_load_ccb failed = %d count = %d\n", | DBG_ERR_BTL(rcb->dvp, "bus_dmamap_load_ccb failed, return status = %d transfer length = %d\n", | ||||
error, rcb->bcount); | bsd_error, rcb->bcount); | ||||
return error; | return bsd_error; | ||||
} | } | ||||
} else { | } else { | ||||
/* | /* | ||||
Context not available. | |||||
/* Call IO functions depending on pd or ld */ | /* Call IO functions depending on pd or ld */ | ||||
rcb->status = REQUEST_PENDING; | rcb->status = REQUEST_PENDING; | ||||
error = pqisrc_build_send_io(softs, rcb); | pqi_error = pqisrc_build_send_io(softs, rcb); | ||||
bsd_error = pqi_error_to_bsd_error(pqi_error); | |||||
} | } | ||||
DBG_FUNC("OUT error = %d\n", error); | DBG_FUNC("OUT error = %d\n", bsd_error); | ||||
return error; | return bsd_error; | ||||
} | } | ||||
/* | /* | ||||
* Function to clear the request control block | * Function to clear the request control block | ||||
*/ | */ | ||||
void os_reset_rcb( rcb_t *rcb ) | void os_reset_rcb(rcb_t *rcb) | ||||
{ | { | ||||
rcb->error_info = NULL; | rcb->error_info = NULL; | ||||
rcb->req = NULL; | rcb->req = NULL; | ||||
Context not available. | |||||
rcb->softs = NULL; | rcb->softs = NULL; | ||||
rcb->cm_flags = 0; | rcb->cm_flags = 0; | ||||
rcb->cm_data = NULL; | rcb->cm_data = NULL; | ||||
rcb->bcount = 0; | rcb->bcount = 0; | ||||
rcb->nseg = 0; | rcb->nseg = 0; | ||||
rcb->sgt = NULL; | rcb->sgt = NULL; | ||||
rcb->cm_ccb = NULL; | rcb->cm_ccb = NULL; | ||||
Context not available. | |||||
rcb->ioaccel_handle = 0; | rcb->ioaccel_handle = 0; | ||||
rcb->resp_qid = 0; | rcb->resp_qid = 0; | ||||
rcb->req_pending = false; | rcb->req_pending = false; | ||||
rcb->tm_req = false; | |||||
} | } | ||||
/* | /* | ||||
Context not available. | |||||
/* | /* | ||||
* Function to rescan the lun | * Function to rescan the lun | ||||
*/ | */ | ||||
static void smartpqi_lun_rescan(struct pqisrc_softstate *softs, int target, | static void smartpqi_lun_rescan(struct pqisrc_softstate *softs, int target, | ||||
int lun) | int lun) | ||||
{ | { | ||||
union ccb *ccb = NULL; | union ccb *ccb = NULL; | ||||
cam_status status = 0; | cam_status status = 0; | ||||
struct cam_path *path = NULL; | struct cam_path *path = NULL; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
ccb = xpt_alloc_ccb_nowait(); | ccb = xpt_alloc_ccb_nowait(); | ||||
if (ccb == NULL) { | |||||
DBG_ERR("Unable to alloc ccb for lun rescan\n"); | |||||
return; | |||||
} | |||||
status = xpt_create_path(&path, NULL, | status = xpt_create_path(&path, NULL, | ||||
cam_sim_path(softs->os_specific.sim), target, lun); | cam_sim_path(softs->os_specific.sim), target, lun); | ||||
if (status != CAM_REQ_CMP) { | if (status != CAM_REQ_CMP) { | ||||
Context not available. | |||||
/* | /* | ||||
* Set the mode of tagged command queueing for the current task. | * Set the mode of tagged command queueing for the current task. | ||||
*/ | */ | ||||
uint8_t os_get_task_attr(rcb_t *rcb) | uint8_t os_get_task_attr(rcb_t *rcb) | ||||
{ | { | ||||
union ccb *ccb = rcb->cm_ccb; | union ccb *ccb = rcb->cm_ccb; | ||||
uint8_t tag_action = SOP_TASK_ATTRIBUTE_SIMPLE; | uint8_t tag_action = SOP_TASK_ATTRIBUTE_SIMPLE; | ||||
Context not available. | |||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
for (tag = 1; tag < softs->max_outstanding_io; tag++) { | for (tag = 1; tag <= softs->max_outstanding_io; tag++) { | ||||
rcb_t *prcb = &softs->rcb[tag]; | rcb_t *prcb = &softs->rcb[tag]; | ||||
if(prcb->req_pending && prcb->cm_ccb ) { | if(prcb->req_pending && prcb->cm_ccb ) { | ||||
prcb->req_pending = false; | prcb->req_pending = false; | ||||
prcb->cm_ccb->ccb_h.status = CAM_REQ_ABORTED | CAM_REQ_CMP; | prcb->cm_ccb->ccb_h.status = CAM_REQ_ABORTED | CAM_REQ_CMP; | ||||
xpt_done((union ccb *)prcb->cm_ccb); | pqisrc_decrement_device_active_io(softs, prcb); | ||||
prcb->cm_ccb = NULL; | pqi_complete_scsi_io(&prcb->cm_ccb->csio, prcb); | ||||
} | } | ||||
} | } | ||||
Context not available. | |||||
uint32_t tag, no_transfer = 0; | uint32_t tag, no_transfer = 0; | ||||
pqisrc_softstate_t *softs = (struct pqisrc_softstate *) | pqisrc_softstate_t *softs = (struct pqisrc_softstate *) | ||||
cam_sim_softc(sim); | cam_sim_softc(sim); | ||||
int32_t error = PQI_STATUS_FAILURE; | int32_t error = BSD_FAILURE; | ||||
pqi_scsi_dev_t *dvp; | pqi_scsi_dev_t *dvp; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if( softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun] == NULL ) { | if( softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun] == NULL ) { | ||||
ccb->ccb_h.status = CAM_DEV_NOT_THERE; | ccb->ccb_h.status = CAM_DEV_NOT_THERE; | ||||
DBG_INFO("Device = %d not there\n", ccb->ccb_h.target_id); | DBG_INFO("Device = %d not there\n", ccb->ccb_h.target_id); | ||||
return PQI_STATUS_FAILURE; | return error; | ||||
} | } | ||||
dvp = softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun]; | dvp = softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun]; | ||||
Context not available. | |||||
return error; | return error; | ||||
} | } | ||||
/* Check device reset */ | /* Check device reset */ | ||||
if (dvp->reset_in_progress) { | if (DEVICE_RESET(dvp)) { | ||||
ccb->ccb_h.status = CAM_SCSI_BUSY | CAM_REQ_INPROG | CAM_BUSY; | ccb->ccb_h.status = CAM_SCSI_BUSY | CAM_REQ_INPROG | CAM_BUSY; | ||||
DBG_WARN("Device %d reset returned busy\n", ccb->ccb_h.target_id); | DBG_WARN("Device %d reset returned busy\n", ccb->ccb_h.target_id); | ||||
return error; | return error; | ||||
Context not available. | |||||
xpt_freeze_simq(softs->os_specific.sim, 1); | xpt_freeze_simq(softs->os_specific.sim, 1); | ||||
softs->os_specific.pqi_flags |= PQI_FLAG_BUSY; | softs->os_specific.pqi_flags |= PQI_FLAG_BUSY; | ||||
ccb->ccb_h.status |= (CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ); | ccb->ccb_h.status |= (CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ); | ||||
return PQI_STATUS_FAILURE; | return BSD_FAILURE; | ||||
} | } | ||||
DBG_IO("tag = %d &softs->taglist : %p\n", tag, &softs->taglist); | DBG_IO("tag = %d &softs->taglist : %p\n", tag, &softs->taglist); | ||||
rcb = &softs->rcb[tag]; | rcb = &softs->rcb[tag]; | ||||
os_reset_rcb( rcb ); | os_reset_rcb(rcb); | ||||
rcb->tag = tag; | rcb->tag = tag; | ||||
rcb->softs = softs; | rcb->softs = softs; | ||||
rcb->cmdlen = ccb->csio.cdb_len; | rcb->cmdlen = ccb->csio.cdb_len; | ||||
Context not available. | |||||
* if we ever learn a transport layer other than simple, may fail | * if we ever learn a transport layer other than simple, may fail | ||||
* if the adapter rejects the command). | * if the adapter rejects the command). | ||||
*/ | */ | ||||
if ((error = pqi_map_request(rcb)) != 0) { | if ((error = pqi_map_request(rcb)) != BSD_SUCCESS) { | ||||
rcb->req_pending = false; | |||||
xpt_freeze_simq(softs->os_specific.sim, 1); | xpt_freeze_simq(softs->os_specific.sim, 1); | ||||
ccb->ccb_h.status |= CAM_RELEASE_SIMQ; | |||||
if (error == EINPROGRESS) { | if (error == EINPROGRESS) { | ||||
DBG_WARN("In Progress on %d\n", ccb->ccb_h.target_id); | /* Release simq in the completion */ | ||||
error = 0; | softs->os_specific.pqi_flags |= PQI_FLAG_BUSY; | ||||
error = BSD_SUCCESS; | |||||
} else { | } else { | ||||
ccb->ccb_h.status |= CAM_REQUEUE_REQ; | rcb->req_pending = false; | ||||
ccb->ccb_h.status |= CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; | |||||
DBG_WARN("Requeue req error = %d target = %d\n", error, | DBG_WARN("Requeue req error = %d target = %d\n", error, | ||||
ccb->ccb_h.target_id); | ccb->ccb_h.target_id); | ||||
pqi_unmap_request(rcb); | pqi_unmap_request(rcb); | ||||
error = BSD_FAILURE; | |||||
} | } | ||||
} | } | ||||
DBG_FUNC("OUT error = %d\n", error); | DBG_FUNC("OUT error = %d\n", error); | ||||
return error; | return error; | ||||
} | } | ||||
static uint32_t get_tag_for_tmf(pqisrc_softstate_t *softs, rcb_t *rcb) | |||||
{ | |||||
uint32_t free_tag; | |||||
DBG_FUNC("IN\n"); | |||||
free_tag = pqisrc_get_tag(&softs->taglist); | |||||
rcb = &softs->rcb[free_tag]; | |||||
rcb->tag = free_tag; | |||||
rcb->tm_req = true; | |||||
DBG_FUNC("OUT\n"); | |||||
return free_tag; | |||||
} | |||||
static inline int pqi_tmf_err_to_bsd_tmf_err(int pqi_error, rcb_t *rcb) | |||||
{ | |||||
if (PQI_STATUS_SUCCESS == pqi_error && | |||||
REQUEST_SUCCESS == rcb->status) | |||||
return BSD_SUCCESS; | |||||
else | |||||
return BSD_FAILURE; | |||||
} | |||||
/* | /* | ||||
* Abort a task, task management functionality | * Abort a task, task management functionality | ||||
*/ | */ | ||||
static int | static int | ||||
pqisrc_scsi_abort_task(pqisrc_softstate_t *softs, union ccb *ccb) | pqisrc_scsi_abort_task(pqisrc_softstate_t *softs, union ccb *ccb) | ||||
{ | { | ||||
rcb_t *rcb = ccb->ccb_h.sim_priv.entries[0].ptr; | struct ccb_hdr *ccb_h = &ccb->ccb_h; | ||||
uint32_t abort_tag = rcb->tag; | rcb_t *rcb = NULL; | ||||
uint32_t tag = 0; | rcb_t *prcb = ccb->ccb_h.sim_priv.entries[0].ptr; | ||||
int rval = PQI_STATUS_SUCCESS; | uint32_t tag; | ||||
uint16_t qid; | int rval; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
qid = (uint16_t)rcb->resp_qid; | tag = get_tag_for_tmf(softs, rcb); | ||||
tag = pqisrc_get_tag(&softs->taglist); | if (!rcb->dvp) { | ||||
rcb = &softs->rcb[tag]; | DBG_ERR("dvp is null, tmf type : 0x%x\n", ccb_h->func_code); | ||||
rcb->tag = tag; | rval = BSD_FAILURE; | ||||
rcb->resp_qid = qid; | goto error_tmf; | ||||
} | |||||
rval = pqisrc_send_tmf(softs, rcb->dvp, rcb, abort_tag, | rval = pqisrc_send_tmf(softs, rcb->dvp, rcb, prcb, | ||||
SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK); | SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK); | ||||
if (PQI_STATUS_SUCCESS == rval) { | if ((rval = pqi_tmf_err_to_bsd_tmf_err(rval, rcb)) == BSD_SUCCESS) | ||||
rval = rcb->status; | ccb->ccb_h.status = CAM_REQ_ABORTED; | ||||
if (REQUEST_SUCCESS == rval) { | |||||
ccb->ccb_h.status = CAM_REQ_ABORTED; | error_tmf: | ||||
} | os_reset_rcb(rcb); | ||||
} | pqisrc_put_tag(&softs->taglist, tag); | ||||
pqisrc_put_tag(&softs->taglist, abort_tag); | |||||
pqisrc_put_tag(&softs->taglist,rcb->tag); | |||||
DBG_FUNC("OUT rval = %d\n", rval); | DBG_FUNC("OUT rval = %d\n", rval); | ||||
Context not available. | |||||
static int | static int | ||||
pqisrc_scsi_abort_task_set(pqisrc_softstate_t *softs, union ccb *ccb) | pqisrc_scsi_abort_task_set(pqisrc_softstate_t *softs, union ccb *ccb) | ||||
{ | { | ||||
struct ccb_hdr *ccb_h = &ccb->ccb_h; | |||||
rcb_t *rcb = NULL; | rcb_t *rcb = NULL; | ||||
uint32_t tag = 0; | uint32_t tag; | ||||
int rval = PQI_STATUS_SUCCESS; | int rval; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
tag = pqisrc_get_tag(&softs->taglist); | tag = get_tag_for_tmf(softs, rcb); | ||||
rcb = &softs->rcb[tag]; | |||||
rcb->tag = tag; | |||||
rval = pqisrc_send_tmf(softs, rcb->dvp, rcb, 0, | if (!rcb->dvp) { | ||||
DBG_ERR("dvp is null, tmf type : 0x%x\n", ccb_h->func_code); | |||||
rval = BSD_FAILURE; | |||||
goto error_tmf; | |||||
} | |||||
rval = pqisrc_send_tmf(softs, rcb->dvp, rcb, NULL, | |||||
SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK_SET); | SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK_SET); | ||||
if (rval == PQI_STATUS_SUCCESS) { | rval = pqi_tmf_err_to_bsd_tmf_err(rval, rcb); | ||||
rval = rcb->status; | |||||
} | |||||
pqisrc_put_tag(&softs->taglist,rcb->tag); | error_tmf: | ||||
os_reset_rcb(rcb); | |||||
pqisrc_put_tag(&softs->taglist, tag); | |||||
DBG_FUNC("OUT rval = %d\n", rval); | DBG_FUNC("OUT rval = %d\n", rval); | ||||
Context not available. | |||||
static int | static int | ||||
pqisrc_target_reset( pqisrc_softstate_t *softs, union ccb *ccb) | pqisrc_target_reset( pqisrc_softstate_t *softs, union ccb *ccb) | ||||
{ | { | ||||
struct ccb_hdr *ccb_h = &ccb->ccb_h; | |||||
pqi_scsi_dev_t *devp = softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun]; | pqi_scsi_dev_t *devp = softs->device_list[ccb->ccb_h.target_id][ccb->ccb_h.target_lun]; | ||||
rcb_t *rcb = NULL; | rcb_t *rcb = NULL; | ||||
uint32_t tag = 0; | uint32_t tag; | ||||
int rval = PQI_STATUS_SUCCESS; | int rval; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (devp == NULL) { | if (devp == NULL) { | ||||
DBG_ERR("bad target t%d\n", ccb->ccb_h.target_id); | DBG_ERR("bad target %d, tmf type : 0x%x\n", ccb_h->target_id, ccb_h->func_code); | ||||
return (-1); | return BSD_FAILURE; | ||||
} | } | ||||
tag = pqisrc_get_tag(&softs->taglist); | tag = get_tag_for_tmf(softs, rcb); | ||||
rcb = &softs->rcb[tag]; | |||||
rcb->tag = tag; | |||||
devp->reset_in_progress = true; | devp->reset_in_progress = true; | ||||
rval = pqisrc_send_tmf(softs, devp, rcb, 0, | |||||
rval = pqisrc_send_tmf(softs, devp, rcb, NULL, | |||||
SOP_TASK_MANAGEMENT_LUN_RESET); | SOP_TASK_MANAGEMENT_LUN_RESET); | ||||
if (PQI_STATUS_SUCCESS == rval) { | |||||
rval = rcb->status; | rval = pqi_tmf_err_to_bsd_tmf_err(rval, rcb); | ||||
} | |||||
devp->reset_in_progress = false; | devp->reset_in_progress = false; | ||||
pqisrc_put_tag(&softs->taglist,rcb->tag); | |||||
os_reset_rcb(rcb); | |||||
pqisrc_put_tag(&softs->taglist, tag); | |||||
DBG_FUNC("OUT rval = %d\n", rval); | DBG_FUNC("OUT rval = %d\n", rval); | ||||
return ((rval == REQUEST_SUCCESS) ? | return rval; | ||||
PQI_STATUS_SUCCESS : PQI_STATUS_FAILURE); | |||||
} | } | ||||
/* | /* | ||||
Context not available. | |||||
ccg = &ccb->ccg; | ccg = &ccb->ccg; | ||||
if (ccg->block_size == 0) { | if (ccg->block_size == 0) { | ||||
ccb->ccb_h.status &= ~CAM_SIM_QUEUED; | ccb->ccb_h.status &= ~CAM_SIM_QUEUED; | ||||
ccb->ccb_h.status = CAM_REQ_INVALID; | ccb->ccb_h.status |= CAM_REQ_INVALID; | ||||
break; | break; | ||||
} | } | ||||
cam_calc_geometry(ccg, /* extended */ 1); | cam_calc_geometry(ccg, /* extended */ 1); | ||||
Context not available. | |||||
*/ | */ | ||||
int register_sim(struct pqisrc_softstate *softs, int card_index) | int register_sim(struct pqisrc_softstate *softs, int card_index) | ||||
{ | { | ||||
int error = 0; | |||||
int max_transactions; | int max_transactions; | ||||
union ccb *ccb = NULL; | union ccb *ccb = NULL; | ||||
cam_status status = 0; | cam_status status = 0; | ||||
Context not available. | |||||
if (softs->os_specific.devq == NULL) { | if (softs->os_specific.devq == NULL) { | ||||
DBG_ERR("cam_simq_alloc failed txns = %d\n", | DBG_ERR("cam_simq_alloc failed txns = %d\n", | ||||
max_transactions); | max_transactions); | ||||
return PQI_STATUS_FAILURE; | return BSD_FAILURE; | ||||
} | } | ||||
sim = cam_sim_alloc(smartpqi_cam_action, \ | sim = cam_sim_alloc(smartpqi_cam_action, \ | ||||
Context not available. | |||||
DBG_ERR("cam_sim_alloc failed txns = %d\n", | DBG_ERR("cam_sim_alloc failed txns = %d\n", | ||||
max_transactions); | max_transactions); | ||||
cam_simq_free(softs->os_specific.devq); | cam_simq_free(softs->os_specific.devq); | ||||
return PQI_STATUS_FAILURE; | return BSD_FAILURE; | ||||
} | } | ||||
softs->os_specific.sim = sim; | softs->os_specific.sim = sim; | ||||
Context not available. | |||||
cam_sim_free(softs->os_specific.sim, FALSE); | cam_sim_free(softs->os_specific.sim, FALSE); | ||||
cam_simq_free(softs->os_specific.devq); | cam_simq_free(softs->os_specific.devq); | ||||
mtx_unlock(&softs->os_specific.cam_lock); | mtx_unlock(&softs->os_specific.cam_lock); | ||||
return PQI_STATUS_FAILURE; | return BSD_FAILURE; | ||||
} | } | ||||
softs->os_specific.sim_registered = TRUE; | softs->os_specific.sim_registered = TRUE; | ||||
ccb = xpt_alloc_ccb_nowait(); | ccb = xpt_alloc_ccb_nowait(); | ||||
if (ccb == NULL) { | if (ccb == NULL) { | ||||
DBG_ERR("xpt_create_path failed\n"); | DBG_ERR("xpt_create_path failed\n"); | ||||
return PQI_STATUS_FAILURE; | return BSD_FAILURE; | ||||
} | } | ||||
if (xpt_create_path(&ccb->ccb_h.path, NULL, | if (xpt_create_path(&ccb->ccb_h.path, NULL, | ||||
Context not available. | |||||
xpt_bus_deregister(cam_sim_path(softs->os_specific.sim)); | xpt_bus_deregister(cam_sim_path(softs->os_specific.sim)); | ||||
cam_sim_free(softs->os_specific.sim, TRUE); | cam_sim_free(softs->os_specific.sim, TRUE); | ||||
mtx_unlock(&softs->os_specific.cam_lock); | mtx_unlock(&softs->os_specific.cam_lock); | ||||
return PQI_STATUS_FAILURE; | return BSD_FAILURE; | ||||
} | } | ||||
/* | /* | ||||
* Callback to set the queue depth per target which is | * Callback to set the queue depth per target which is | ||||
Context not available. | |||||
mtx_unlock(&softs->os_specific.cam_lock); | mtx_unlock(&softs->os_specific.cam_lock); | ||||
DBG_INFO("OUT\n"); | DBG_INFO("OUT\n"); | ||||
return error; | |||||
return BSD_SUCCESS; | |||||
} | } | ||||
/* | /* | ||||
Context not available. | |||||
xpt_action((union ccb *)&csa); | xpt_action((union ccb *)&csa); | ||||
xpt_free_path(softs->os_specific.path); | xpt_free_path(softs->os_specific.path); | ||||
xpt_release_simq(softs->os_specific.sim, 0); | |||||
xpt_bus_deregister(cam_sim_path(softs->os_specific.sim)); | |||||
softs->os_specific.sim_registered = FALSE; | |||||
if (softs->os_specific.sim) { | if (softs->os_specific.sim) { | ||||
xpt_release_simq(softs->os_specific.sim, 0); | |||||
xpt_bus_deregister(cam_sim_path(softs->os_specific.sim)); | |||||
softs->os_specific.sim_registered = FALSE; | |||||
cam_sim_free(softs->os_specific.sim, FALSE); | cam_sim_free(softs->os_specific.sim, FALSE); | ||||
softs->os_specific.sim = NULL; | softs->os_specific.sim = NULL; | ||||
} | } | ||||
if (softs->os_specific.mtx_init) { | if (softs->os_specific.mtx_init) { | ||||
mtx_unlock(&softs->os_specific.cam_lock); | mtx_unlock(&softs->os_specific.cam_lock); | ||||
} | } | ||||
Context not available. |
also, s/it's/its/ ?