Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/isp/isp_pci.c
Context not available. | |||||
static int isp_pci_detach (device_t); | static int isp_pci_detach (device_t); | ||||
#define ISP_PCD(isp) ((struct isp_pcisoftc *)isp)->pci_dev | |||||
struct isp_pcisoftc { | struct isp_pcisoftc { | ||||
ispsoftc_t pci_isp; | ispsoftc_t pci_isp; | ||||
device_t pci_dev; | |||||
struct resource * regs; | struct resource * regs; | ||||
struct resource * regs1; | struct resource * regs1; | ||||
struct resource * regs2; | struct resource * regs2; | ||||
Context not available. | |||||
size_t psize, xsize; | size_t psize, xsize; | ||||
char fwname[32]; | char fwname[32]; | ||||
pcs->pci_dev = dev; | |||||
isp->isp_dev = dev; | isp->isp_dev = dev; | ||||
isp->isp_nchan = 1; | isp->isp_nchan = 1; | ||||
mtx_init(&isp->isp_lock, "isp", NULL, MTX_DEF); | mtx_init(&isp->isp_lock, "isp", NULL, MTX_DEF); | ||||
Context not available. | |||||
pcs->regs = pcs->regs2 = NULL; | pcs->regs = pcs->regs2 = NULL; | ||||
pcs->rgd = pcs->rtp = 0; | pcs->rgd = pcs->rtp = 0; | ||||
pcs->pci_dev = dev; | |||||
isp->isp_nchan += isp_nvports; | isp->isp_nchan += isp_nvports; | ||||
switch (pci_get_devid(dev)) { | switch (pci_get_devid(dev)) { | ||||
case PCI_QLOGIC_ISP2422: | case PCI_QLOGIC_ISP2422: | ||||
Context not available. | |||||
static int | static int | ||||
isp_pci_mbxdma(ispsoftc_t *isp) | isp_pci_mbxdma(ispsoftc_t *isp) | ||||
{ | { | ||||
bus_dma_tag_t ptag; | |||||
caddr_t base; | caddr_t base; | ||||
uint32_t len; | uint32_t len; | ||||
int i, error, cmap; | int i, error, cmap = 0; | ||||
bus_size_t slim; /* segment size */ | bus_size_t slim; /* segment size */ | ||||
struct imush im; | struct imush im; | ||||
#ifdef ISP_TARGET_MODE | #ifdef ISP_TARGET_MODE | ||||
Context not available. | |||||
if (isp->isp_rquest != NULL && isp->isp_maxcmds == 0) | if (isp->isp_rquest != NULL && isp->isp_maxcmds == 0) | ||||
return (0); | return (0); | ||||
ISP_UNLOCK(isp); | ISP_UNLOCK(isp); | ||||
if (isp->isp_rquest != NULL) | |||||
goto gotmaxcmds; | |||||
ptag = bus_get_dma_tag(isp->isp_osinfo.dev); | |||||
if (sizeof (bus_size_t) > 4) | if (sizeof (bus_size_t) > 4) | ||||
slim = (bus_size_t) (1ULL << 32); | slim = (bus_size_t) (1ULL << 32); | ||||
else | else | ||||
slim = (bus_size_t) (1UL << 31); | slim = (bus_size_t) (1UL << 31); | ||||
if (bus_dma_tag_create(bus_get_dma_tag(ISP_PCD(isp)), 1, slim, | |||||
if (isp->isp_rquest != NULL) | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
goto gotmaxcmds; | (ISP_NSEG64_MAX - 1) * PAGE_SIZE, ISP_NSEG64_MAX, | ||||
(ISP_NSEG64_MAX - 1) * PAGE_SIZE, 0, | |||||
busdma_lock_mutex, &isp->isp_lock, &isp->isp_osinfo.dmat)) { | |||||
ISP_LOCK(isp); | |||||
isp_prt(isp, ISP_LOGERR, "could not create master dma tag"); | |||||
return (1); | |||||
} | |||||
/* | /* | ||||
* Allocate and map the request queue. | * Allocate and map the request queue. | ||||
*/ | */ | ||||
len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); | len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); | ||||
if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, | if (bus_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim, | ||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.reqdmat)) { | len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.reqdmat)) { | ||||
isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag"); | isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag"); | ||||
Context not available. | |||||
* Allocate region for external DMA addressable command/status structures. | * Allocate region for external DMA addressable command/status structures. | ||||
*/ | */ | ||||
len = N_XCMDS * XCMD_SIZE; | len = N_XCMDS * XCMD_SIZE; | ||||
if (bus_dma_tag_create(ptag, XCMD_SIZE, slim, | if (bus_dma_tag_create(isp->isp_osinfo.dmat, XCMD_SIZE, slim, | ||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.ecmd_dmat)) { | len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.ecmd_dmat)) { | ||||
isp_prt(isp, ISP_LOGERR, "cannot create ECMD DMA tag"); | isp_prt(isp, ISP_LOGERR, "cannot create ECMD DMA tag"); | ||||
Context not available. | |||||
if (bus_dmamem_alloc(isp->isp_osinfo.ecmd_dmat, (void **)&base, | if (bus_dmamem_alloc(isp->isp_osinfo.ecmd_dmat, (void **)&base, | ||||
BUS_DMA_COHERENT, &isp->isp_osinfo.ecmd_map) != 0) { | BUS_DMA_COHERENT, &isp->isp_osinfo.ecmd_map) != 0) { | ||||
isp_prt(isp, ISP_LOGERR, "cannot allocate ECMD DMA memory"); | isp_prt(isp, ISP_LOGERR, "cannot allocate ECMD DMA memory"); | ||||
bus_dma_tag_destroy(isp->isp_osinfo.ecmd_dmat); | bus_dma_tag_destroy(isp->isp_osinfo.reqdmat); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
isp->isp_osinfo.ecmd_base = (isp_ecmd_t *)base; | isp->isp_osinfo.ecmd_base = (isp_ecmd_t *)base; | ||||
Context not available. | |||||
* Allocate and map the result queue. | * Allocate and map the result queue. | ||||
*/ | */ | ||||
len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); | len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); | ||||
if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, | if (bus_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim, | ||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.respdmat)) { | len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.respdmat)) { | ||||
isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag"); | isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag"); | ||||
Context not available. | |||||
* Allocate and map ATIO queue. | * Allocate and map ATIO queue. | ||||
*/ | */ | ||||
len = ISP_QUEUE_SIZE(ATIO_QUEUE_LEN(isp)); | len = ISP_QUEUE_SIZE(ATIO_QUEUE_LEN(isp)); | ||||
if (bus_dma_tag_create(ptag, QENTRY_LEN, slim, | if (bus_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim, | ||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.atiodmat)) { | len, 1, len, 0, NULL, NULL, &isp->isp_osinfo.atiodmat)) { | ||||
isp_prt(isp, ISP_LOGERR, "cannot create ATIO DMA tag"); | isp_prt(isp, ISP_LOGERR, "cannot create ATIO DMA tag"); | ||||
Context not available. | |||||
isp->isp_atioq_dma = im.maddr; | isp->isp_atioq_dma = im.maddr; | ||||
#endif | #endif | ||||
if (bus_dma_tag_create(ptag, 64, slim, | if (bus_dma_tag_create(isp->isp_osinfo.dmat, 64, slim, | ||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
2*QENTRY_LEN, 1, 2*QENTRY_LEN, 0, NULL, NULL, | 2*QENTRY_LEN, 1, 2*QENTRY_LEN, 0, NULL, NULL, | ||||
&isp->isp_osinfo.iocbdmat)) { | &isp->isp_osinfo.iocbdmat)) { | ||||
Context not available. | |||||
goto bad; | goto bad; | ||||
isp->isp_iocb_dma = im.maddr; | isp->isp_iocb_dma = im.maddr; | ||||
if (bus_dma_tag_create(ptag, 64, slim, | if (bus_dma_tag_create(isp->isp_osinfo.dmat, 64, slim, | ||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, NULL, NULL, | ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, NULL, NULL, | ||||
&isp->isp_osinfo.scdmat)) | &isp->isp_osinfo.scdmat)) | ||||
Context not available. | |||||
} | } | ||||
gotmaxcmds: | gotmaxcmds: | ||||
if (bus_dma_tag_create(ptag, 1, slim, | |||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | |||||
(ISP_NSEG64_MAX - 1) * PAGE_SIZE, ISP_NSEG64_MAX, | |||||
(ISP_NSEG64_MAX - 1) * PAGE_SIZE, 0, | |||||
busdma_lock_mutex, &isp->isp_lock, &isp->isp_osinfo.dmat)) | |||||
goto bad; | |||||
len = isp->isp_maxcmds * sizeof (struct isp_pcmd); | len = isp->isp_maxcmds * sizeof (struct isp_pcmd); | ||||
isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) | isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) | ||||
malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); | malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); | ||||
Context not available. | |||||
} | } | ||||
isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; | isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0]; | ||||
len = sizeof(isp_hdl_t) * ISP_HANDLE_NUM(isp); | len = sizeof (isp_hdl_t) * isp->isp_maxcmds; | ||||
isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); | isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); | ||||
for (len = 0; len < ISP_HANDLE_NUM(isp) - 1; len++) | for (len = 0; len < isp->isp_maxcmds - 1; len++) | ||||
isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; | isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1]; | ||||
isp->isp_xffree = isp->isp_xflist; | isp->isp_xffree = isp->isp_xflist; | ||||
Context not available. | |||||
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); | free(isp->isp_osinfo.pcmd_pool, M_DEVBUF); | ||||
isp->isp_osinfo.pcmd_pool = NULL; | isp->isp_osinfo.pcmd_pool = NULL; | ||||
} | } | ||||
if (isp->isp_osinfo.dmat) { | |||||
bus_dma_tag_destroy(isp->isp_osinfo.dmat); | |||||
isp->isp_osinfo.dmat = NULL; | |||||
} | |||||
for (i = 0; i < isp->isp_nchan; i++) { | for (i = 0; i < isp->isp_nchan; i++) { | ||||
struct isp_fc *fc = ISP_FC_PC(isp, i); | struct isp_fc *fc = ISP_FC_PC(isp, i); | ||||
if (FCPARAM(isp, i)->isp_scdma != 0) { | if (FCPARAM(isp, i)->isp_scdma != 0) { | ||||
Context not available. | |||||
free(n, M_DEVBUF); | free(n, M_DEVBUF); | ||||
} | } | ||||
} | } | ||||
if (isp->isp_osinfo.scdmat) { | |||||
bus_dma_tag_destroy(isp->isp_osinfo.scdmat); | |||||
isp->isp_osinfo.scdmat = NULL; | |||||
} | |||||
if (isp->isp_iocb_dma != 0) { | if (isp->isp_iocb_dma != 0) { | ||||
bus_dma_tag_destroy(isp->isp_osinfo.scdmat); | |||||
bus_dmamap_unload(isp->isp_osinfo.iocbdmat, | bus_dmamap_unload(isp->isp_osinfo.iocbdmat, | ||||
isp->isp_osinfo.iocbmap); | isp->isp_osinfo.iocbmap); | ||||
isp->isp_iocb_dma = 0; | isp->isp_iocb_dma = 0; | ||||
Context not available. |