Convert the use of vtophys() for doing autosense to use busdma. Also correct

some error codes that get returned to CAM.
This commit is contained in:
Scott Long 2002-12-14 19:20:57 +00:00
parent 2bfe8dcc0a
commit 2c6a3591f9
2 changed files with 79 additions and 12 deletions

View File

@ -47,7 +47,7 @@
*********************************************************************
*/
/* #define AMD_DEBUG0 */
/* #define AMD_DEBUG0 */
/* #define AMD_DEBUG_SCSI_PHASE */
#include <sys/param.h>
@ -76,7 +76,6 @@
#include <pci/pcivar.h>
#include <pci/pcireg.h>
#include <dev/amd/amd.h>
#define PCI_DEVICE_ID_AMD53C974 0x20201022ul
@ -119,6 +118,9 @@ static void amd_ResetSCSIBus(struct amd_softc *amd);
static void RequestSense(struct amd_softc *amd, struct amd_srb *pSRB);
static void amd_InvalidCmd(struct amd_softc *amd);
static void amd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegs,
int error);
#if 0
static void amd_timeout(void *arg1);
static void amd_reset(struct amd_softc *amd);
@ -155,6 +157,30 @@ amd_clear_msg_state(struct amd_softc *amd)
amd->msgin_index = 0;
}
static __inline uint32_t
amd_get_sense_bufaddr(struct amd_softc *amd, struct amd_srb *pSRB)
{
int offset;
offset = pSRB->TagNumber;
return (amd->sense_busaddr + (offset * sizeof(struct scsi_sense_data)));
}
static __inline struct scsi_sense_data *
amd_get_sense_buf(struct amd_softc *amd, struct amd_srb *pSRB)
{
int offset;
offset = pSRB->TagNumber;
return (&amd->sense_buffers[offset]);
}
static __inline uint32_t
amd_get_sense_bufsize(struct amd_softc *amd, struct amd_srb *pSRB)
{
return (sizeof(struct scsi_sense_data));
}
/* CAM SIM entry points */
#define ccb_srb_ptr spriv_ptr0
#define ccb_amd_ptr spriv_ptr1
@ -234,18 +260,15 @@ static void
amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb)
{
struct scsi_request_sense sense_cmd;
struct ccb_scsiio *csio;
u_int8_t *cdb;
u_int cdb_len;
csio = &srb->pccb->csio;
if (srb->SRBFlag & AUTO_REQSENSE) {
sense_cmd.opcode = REQUEST_SENSE;
sense_cmd.byte2 = srb->pccb->ccb_h.target_lun << 5;
sense_cmd.unused[0] = 0;
sense_cmd.unused[1] = 0;
sense_cmd.length = csio->sense_len;
sense_cmd.length = sizeof(struct scsi_sense_data);
sense_cmd.control = 0;
cdb = &sense_cmd.opcode;
cdb_len = sizeof(sense_cmd);
@ -713,6 +736,15 @@ phystovirt(struct amd_srb * pSRB, u_int32_t xferCnt)
return ((u_int8_t *) dataPtr);
}
static void
amd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
bus_addr_t *baddr;
baddr = (bus_addr_t *)arg;
*baddr = segs->ds_addr;
}
static void
ResetDevParam(struct amd_softc * amd)
{
@ -1875,7 +1907,7 @@ SRBdone(struct amd_softc *amd, struct amd_srb *pSRB)
pSRB->TargetStatus = SCSI_STATUS_CHECK_COND;
if (status == SCSI_STATUS_CHECK_COND) {
pccb->ccb_h.status = CAM_SEL_TIMEOUT;
pccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
goto ckc_e;
}
*((u_int32_t *)&(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
@ -1892,7 +1924,10 @@ SRBdone(struct amd_softc *amd, struct amd_srb *pSRB)
} else {
pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
}
pccb->ccb_h.status = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR;
bzero(&pcsio->sense_data, pcsio->sense_len);
bcopy(amd_get_sense_buf(amd, pSRB), &pcsio->sense_data,
pcsio->sense_len);
pccb->ccb_h.status = CAM_AUTOSNS_VALID;
goto ckc_e;
}
if (status) {
@ -2064,16 +2099,19 @@ RequestSense(struct amd_softc *amd, struct amd_srb *pSRB)
pSRB->AdaptStatus = 0;
pSRB->TargetStatus = 0;
pSRB->Segmentx.SGXPtr = (u_int32_t) vtophys(&pcsio->sense_data);
pSRB->Segmentx.SGXLen = (u_int32_t) pcsio->sense_len;
pSRB->Segmentx.SGXPtr = amd_get_sense_bufaddr(amd, pSRB);
pSRB->Segmentx.SGXLen = amd_get_sense_bufsize(amd, pSRB);
pSRB->pSGlist = &pSRB->Segmentx;
pSRB->SGcount = 1;
pSRB->SGIndex = 0;
*((u_int32_t *) & (pSRB->CmdBlock[0])) = 0x00000003;
pSRB->CmdBlock[0] = REQUEST_SENSE;
pSRB->CmdBlock[1] = pSRB->pccb->ccb_h.target_lun << 5;
*((u_int16_t *) & (pSRB->CmdBlock[4])) = pcsio->sense_len;
pSRB->CmdBlock[2] = 0;
pSRB->CmdBlock[3] = 0;
pSRB->CmdBlock[4] = pcsio->sense_len;
pSRB->CmdBlock[5] = 0;
pSRB->ScsiCmdLen = 6;
pSRB->TotalXferredLen = 0;
@ -2281,6 +2319,31 @@ amd_init(device_t dev)
printf("amd_init: bus_dma_tag_create failure!\n");
return ENXIO;
}
/* Create, allocate, and map DMA buffers for autosense data */
if (bus_dma_tag_create(/*parent_dmat*/NULL, /*alignment*/1,
/*boundary*/0,
/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
/*highaddr*/BUS_SPACE_MAXADDR,
/*filter*/NULL, /*filterarg*/NULL,
sizeof(struct scsi_sense_data) * MAX_SRB_CNT,
/*nsegments*/1,
/*maxsegsz*/AMD_MAXTRANSFER_SIZE,
/*flags*/0, &amd->sense_dmat) != 0) {
if (bootverbose)
device_printf(dev, "cannot create sense buffer dmat\n");
return (ENXIO);
}
if (bus_dmamem_alloc(amd->sense_dmat, (void **)&amd->sense_buffers,
BUS_DMA_NOWAIT, &amd->sense_dmamap) != 0)
return (ENOMEM);
bus_dmamap_load(amd->sense_dmat, amd->sense_dmamap,
amd->sense_buffers,
sizeof(struct scsi_sense_data) * MAX_SRB_CNT,
amd_dmamap_cb, &amd->sense_busaddr, /*flags*/0);
TAILQ_INIT(&amd->free_srbs);
TAILQ_INIT(&amd->running_srbs);
TAILQ_INIT(&amd->waiting_srbs);

View File

@ -197,6 +197,10 @@ struct amd_softc {
bus_space_tag_t tag;
bus_space_handle_t bsh;
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
bus_dma_tag_t sense_dmat; /* dmat for sense buffer */
bus_dmamap_t sense_dmamap;
struct scsi_sense_data *sense_buffers;
bus_addr_t sense_busaddr;
int unit;
int last_phase;