Date: Mon, 9 Nov 2020 01:39:55 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r367508 - in stable/11: share/man/man4 sys/dev/arcmsr Message-ID: <202011090139.0A91dtb8023272@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Mon Nov 9 01:39:55 2020 New Revision: 367508 URL: https://svnweb.freebsd.org/changeset/base/367508 Log: MFC r358477,365113,366767: arcmsr(4) 1.50.00.00. Modified: stable/11/share/man/man4/arcmsr.4 stable/11/sys/dev/arcmsr/arcmsr.c stable/11/sys/dev/arcmsr/arcmsr.h Directory Properties: stable/11/ (props changed) Modified: stable/11/share/man/man4/arcmsr.4 ============================================================================== --- stable/11/share/man/man4/arcmsr.4 Mon Nov 9 01:38:02 2020 (r367507) +++ stable/11/share/man/man4/arcmsr.4 Mon Nov 9 01:39:55 2020 (r367508) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 8, 2017 +.Dd October 15, 2020 .Dt ARCMSR 4 .Os .Sh NAME @@ -153,6 +153,8 @@ ARC-1882 ARC-1883 .It ARC-1884 +.It +ARC-1886 .El .Sh FILES .Bl -tag -width ".Pa /dev/arcmsr?" -compact Modified: stable/11/sys/dev/arcmsr/arcmsr.c ============================================================================== --- stable/11/sys/dev/arcmsr/arcmsr.c Mon Nov 9 01:38:02 2020 (r367507) +++ stable/11/sys/dev/arcmsr/arcmsr.c Mon Nov 9 01:39:55 2020 (r367508) @@ -79,6 +79,7 @@ ** 1.30.00.00 11/30/2015 Ching Huang Added support ARC1203 ** 1.40.00.00 07/11/2017 Ching Huang Added support ARC1884 ** 1.40.00.01 10/30/2017 Ching Huang Fixed release memory resource +** 1.50.00.00 09/30/2020 Ching Huang Added support ARC-1886, NVMe/SAS/SATA controller ****************************************************************************************** */ @@ -128,29 +129,15 @@ __FBSDID("$FreeBSD$"); ************************************************************************** ************************************************************************** */ -#if __FreeBSD_version >= 500005 - #include <sys/selinfo.h> - #include <sys/mutex.h> - #include <sys/endian.h> - #include <dev/pci/pcivar.h> - #include <dev/pci/pcireg.h> -#else - #include <sys/select.h> - #include <pci/pcivar.h> - #include <pci/pcireg.h> -#endif +#include <sys/selinfo.h> +#include <sys/mutex.h> +#include <sys/endian.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> -#if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025 -#define CAM_NEW_TRAN_CODE 1 -#endif - -#if __FreeBSD_version > 500000 #define arcmsr_callout_init(a) callout_init(a, /*mpsafe*/1); -#else -#define arcmsr_callout_init(a) callout_init(a); -#endif -#define ARCMSR_DRIVER_VERSION "arcmsr version 1.40.00.01 2017-10-30" +#define ARCMSR_DRIVER_VERSION "arcmsr version 1.50.00.00 2020-09-30" #include <dev/arcmsr/arcmsr.h> /* ************************************************************************** @@ -188,6 +175,7 @@ static void arcmsr_polling_devmap(void *arg); static void arcmsr_srb_timeout(void *arg); static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb); static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb); +static void arcmsr_hbf_postqueue_isr(struct AdapterControlBlock *acb); static void arcmsr_teardown_intr(device_t dev, struct AdapterControlBlock *acb); #ifdef ARCMSR_DEBUG1 static void arcmsr_dump_data(struct AdapterControlBlock *acb); @@ -218,12 +206,7 @@ static device_method_t arcmsr_methods[]={ DEVMETHOD(device_shutdown, arcmsr_shutdown), DEVMETHOD(device_suspend, arcmsr_suspend), DEVMETHOD(device_resume, arcmsr_resume), - -#if __FreeBSD_version >= 803000 DEVMETHOD_END -#else - { 0, 0 } -#endif }; static driver_t arcmsr_driver={ @@ -237,59 +220,23 @@ MODULE_DEPEND(arcmsr, cam, 1, 1, 1); #ifndef BUS_DMA_COHERENT #define BUS_DMA_COHERENT 0x04 /* hint: map memory in a coherent way */ #endif -#if __FreeBSD_version >= 501000 static struct cdevsw arcmsr_cdevsw={ - #if __FreeBSD_version >= 503000 .d_version = D_VERSION, - #endif - #if (__FreeBSD_version>=503000 && __FreeBSD_version<600034) - .d_flags = D_NEEDGIANT, - #endif .d_open = arcmsr_open, /* open */ .d_close = arcmsr_close, /* close */ .d_ioctl = arcmsr_ioctl, /* ioctl */ .d_name = "arcmsr", /* name */ }; -#else - #define ARCMSR_CDEV_MAJOR 180 - -static struct cdevsw arcmsr_cdevsw = { - arcmsr_open, /* open */ - arcmsr_close, /* close */ - noread, /* read */ - nowrite, /* write */ - arcmsr_ioctl, /* ioctl */ - nopoll, /* poll */ - nommap, /* mmap */ - nostrategy, /* strategy */ - "arcmsr", /* name */ - ARCMSR_CDEV_MAJOR, /* major */ - nodump, /* dump */ - nopsize, /* psize */ - 0 /* flags */ - }; -#endif /* ************************************************************************** ************************************************************************** */ -#if __FreeBSD_version < 500005 - static int arcmsr_open(dev_t dev, int flags, int fmt, struct proc *proc) -#else - #if __FreeBSD_version < 503000 - static int arcmsr_open(dev_t dev, int flags, int fmt, struct thread *proc) - #else - static int arcmsr_open(struct cdev *dev, int flags, int fmt, struct thread *proc) - #endif -#endif +static int arcmsr_open(struct cdev *dev, int flags, int fmt, struct thread *proc) { - #if __FreeBSD_version < 503000 - struct AdapterControlBlock *acb = dev->si_drv1; - #else - int unit = dev2unit(dev); - struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); - #endif - if(acb == NULL) { + int unit = dev2unit(dev); + struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); + + if (acb == NULL) { return ENXIO; } return (0); @@ -298,23 +245,12 @@ static struct cdevsw arcmsr_cdevsw = { ************************************************************************** ************************************************************************** */ -#if __FreeBSD_version < 500005 - static int arcmsr_close(dev_t dev, int flags, int fmt, struct proc *proc) -#else - #if __FreeBSD_version < 503000 - static int arcmsr_close(dev_t dev, int flags, int fmt, struct thread *proc) - #else - static int arcmsr_close(struct cdev *dev, int flags, int fmt, struct thread *proc) - #endif -#endif +static int arcmsr_close(struct cdev *dev, int flags, int fmt, struct thread *proc) { - #if __FreeBSD_version < 503000 - struct AdapterControlBlock *acb = dev->si_drv1; - #else - int unit = dev2unit(dev); - struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); - #endif - if(acb == NULL) { + int unit = dev2unit(dev); + struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); + + if (acb == NULL) { return ENXIO; } return 0; @@ -323,24 +259,12 @@ static struct cdevsw arcmsr_cdevsw = { ************************************************************************** ************************************************************************** */ -#if __FreeBSD_version < 500005 - static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct proc *proc) -#else - #if __FreeBSD_version < 503000 - static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc) - #else - static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc) - #endif -#endif +static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc) { - #if __FreeBSD_version < 503000 - struct AdapterControlBlock *acb = dev->si_drv1; - #else - int unit = dev2unit(dev); - struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); - #endif - - if(acb == NULL) { + int unit = dev2unit(dev); + struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit); + + if (acb == NULL) { return ENXIO; } return (arcmsr_iop_ioctlcmd(acb, ioctl_cmd, arg)); @@ -370,19 +294,20 @@ static u_int32_t arcmsr_disable_allintr( struct Adapte break; case ACB_ADAPTER_TYPE_C: { /* disable all outbound interrupt */ - intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask) ; /* disable outbound message0 int */ + intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask); /* disable outbound message0 int */ CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE); } break; case ACB_ADAPTER_TYPE_D: { /* disable all outbound interrupt */ - intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable) ; /* disable outbound message0 int */ + intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable); /* disable outbound message0 int */ CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE); } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { /* disable all outbound interrupt */ - intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask) ; /* disable outbound message0 int */ + intmask_org = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_mask); /* disable outbound message0 int */ CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org | ARCMSR_HBEMU_ALL_INTMASKENABLE); } break; @@ -428,7 +353,8 @@ static void arcmsr_enable_allintr( struct AdapterContr acb->outbound_int_enable = mask; } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { /* enable outbound Post Queue, outbound doorbell Interrupt */ mask = ~(ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR); CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org & mask); @@ -527,7 +453,7 @@ static u_int8_t arcmsr_hbe_wait_msgint_ready(struct Ad { u_int32_t Index, read_doorbell; u_int8_t Retries = 0x00; - + do { for(Index=0; Index < 100; Index++) { read_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell); @@ -618,7 +544,7 @@ static void arcmsr_flush_hbd_cache(struct AdapterContr static void arcmsr_flush_hbe_cache(struct AdapterControlBlock *acb) { int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ - + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); @@ -653,7 +579,8 @@ static void arcmsr_flush_adapter_cache(struct AdapterC arcmsr_flush_hbd_cache(acb); } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { arcmsr_flush_hbe_cache(acb); } break; @@ -809,7 +736,8 @@ static void arcmsr_abort_allcmd(struct AdapterControlB arcmsr_abort_hbd_allcmd(acb); } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { arcmsr_abort_hbe_allcmd(acb); } break; @@ -920,6 +848,7 @@ static void arcmsr_drain_donequeue(struct AdapterContr srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0)); /*frame must be 32 bytes aligned*/ break; case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: srb = acb->psrb_pool[flag_srb]; break; default: @@ -1010,7 +939,6 @@ static void arcmsr_done4abort_postqueue(struct Adapter } break; case ACB_ADAPTER_TYPE_C: { - while((CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low); error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE; @@ -1018,14 +946,15 @@ static void arcmsr_done4abort_postqueue(struct Adapter } } break; - case ACB_ADAPTER_TYPE_D: { - arcmsr_hbd_postqueue_isr(acb); - } + case ACB_ADAPTER_TYPE_D: + arcmsr_hbd_postqueue_isr(acb); break; - case ACB_ADAPTER_TYPE_E: { - arcmsr_hbe_postqueue_isr(acb); - } + case ACB_ADAPTER_TYPE_E: + arcmsr_hbe_postqueue_isr(acb); break; + case ACB_ADAPTER_TYPE_F: + arcmsr_hbf_postqueue_isr(acb); + break; } } /* @@ -1244,8 +1173,20 @@ static void arcmsr_post_srb(struct AdapterControlBlock ccb_post_stamp = (srb->smid | ((arc_cdb_size-1) >> 6)); CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_high, 0); CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp); - } + } break; + case ACB_ADAPTER_TYPE_F: { + u_int32_t ccb_post_stamp, arc_cdb_size; + + if (srb->arc_cdb_size <= 0x300) + arc_cdb_size = (srb->arc_cdb_size - 1) >> 6 | 1; + else + arc_cdb_size = (((srb->arc_cdb_size + 0xff) >> 8) + 2) << 1 | 1; + ccb_post_stamp = (srb->smid | arc_cdb_size); + CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_queueport_high, 0); + CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp); + } + break; } } /* @@ -1283,10 +1224,13 @@ static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct break; case ACB_ADAPTER_TYPE_E: { struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu; - + qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer; } break; + case ACB_ADAPTER_TYPE_F: + qbuffer = (struct QBUFFER *)acb->message_rbuffer; + break; } return(qbuffer); } @@ -1325,10 +1269,13 @@ static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct break; case ACB_ADAPTER_TYPE_E: { struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu; - + qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer; } break; + case ACB_ADAPTER_TYPE_F: + qbuffer = (struct QBUFFER *)acb->message_wbuffer; + break; } return(qbuffer); } @@ -1360,7 +1307,8 @@ static void arcmsr_iop_message_read(struct AdapterCont CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ); } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { /* let IOP know data has been read */ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK; CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); @@ -1408,7 +1356,8 @@ static void arcmsr_iop_message_wrote(struct AdapterCon CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY); } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { /* ** push inbound doorbell tell iop, driver data write ok ** and wait reply on next hwinterrupt for next Qbuffer post @@ -1509,7 +1458,8 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterCon arcmsr_stop_hbd_bgrb(acb); } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { arcmsr_stop_hbe_bgrb(acb); } break; @@ -1538,7 +1488,6 @@ static void arcmsr_poll(struct cam_sim *psim) */ static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer) { - u_int8_t *pQbuffer; u_int8_t *buf1 = NULL; u_int32_t *iop_data, *buf2 = NULL; @@ -1583,7 +1532,6 @@ static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struc */ static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer) { - u_int8_t *pQbuffer; u_int8_t *iop_data; u_int32_t iop_len; @@ -1750,7 +1698,7 @@ static void arcmsr_rescan_lun(struct AdapterControlBlo union ccb *ccb; if ((ccb = (union ccb *)xpt_alloc_ccb_nowait()) == NULL) - return; + return; if (xpt_create_path(&path, NULL, cam_sim_path(acb->psim), target, lun) != CAM_REQ_CMP) { xpt_free_ccb(ccb); @@ -1765,7 +1713,6 @@ static void arcmsr_rescan_lun(struct AdapterControlBlo xpt_action(ccb); } - static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, int lun) { struct CommandControlBlock *srb; @@ -1840,10 +1787,18 @@ static void arcmsr_dr_handle(struct AdapterControlBloc devicemap = offsetof(struct HBE_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); for (target = 0; target < 4; target++) { - deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); - devicemap += 4; + deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap); + devicemap += 4; } break; + case ACB_ADAPTER_TYPE_F: + devicemap = ARCMSR_FW_DEVMAP_OFFSET; + for (target = 0; target < 4; target++) + { + deviceMapCurrent[target] = acb->msgcode_rwbuffer[devicemap]; + devicemap += 1; + } + break; } if(acb->acb_flags & ACB_F_BUS_HANG_ON) @@ -1854,7 +1809,7 @@ static void arcmsr_dr_handle(struct AdapterControlBloc ** adapter posted CONFIG message ** copy the new map, note if there are differences with the current map */ - pDevMap = (u_int8_t *)&deviceMapCurrent[0]; + pDevMap = (u_int8_t *)&deviceMapCurrent[0]; for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) { if (*pDevMap != acb->device_map[target]) @@ -2041,7 +1996,7 @@ static void arcmsr_hbd_doorbell_isr(struct AdapterCont static void arcmsr_hbe_doorbell_isr(struct AdapterControlBlock *acb) { u_int32_t doorbell_status, in_doorbell; - + /* ******************************************************************* ** Maybe here we need to check wrqbuffer_lock is lock or not @@ -2082,7 +2037,7 @@ static void arcmsr_hba_postqueue_isr(struct AdapterCon while((flag_srb = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_queueport)) != 0xFFFFFFFF) { /* check if command done with no error*/ - error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE; + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); } /*drain reply FIFO*/ } @@ -2111,7 +2066,7 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterCon index %= ARCMSR_MAX_HBB_POSTQUEUE; /*if last index number set it to 0 */ phbbmu->doneq_index = index; /* check if command done with no error*/ - error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; + error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE; arcmsr_drain_donequeue(acb, flag_srb, error); } /*drain reply FIFO*/ } @@ -2129,7 +2084,7 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterCon ** areca cdb command done ***************************************************************************** */ - bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); + bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); do { flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low); if (flag_srb == 0xFFFFFFFF) @@ -2139,7 +2094,7 @@ static void arcmsr_hbc_postqueue_isr(struct AdapterCon arcmsr_drain_donequeue(acb, flag_srb, error); throttling++; if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) { - CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING); + CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING); throttling = 0; } } while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR); @@ -2212,7 +2167,7 @@ static void arcmsr_hbe_postqueue_isr(struct AdapterCon u_int16_t error; uint32_t doneq_index; uint16_t cmdSMID; - + /* ***************************************************************************** ** areca cdb command done @@ -2231,6 +2186,35 @@ static void arcmsr_hbe_postqueue_isr(struct AdapterCon acb->doneq_index = doneq_index; CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_consumer_index, doneq_index); } + +static void arcmsr_hbf_postqueue_isr(struct AdapterControlBlock *acb) +{ + uint16_t error; + uint32_t doneq_index; + uint16_t cmdSMID; + + /* + ***************************************************************************** + ** areca cdb command done + ***************************************************************************** + */ + bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + doneq_index = acb->doneq_index; + while (1) { + cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID; + if (cmdSMID == 0xffff) + break; + error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE; + arcmsr_drain_donequeue(acb, (u_int32_t)cmdSMID, error); + acb->pCompletionQ[doneq_index].cmdSMID = 0xffff; + doneq_index++; + if (doneq_index >= acb->completionQ_entry) + doneq_index = 0; + } + acb->doneq_index = doneq_index; + CHIP_REG_WRITE32(HBF_MessageUnit, 0, reply_post_consumer_index, doneq_index); +} + /* ********************************************************************** ********************************************************************** @@ -2392,6 +2376,34 @@ static void arcmsr_handle_hbe_isr( struct AdapterContr host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status); } while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR)); } + +static void arcmsr_handle_hbf_isr( struct AdapterControlBlock *acb) +{ + u_int32_t host_interrupt_status; + /* + ********************************************* + ** check outbound intstatus + ********************************************* + */ + host_interrupt_status = CHIP_REG_READ32(HBF_MessageUnit, 0, host_int_status) & + (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | + ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR); + if(!host_interrupt_status) { + /*it must be share irq*/ + return; + } + do { + /* MU doorbell interrupts*/ + if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR) { + arcmsr_hbe_doorbell_isr(acb); + } + /* MU post queue interrupts*/ + if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR) { + arcmsr_hbf_postqueue_isr(acb); + } + host_interrupt_status = CHIP_REG_READ32(HBF_MessageUnit, 0, host_int_status); + } while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR)); +} /* ****************************************************************************** ****************************************************************************** @@ -2414,6 +2426,9 @@ static void arcmsr_interrupt(struct AdapterControlBloc case ACB_ADAPTER_TYPE_E: arcmsr_handle_hbe_isr(acb); break; + case ACB_ADAPTER_TYPE_F: + arcmsr_handle_hbf_isr(acb); + break; default: printf("arcmsr%d: interrupt service," " unknown adapter type =%d\n", acb->pci_unit, acb->adapter_type); @@ -2444,7 +2459,7 @@ static void arcmsr_polling_devmap(void *arg) CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); break; - case ACB_ADAPTER_TYPE_B: { + case ACB_ADAPTER_TYPE_B: { struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu; WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG); } @@ -2459,13 +2474,24 @@ static void arcmsr_polling_devmap(void *arg) CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); break; - case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_E: CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); - break; - } + break; + case ACB_ADAPTER_TYPE_F: { + u_int32_t outMsg1 = CHIP_REG_READ32(HBF_MessageUnit, 0, outbound_msgaddr1); + if (!(outMsg1 & ARCMSR_HBFMU_MESSAGE_FIRMWARE_OK) || + (outMsg1 & ARCMSR_HBFMU_MESSAGE_NO_VOLUME_CHANGE)) + goto nxt6s; + CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + break; + } + } +nxt6s: if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0) { callout_reset(&acb->devmap_callout, 5 * hz, arcmsr_polling_devmap, acb); /* polling per 5 seconds */ @@ -3064,7 +3090,7 @@ static void arcmsr_handle_virtual_command(struct Adapt case INQUIRY: { unsigned char inqdata[36]; char *buffer = pccb->csio.data_ptr; - + inqdata[0] = T_PROCESSOR; /* Periph Qualifier & Periph Dev Type */ inqdata[1] = 0; /* rem media bit & Dev Type Modifier */ inqdata[2] = 0; /* ISO, ECMA, & ANSI versions */ @@ -3158,7 +3184,6 @@ static void arcmsr_action(struct cam_sim *psim, union strlcpy(cpi->hba_vid, "ARCMSR", HBA_IDLEN); strlcpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(psim); - #ifdef CAM_NEW_TRAN_CODE if(acb->adapter_bus_speed == ACB_BUS_SPEED_12G) cpi->base_transfer_speed = 1200000; else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G) @@ -3181,14 +3206,13 @@ static void arcmsr_action(struct cam_sim *psim, union cpi->protocol_version = SCSI_REV_2; } cpi->protocol = PROTO_SCSI; - #endif cpi->ccb_h.status |= CAM_REQ_CMP; xpt_done(pccb); break; } case XPT_ABORT: { union ccb *pabort_ccb; - + pabort_ccb = pccb->cab.abort_ccb; switch (pabort_ccb->ccb_h.func_code) { case XPT_ACCEPT_TARGET_IO: @@ -3239,7 +3263,6 @@ static void arcmsr_action(struct cam_sim *psim, union break; } cts = &pccb->cts; - #ifdef CAM_NEW_TRAN_CODE { struct ccb_trans_settings_scsi *scsi; struct ccb_trans_settings_spi *spi; @@ -3286,22 +3309,6 @@ static void arcmsr_action(struct cam_sim *psim, union | CTS_SPI_VALID_BUS_WIDTH; } } - #else - { - cts->flags = (CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); - if (acb->adapter_bus_speed == ACB_BUS_SPEED_6G) - cts->sync_period = 1; - else - cts->sync_period = 2; - cts->sync_offset = 32; - cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; - cts->valid = CCB_TRANS_SYNC_RATE_VALID | - CCB_TRANS_SYNC_OFFSET_VALID | - CCB_TRANS_BUS_WIDTH_VALID | - CCB_TRANS_DISC_VALID | - CCB_TRANS_TQ_VALID; - } - #endif pccb->ccb_h.status |= CAM_REQ_CMP; xpt_done(pccb); break; @@ -3317,38 +3324,7 @@ static void arcmsr_action(struct cam_sim *psim, union xpt_done(pccb); break; } -#if __FreeBSD_version >= 500000 cam_calc_geometry(&pccb->ccg, 1); -#else - { - struct ccb_calc_geometry *ccg; - u_int32_t size_mb; - u_int32_t secs_per_cylinder; - - ccg = &pccb->ccg; - if (ccg->block_size == 0) { - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; - } - if(((1024L * 1024L)/ccg->block_size) < 0) { - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; - } - size_mb = ccg->volume_size/((1024L * 1024L)/ccg->block_size); - if(size_mb > 1024 ) { - ccg->heads = 255; - ccg->secs_per_track = 63; - } else { - ccg->heads = 64; - ccg->secs_per_track = 32; - } - secs_per_cylinder = ccg->heads * ccg->secs_per_track; - ccg->cylinders = ccg->volume_size / secs_per_cylinder; - pccb->ccb_h.status |= CAM_REQ_CMP; - } -#endif xpt_done(pccb); break; default: @@ -3441,6 +3417,7 @@ static void arcmsr_start_adapter_bgrb(struct AdapterCo arcmsr_start_hbd_bgrb(acb); break; case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: arcmsr_start_hbe_bgrb(acb); break; } @@ -3582,7 +3559,7 @@ polling_ccb_retry: break; } if (acb->srboutstandingcount == 0) { - break; + break; } goto polling_ccb_retry; } @@ -3674,7 +3651,7 @@ static void arcmsr_polling_hbe_srbdone(struct AdapterC struct CommandControlBlock *srb; u_int32_t poll_srb_done=0, poll_count=0, doneq_index; u_int16_t error, cmdSMID; - + polling_ccb_retry: poll_count++; bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); @@ -3685,12 +3662,12 @@ polling_ccb_retry: break;/*chip FIFO no ccb for completion already*/ } else { UDELAY(25000); - if ((poll_count > 100) && (poll_srb != NULL)) { + if ((poll_count > 100) && (poll_srb != NULL)) { break; } - if (acb->srboutstandingcount == 0) { - break; - } + if (acb->srboutstandingcount == 0) { + break; + } goto polling_ccb_retry; } } @@ -3726,25 +3703,21 @@ polling_ccb_retry: static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { - arcmsr_polling_hba_srbdone(acb, poll_srb); - } + case ACB_ADAPTER_TYPE_A: + arcmsr_polling_hba_srbdone(acb, poll_srb); break; - case ACB_ADAPTER_TYPE_B: { - arcmsr_polling_hbb_srbdone(acb, poll_srb); - } + case ACB_ADAPTER_TYPE_B: + arcmsr_polling_hbb_srbdone(acb, poll_srb); break; - case ACB_ADAPTER_TYPE_C: { - arcmsr_polling_hbc_srbdone(acb, poll_srb); - } + case ACB_ADAPTER_TYPE_C: + arcmsr_polling_hbc_srbdone(acb, poll_srb); break; - case ACB_ADAPTER_TYPE_D: { - arcmsr_polling_hbd_srbdone(acb, poll_srb); - } + case ACB_ADAPTER_TYPE_D: + arcmsr_polling_hbd_srbdone(acb, poll_srb); break; - case ACB_ADAPTER_TYPE_E: { - arcmsr_polling_hbe_srbdone(acb, poll_srb); - } + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: + arcmsr_polling_hbe_srbdone(acb, poll_srb); break; } } @@ -3961,14 +3934,14 @@ static void arcmsr_get_hbe_config(struct AdapterContro size_t iop_firm_version = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/ size_t iop_device_map = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]); int i; - + CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); if(!arcmsr_hbe_wait_msgint_ready(acb)) { printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit); } - + i = 0; while(i < 8) { *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); @@ -4004,29 +3977,81 @@ static void arcmsr_get_hbe_config(struct AdapterContro ********************************************************************** ********************************************************************** */ +static void arcmsr_get_hbf_config(struct AdapterControlBlock *acb) +{ + u_int32_t *acb_firm_model = (u_int32_t *)acb->firm_model; + u_int32_t *acb_firm_version = (u_int32_t *)acb->firm_version; + u_int32_t *acb_device_map = (u_int32_t *)acb->device_map; + size_t iop_firm_model = ARCMSR_FW_MODEL_OFFSET; /*firm_model,15,60-67*/ + size_t iop_firm_version = ARCMSR_FW_VERS_OFFSET; /*firm_version,17,68-83*/ + size_t iop_device_map = ARCMSR_FW_DEVMAP_OFFSET; + int i; + + CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + if(!arcmsr_hbe_wait_msgint_ready(acb)) + printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit); + + i = 0; + while(i < 2) { + *acb_firm_model = acb->msgcode_rwbuffer[iop_firm_model]; + /* 8 bytes firm_model, 15, 60-67*/ + acb_firm_model++; + iop_firm_model++; + i++; + } + i = 0; + while(i < 4) { + *acb_firm_version = acb->msgcode_rwbuffer[iop_firm_version]; + /* 16 bytes firm_version, 17, 68-83*/ + acb_firm_version++; + iop_firm_version++; + i++; + } + i = 0; + while(i < 4) { + *acb_device_map = acb->msgcode_rwbuffer[iop_device_map]; + acb_device_map++; + iop_device_map++; + i++; + } + printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version); + acb->firm_request_len = acb->msgcode_rwbuffer[1]; /*firm_request_len, 1, 04-07*/ + acb->firm_numbers_queue = acb->msgcode_rwbuffer[2]; /*firm_numbers_queue, 2, 08-11*/ + acb->firm_sdram_size = acb->msgcode_rwbuffer[3]; /*firm_sdram_size, 3, 12-15*/ + acb->firm_ide_channels = acb->msgcode_rwbuffer[4]; /*firm_ide_channels, 4, 16-19*/ + acb->firm_cfg_version = acb->msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]; /*firm_cfg_version, 25*/ + if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD) + acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1; + else + acb->maxOutstanding = acb->firm_numbers_queue - 1; +} +/* +********************************************************************** +********************************************************************** +*/ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { - arcmsr_get_hba_config(acb); - } + case ACB_ADAPTER_TYPE_A: + arcmsr_get_hba_config(acb); break; - case ACB_ADAPTER_TYPE_B: { - arcmsr_get_hbb_config(acb); - } + case ACB_ADAPTER_TYPE_B: + arcmsr_get_hbb_config(acb); break; - case ACB_ADAPTER_TYPE_C: { - arcmsr_get_hbc_config(acb); - } + case ACB_ADAPTER_TYPE_C: + arcmsr_get_hbc_config(acb); break; - case ACB_ADAPTER_TYPE_D: { - arcmsr_get_hbd_config(acb); - } + case ACB_ADAPTER_TYPE_D: + arcmsr_get_hbd_config(acb); break; - case ACB_ADAPTER_TYPE_E: { - arcmsr_get_hbe_config(acb); - } + case ACB_ADAPTER_TYPE_E: + arcmsr_get_hbe_config(acb); break; + case ACB_ADAPTER_TYPE_F: + arcmsr_get_hbf_config(acb); + break; } } /* @@ -4088,7 +4113,8 @@ static void arcmsr_wait_firmware_ready( struct Adapter } } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { while ((CHIP_REG_READ32(HBE_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0) { if (timeout++ > 4000) /* (4000*15)/1000 = 60 sec */ @@ -4141,7 +4167,8 @@ static void arcmsr_clear_doorbell_queue_buffer( struct CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ); } break; - case ACB_ADAPTER_TYPE_E: { + case ACB_ADAPTER_TYPE_E: + case ACB_ADAPTER_TYPE_F: { /* empty doorbell Qbuffer if door bell ringed */ acb->in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell); CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /*clear doorbell interrupt */ @@ -4276,6 +4303,27 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterCont } } break; + case ACB_ADAPTER_TYPE_F: { + u_int32_t cdb_phyaddr_lo32; + cdb_phyaddr_lo32 = srb_phyaddr_lo32 + offsetof(struct CommandControlBlock, arcmsr_cdb); + acb->msgcode_rwbuffer[0] = ARCMSR_SIGNATURE_SET_CONFIG; + acb->msgcode_rwbuffer[1] = ARCMSR_SIGNATURE_1886; + acb->msgcode_rwbuffer[2] = cdb_phyaddr_lo32; + acb->msgcode_rwbuffer[3] = srb_phyaddr_hi32; + acb->msgcode_rwbuffer[4] = SRB_SIZE; + cdb_phyaddr_lo32 = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE; + acb->msgcode_rwbuffer[5] = cdb_phyaddr_lo32; + acb->msgcode_rwbuffer[6] = srb_phyaddr_hi32; + acb->msgcode_rwbuffer[7] = COMPLETION_Q_POOL_SIZE; + CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG); + acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; + CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell); + if(!arcmsr_hbe_wait_msgint_ready(acb)) { + printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit); + return FALSE; + } + } + break; } return (TRUE); } @@ -4339,7 +4387,7 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_seg return; } if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D) - || (acb->adapter_type == ACB_ADAPTER_TYPE_E)) + || (acb->adapter_type == ACB_ADAPTER_TYPE_E) || (acb->adapter_type == ACB_ADAPTER_TYPE_F)) { srb_tmp->cdb_phyaddr_low = srb_phyaddr; srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16); @@ -4354,6 +4402,15 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_seg } if (acb->adapter_type == ACB_ADAPTER_TYPE_E) acb->pCompletionQ = (pCompletion_Q)srb_tmp; + else if (acb->adapter_type == ACB_ADAPTER_TYPE_F) { + acb->pCompletionQ = (pCompletion_Q)srb_tmp; + acb->completeQ_phys = srb_phyaddr; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011090139.0A91dtb8023272>