aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/advansys/advansys.c4
-rw-r--r--sys/dev/agp/agp.c2
-rw-r--r--sys/dev/aha/aha.c4
-rw-r--r--sys/dev/ahci/ahci.c4
-rw-r--r--sys/dev/al_eth/al_eth.c4
-rw-r--r--sys/dev/al_eth/al_init_eth_lm.c2
-rw-r--r--sys/dev/an/if_an.c2
-rw-r--r--sys/dev/arcmsr/arcmsr.c15
-rw-r--r--sys/dev/ata/ata-all.c4
-rw-r--r--sys/dev/bce/if_bce.c2
-rw-r--r--sys/dev/beri/virtio/virtio_block.c2
-rw-r--r--sys/dev/bhnd/cores/chipc/chipc_slicer.c12
-rw-r--r--sys/dev/bhnd/cores/chipc/chipc_slicer.h8
-rw-r--r--sys/dev/bhnd/cores/usb/bhnd_usb.c4
-rw-r--r--sys/dev/buslogic/bt.c4
-rw-r--r--sys/dev/buslogic/bt_pci.c4
-rw-r--r--sys/dev/ce/if_ce.c4
-rw-r--r--sys/dev/cm/smc90cx6.c8
-rw-r--r--sys/dev/cp/if_cp.c4
-rw-r--r--sys/dev/ctau/ctddk.c2
-rw-r--r--sys/dev/ctau/if_ct.c4
-rw-r--r--sys/dev/cx/cxddk.c2
-rw-r--r--sys/dev/cx/if_cx.c4
-rw-r--r--sys/dev/de/if_de.c4
-rw-r--r--sys/dev/e1000/if_em.c101
-rw-r--r--sys/dev/ed/if_ed.c2
-rw-r--r--sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c33
-rw-r--r--sys/dev/extres/clk/clk_div.c3
-rw-r--r--sys/dev/fatm/if_fatm.c2
-rw-r--r--sys/dev/fdt/fdt_slicer.c36
-rw-r--r--sys/dev/fe/if_fe.c4
-rw-r--r--sys/dev/ffec/if_ffecreg.h21
-rw-r--r--sys/dev/firewire/if_fwip.c2
-rw-r--r--sys/dev/hptiop/hptiop.c2
-rw-r--r--sys/dev/hptmv/entry.c12
-rw-r--r--sys/dev/hptmv/gui_lib.c8
-rw-r--r--sys/dev/hptmv/hptproc.c2
-rw-r--r--sys/dev/hptmv/ioctl.c2
-rw-r--r--sys/dev/iicbus/if_ic.c2
-rw-r--r--sys/dev/isp/isp_freebsd.c849
-rw-r--r--sys/dev/isp/isp_freebsd.h62
-rw-r--r--sys/dev/isp/isp_pci.c16
-rw-r--r--sys/dev/isp/isp_target.c5
-rw-r--r--sys/dev/iwi/if_iwi.c2
-rw-r--r--sys/dev/iwm/if_iwm.c921
-rw-r--r--sys/dev/iwm/if_iwm_7000.c126
-rw-r--r--sys/dev/iwm/if_iwm_8000.c92
-rw-r--r--sys/dev/iwm/if_iwm_config.h135
-rw-r--r--sys/dev/iwm/if_iwm_pcie_trans.c1
-rw-r--r--sys/dev/iwm/if_iwm_util.c65
-rw-r--r--sys/dev/iwm/if_iwm_util.h4
-rw-r--r--sys/dev/iwm/if_iwmreg.h16
-rw-r--r--sys/dev/iwm/if_iwmvar.h64
-rw-r--r--sys/dev/iwn/if_iwn.c7
-rw-r--r--sys/dev/jedec_ts/jedec_ts.c2
-rw-r--r--sys/dev/le/am7990.c2
-rw-r--r--sys/dev/le/am79900.c2
-rw-r--r--sys/dev/le/lance.c2
-rw-r--r--sys/dev/md/md.c2
-rw-r--r--sys/dev/mvs/mvs.c4
-rw-r--r--sys/dev/mwl/if_mwl.c12
-rw-r--r--sys/dev/nand/nfc_rb.c39
-rw-r--r--sys/dev/ncr/ncr.c8
-rw-r--r--sys/dev/netmap/netmap_freebsd.c2
-rw-r--r--sys/dev/netmap/netmap_mem2.c2
-rw-r--r--sys/dev/nvme/nvme_sim.c8
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c2
-rw-r--r--sys/dev/patm/if_patm_tx.c2
-rw-r--r--sys/dev/pccard/pccard.c6
-rw-r--r--sys/dev/pms/RefTisa/sallsdk/spc/sainit.c2
-rw-r--r--sys/dev/pms/RefTisa/tisa/sassata/common/tdioctl.c2
-rw-r--r--sys/dev/pms/freebsd/driver/ini/src/agtiapi.c8
-rw-r--r--sys/dev/ppbus/if_plip.c4
-rw-r--r--sys/dev/ppbus/ppbconf.c2
-rw-r--r--sys/dev/ppc/ppc.c6
-rw-r--r--sys/dev/qlxgbe/ql_os.c1
-rw-r--r--sys/dev/ral/rt2661.c2
-rw-r--r--sys/dev/sbni/if_sbni_isa.c2
-rw-r--r--sys/dev/sdhci/sdhci_fdt_gpio.c2
-rw-r--r--sys/dev/siis/siis.c4
-rw-r--r--sys/dev/sn/if_sn.c8
-rw-r--r--sys/dev/sym/sym_hipd.c11
-rw-r--r--sys/dev/trm/trm.c162
-rw-r--r--sys/dev/usb/storage/cfumass.c1075
-rw-r--r--sys/dev/usb/wlan/if_zyd.c2
-rw-r--r--sys/dev/vmware/vmxnet3/if_vmxvar.h4
-rw-r--r--sys/dev/vx/if_vx.c4
-rw-r--r--sys/dev/xen/timer/timer.c14
88 files changed, 2712 insertions, 1404 deletions
diff --git a/sys/dev/advansys/advansys.c b/sys/dev/advansys/advansys.c
index 8ca81ae55459..a875fe5ccb6a 100644
--- a/sys/dev/advansys/advansys.c
+++ b/sys/dev/advansys/advansys.c
@@ -232,10 +232,6 @@ adv_action(struct cam_sim *sim, union ccb *ccb)
break;
}
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
- case XPT_EN_LUN: /* Enable LUN as a target */
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
diff --git a/sys/dev/agp/agp.c b/sys/dev/agp/agp.c
index 7d024d047246..47c0aaa046ce 100644
--- a/sys/dev/agp/agp.c
+++ b/sys/dev/agp/agp.c
@@ -820,7 +820,7 @@ agp_close(struct cdev *kdev, int fflag, int devtype, struct thread *td)
/*
* Clear the GATT and force release on last close
*/
- while ((mem = TAILQ_FIRST(&sc->as_memory)) != 0) {
+ while ((mem = TAILQ_FIRST(&sc->as_memory)) != NULL) {
if (mem->am_is_bound)
AGP_UNBIND_MEMORY(dev, mem);
AGP_FREE_MEMORY(dev, mem);
diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c
index 233339f8c434..d2709a72e678 100644
--- a/sys/dev/aha/aha.c
+++ b/sys/dev/aha/aha.c
@@ -831,10 +831,6 @@ ahaaction(struct cam_sim *sim, union ccb *ccb)
}
break;
}
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 7083afb10cba..c5064f349e34 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -2578,10 +2578,6 @@ ahciaction(struct cam_sim *sim, union ccb *ccb)
}
ahci_begin_transaction(ch, ccb);
return;
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
diff --git a/sys/dev/al_eth/al_eth.c b/sys/dev/al_eth/al_eth.c
index 6a58fb5c5319..79523fd189c3 100644
--- a/sys/dev/al_eth/al_eth.c
+++ b/sys/dev/al_eth/al_eth.c
@@ -2009,7 +2009,7 @@ al_eth_enable_msix(struct al_eth_adapter *adapter)
adapter->msix_entries = malloc(msix_vecs*sizeof(*adapter->msix_entries),
M_IFAL, M_ZERO | M_WAITOK);
- if (adapter->msix_entries == 0) {
+ if (adapter->msix_entries == NULL) {
device_printf_dbg(adapter->dev, "failed to allocate"
" msix_entries %d\n", msix_vecs);
rc = ENOMEM;
@@ -3544,7 +3544,7 @@ al_miibus_linkchg(device_t dev)
uint8_t duplex = 0;
uint8_t speed = 0;
- if (adapter->mii == 0)
+ if (adapter->mii == NULL)
return;
if ((adapter->netdev->if_flags & IFF_UP) == 0)
diff --git a/sys/dev/al_eth/al_init_eth_lm.c b/sys/dev/al_eth/al_init_eth_lm.c
index f6aebda6f105..96da4bb34d96 100644
--- a/sys/dev/al_eth/al_init_eth_lm.c
+++ b/sys/dev/al_eth/al_init_eth_lm.c
@@ -1168,7 +1168,7 @@ al_eth_lm_link_detection(struct al_eth_lm_context *lm_context,
boolean_t lm_pause = lm_context->lm_pause(lm_context->i2c_context);
if (lm_pause == TRUE) {
*new_mode = AL_ETH_LM_MODE_DISCONNECTED;
- if (link_fault != 0) {
+ if (link_fault != NULL) {
if (lm_context->link_state == AL_ETH_LM_LINK_UP)
*link_fault = FALSE;
else
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index dc3fbf2adf58..cae604c055c1 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -3057,7 +3057,7 @@ static void
an_cache_store(struct an_softc *sc, struct ether_header *eh, struct mbuf *m,
u_int8_t rx_rssi, u_int8_t rx_quality)
{
- struct ip *ip = 0;
+ struct ip *ip = NULL;
int i;
static int cache_slot = 0; /* use this cache entry */
static int wrapindex = 0; /* next "free" cache entry */
diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c
index f293db0a7be3..8b0258ba2687 100644
--- a/sys/dev/arcmsr/arcmsr.c
+++ b/sys/dev/arcmsr/arcmsr.c
@@ -1398,8 +1398,8 @@ static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb
struct QBUFFER *prbuffer) {
u_int8_t *pQbuffer;
- u_int8_t *buf1 = 0;
- u_int32_t *iop_data, *buf2 = 0;
+ u_int8_t *buf1 = NULL;
+ u_int32_t *iop_data, *buf2 = NULL;
u_int32_t iop_len, data_len;
iop_data = (u_int32_t *)prbuffer->data;
@@ -1494,8 +1494,8 @@ static void arcmsr_Write_data_2iop_wqbuffer_D(struct AdapterControlBlock *acb)
{
u_int8_t *pQbuffer;
struct QBUFFER *pwbuffer;
- u_int8_t *buf1 = 0;
- u_int32_t *iop_data, *buf2 = 0;
+ u_int8_t *buf1 = NULL;
+ u_int32_t *iop_data, *buf2 = NULL;
u_int32_t allxfer_len = 0, data_len;
if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
@@ -2883,12 +2883,6 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
}
break;
}
- case XPT_TARGET_IO: {
- /* target mode not yet support vendor specific commands. */
- pccb->ccb_h.status |= CAM_REQ_CMP;
- xpt_done(pccb);
- break;
- }
case XPT_PATH_INQ: {
struct ccb_pathinq *cpi = &pccb->cpi;
@@ -2938,7 +2932,6 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
pabort_ccb = pccb->cab.abort_ccb;
switch (pabort_ccb->ccb_h.func_code) {
case XPT_ACCEPT_TARGET_IO:
- case XPT_IMMED_NOTIFY:
case XPT_CONT_TARGET_IO:
if(arcmsr_seek_cmd2abort(pabort_ccb)==TRUE) {
pabort_ccb->ccb_h.status |= CAM_REQ_ABORTED;
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index a4fcbc179c05..e336c444e97c 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -1013,10 +1013,6 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
}
ata_cam_begin_transaction(dev, ccb);
return;
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 0b406e23cb71..cdf234ee4a5e 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -2800,7 +2800,7 @@ bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
if (align_start || align_end) {
buf = malloc(len32, M_DEVBUF, M_NOWAIT);
- if (buf == 0) {
+ if (buf == NULL) {
rc = ENOMEM;
goto bce_nvram_write_exit;
}
diff --git a/sys/dev/beri/virtio/virtio_block.c b/sys/dev/beri/virtio/virtio_block.c
index 405746c52b51..50bb7f3a53bd 100644
--- a/sys/dev/beri/virtio/virtio_block.c
+++ b/sys/dev/beri/virtio/virtio_block.c
@@ -457,7 +457,7 @@ beri_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
sc->opened = 1;
break;
case MDIOCDETACH:
- if (sc->vnode == 0) {
+ if (sc->vnode == NULL) {
/* File not opened */
return (1);
}
diff --git a/sys/dev/bhnd/cores/chipc/chipc_slicer.c b/sys/dev/bhnd/cores/chipc/chipc_slicer.c
index 45cac4d3794c..4c6969d7ff2f 100644
--- a/sys/dev/bhnd/cores/chipc/chipc_slicer.c
+++ b/sys/dev/bhnd/cores/chipc/chipc_slicer.c
@@ -63,10 +63,12 @@ chipc_register_slicer(chipc_flash flash_type)
switch (flash_type) {
case CHIPC_SFLASH_AT:
case CHIPC_SFLASH_ST:
- flash_register_slicer(chipc_slicer_spi);
+ flash_register_slicer(chipc_slicer_spi, FLASH_SLICES_TYPE_SPI,
+ TRUE);
break;
case CHIPC_PFLASH_CFI:
- flash_register_slicer(chipc_slicer_cfi);
+ flash_register_slicer(chipc_slicer_cfi, FLASH_SLICES_TYPE_CFI,
+ TRUE);
break;
default:
/* Unsupported */
@@ -75,7 +77,8 @@ chipc_register_slicer(chipc_flash flash_type)
}
int
-chipc_slicer_cfi(device_t dev, struct flash_slice *slices, int *nslices)
+chipc_slicer_cfi(device_t dev, const char *provider __unused,
+ struct flash_slice *slices, int *nslices)
{
struct cfi_softc *sc;
device_t parent;
@@ -100,7 +103,8 @@ chipc_slicer_cfi(device_t dev, struct flash_slice *slices, int *nslices)
}
int
-chipc_slicer_spi(device_t dev, struct flash_slice *slices, int *nslices)
+chipc_slicer_spi(device_t dev, const char *provider __unused,
+ struct flash_slice *slices, int *nslices)
{
struct chipc_spi_softc *sc;
device_t chipc, spi, spibus;
diff --git a/sys/dev/bhnd/cores/chipc/chipc_slicer.h b/sys/dev/bhnd/cores/chipc/chipc_slicer.h
index 4c35caa1af25..6f296262891a 100644
--- a/sys/dev/bhnd/cores/chipc/chipc_slicer.h
+++ b/sys/dev/bhnd/cores/chipc/chipc_slicer.h
@@ -41,9 +41,9 @@
#define NVRAM_MAGIC 0x48534C46
void chipc_register_slicer(chipc_flash flash_type);
-int chipc_slicer_spi(device_t dev, struct flash_slice *slices,
- int *nslices);
-int chipc_slicer_cfi(device_t dev, struct flash_slice *slices,
- int *nslices);
+int chipc_slicer_spi(device_t dev, const char *provider,
+ struct flash_slice *slices, int *nslices);
+int chipc_slicer_cfi(device_t dev, const char *provider,
+ struct flash_slice *slices, int *nslices);
#endif /* _BHND_CORES_CHIPC_CHIPC_SLICER_H_ */
diff --git a/sys/dev/bhnd/cores/usb/bhnd_usb.c b/sys/dev/bhnd/cores/usb/bhnd_usb.c
index f753e5b0d6cd..4e88c4a8f94f 100644
--- a/sys/dev/bhnd/cores/usb/bhnd_usb.c
+++ b/sys/dev/bhnd/cores/usb/bhnd_usb.c
@@ -291,7 +291,7 @@ bhnd_usb_alloc_resource(device_t bus, device_t child, int type, int *rid,
rv = rman_reserve_resource(&sc->mem_rman, start, end, count,
flags, child);
- if (rv == 0) {
+ if (rv == NULL) {
BHND_ERROR_DEV(bus, "could not reserve resource");
return (0);
}
@@ -312,7 +312,7 @@ bhnd_usb_alloc_resource(device_t bus, device_t child, int type, int *rid,
rv = rman_reserve_resource(&sc->irq_rman, start, end, count,
flags, child);
- if (rv == 0) {
+ if (rv == NULL) {
BHND_ERROR_DEV(bus, "could not reserve resource");
return (0);
}
diff --git a/sys/dev/buslogic/bt.c b/sys/dev/buslogic/bt.c
index c17c4f439b4c..9c32caebf493 100644
--- a/sys/dev/buslogic/bt.c
+++ b/sys/dev/buslogic/bt.c
@@ -1217,10 +1217,6 @@ btaction(struct cam_sim *sim, union ccb *ccb)
}
break;
}
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
diff --git a/sys/dev/buslogic/bt_pci.c b/sys/dev/buslogic/bt_pci.c
index 7615ae8039ae..48c90e08e553 100644
--- a/sys/dev/buslogic/bt_pci.c
+++ b/sys/dev/buslogic/bt_pci.c
@@ -58,8 +58,8 @@ static int
bt_pci_alloc_resources(device_t dev)
{
int type = 0, rid, zero;
- struct resource *regs = 0;
- struct resource *irq = 0;
+ struct resource *regs = NULL;
+ struct resource *irq = NULL;
#if 0
/* XXX Memory Mapped I/O seems to cause problems */
diff --git a/sys/dev/ce/if_ce.c b/sys/dev/ce/if_ce.c
index 69779d6c5e2d..541db6ce16c9 100644
--- a/sys/dev/ce/if_ce.c
+++ b/sys/dev/ce/if_ce.c
@@ -840,11 +840,11 @@ static int ce_detach (device_t dev)
if (! d || ! d->chan)
continue;
callout_drain (&d->timeout_handle);
- channel [b->num * NCHAN + c->num] = 0;
+ channel [b->num * NCHAN + c->num] = NULL;
/* Deallocate buffers. */
ce_bus_dma_mem_free (&d->dmamem);
}
- adapter [b->num] = 0;
+ adapter [b->num] = NULL;
ce_bus_dma_mem_free (&bd->dmamem);
free (b, M_DEVBUF);
#if __FreeBSD_version >= 504000
diff --git a/sys/dev/cm/smc90cx6.c b/sys/dev/cm/smc90cx6.c
index 5607298e5983..e05f9ee58b8c 100644
--- a/sys/dev/cm/smc90cx6.c
+++ b/sys/dev/cm/smc90cx6.c
@@ -373,7 +373,7 @@ cm_start_locked(ifp)
m = arc_frag_next(ifp);
buffer = sc->sc_tx_act ^ 1;
- if (m == 0)
+ if (m == NULL)
return;
#ifdef CM_DEBUG
@@ -388,7 +388,7 @@ cm_start_locked(ifp)
#endif
cm_ram_ptr = buffer * 512;
- if (m == 0)
+ if (m == NULL)
return;
/* write the addresses to RAM and throw them away */
@@ -505,7 +505,7 @@ cm_srint_locked(vsc)
/* Allocate header mbuf */
MGETHDR(m, M_NOWAIT, MT_DATA);
- if (m == 0) {
+ if (m == NULL) {
/*
* in case s.th. goes wrong with mem, drop it
* to make sure the receiver can be started again
@@ -546,7 +546,7 @@ cm_srint_locked(vsc)
}
}
- if (m == 0) {
+ if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto cleanup;
}
diff --git a/sys/dev/cp/if_cp.c b/sys/dev/cp/if_cp.c
index 426a5eedd608..29643b2ba7f1 100644
--- a/sys/dev/cp/if_cp.c
+++ b/sys/dev/cp/if_cp.c
@@ -628,11 +628,11 @@ static int cp_detach (device_t dev)
if (! d || ! d->chan->type)
continue;
callout_drain (&d->timeout_handle);
- channel [b->num*NCHAN + c->num] = 0;
+ channel [b->num*NCHAN + c->num] = NULL;
/* Deallocate buffers. */
cp_bus_dma_mem_free (&d->dmamem);
}
- adapter [b->num] = 0;
+ adapter [b->num] = NULL;
cp_bus_dma_mem_free (&bd->dmamem);
free (b, M_DEVBUF);
mtx_destroy (&bd->cp_mtx);
diff --git a/sys/dev/ctau/ctddk.c b/sys/dev/ctau/ctddk.c
index 0a9dbd2fd46b..cd83311ad52d 100644
--- a/sys/dev/ctau/ctddk.c
+++ b/sys/dev/ctau/ctddk.c
@@ -104,7 +104,7 @@ int ct_open_board (ct_board_t *b, int num, port_t port, int irq, int dma)
case B_TAU2_E1D:
fw = ctau2_fw_data;
flen = 0;
- ft = 0;
+ ft = NULL;
break;
#ifndef CT_DDK_NO_G703
case B_TAU_G703:
diff --git a/sys/dev/ctau/if_ct.c b/sys/dev/ctau/if_ct.c
index a3df2a8c5d24..41975bae1e3f 100644
--- a/sys/dev/ctau/if_ct.c
+++ b/sys/dev/ctau/if_ct.c
@@ -839,8 +839,8 @@ static int ct_detach (device_t dev)
/* Deallocate buffers. */
ct_bus_dma_mem_free (&d->dmamem);
}
- bd->board = 0;
- adapter [b->num] = 0;
+ bd->board = NULL;
+ adapter [b->num] = NULL;
free (b, M_DEVBUF);
mtx_destroy (&bd->ct_mtx);
diff --git a/sys/dev/cx/cxddk.c b/sys/dev/cx/cxddk.c
index 94780fb3591f..a321000f390f 100644
--- a/sys/dev/cx/cxddk.c
+++ b/sys/dev/cx/cxddk.c
@@ -440,7 +440,7 @@ static int cx_receive_interrupt (cx_chan_t *c)
if (c->mode == M_ASYNC && (risr & RISA_TIMEOUT)) {
unsigned long rcbadr = (unsigned short) inw (RCBADRL(c->port)) |
(long) inw (RCBADRU(c->port)) << 16;
- unsigned char *buf = 0;
+ unsigned char *buf = NULL;
port_t cnt_port = 0, sts_port = 0;
if (rcbadr >= c->brphys && rcbadr < c->brphys+DMABUFSZ) {
diff --git a/sys/dev/cx/if_cx.c b/sys/dev/cx/if_cx.c
index 654e9136ccdf..58fca9fe7719 100644
--- a/sys/dev/cx/if_cx.c
+++ b/sys/dev/cx/if_cx.c
@@ -991,8 +991,8 @@ static int cx_detach (device_t dev)
/* Deallocate buffers. */
cx_bus_dma_mem_free (&d->dmamem);
}
- bd->board = 0;
- adapter [b->num] = 0;
+ bd->board = NULL;
+ adapter [b->num] = NULL;
free (b, M_DEVBUF);
splx (s);
diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c
index a6253f5f5e9f..3e56c86258e5 100644
--- a/sys/dev/de/if_de.c
+++ b/sys/dev/de/if_de.c
@@ -4887,8 +4887,8 @@ tulip_pci_attach(device_t dev)
rid = 0;
res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
- if (res == 0 || bus_setup_intr(dev, res, INTR_TYPE_NET |
- INTR_MPSAFE, NULL, intr_rtn, sc, &ih)) {
+ if (res == NULL || bus_setup_intr(dev, res, INTR_TYPE_NET |
+ INTR_MPSAFE, NULL, intr_rtn, sc, &ih)) {
device_printf(dev, "couldn't map interrupt\n");
tulip_busdma_cleanup(sc);
ether_ifdetach(sc->tulip_ifp);
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 818e2e411cf3..621f15cbe843 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -920,7 +920,7 @@ em_if_attach_pre(if_ctx_t ctx)
* Set the frame limits assuming
* standard ethernet sized frames.
*/
- adapter->hw.mac.max_frame_size =
+ scctx->isc_max_frame_size = adapter->hw.mac.max_frame_size =
ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE;
/*
@@ -1117,6 +1117,7 @@ em_if_mtu_set(if_ctx_t ctx, uint32_t mtu)
int max_frame_size;
struct adapter *adapter = iflib_get_softc(ctx);
struct ifnet *ifp = iflib_get_ifp(ctx);
+ if_softc_ctx_t scctx = iflib_get_softc_ctx(ctx);
IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
@@ -1147,7 +1148,8 @@ em_if_mtu_set(if_ctx_t ctx, uint32_t mtu)
return (EINVAL);
}
- adapter->hw.mac.max_frame_size = if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN;
+ scctx->isc_max_frame_size = adapter->hw.mac.max_frame_size =
+ if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN;
return (0);
}
@@ -2236,13 +2238,62 @@ em_reset(if_ctx_t ctx)
case e1000_pch_spt:
pba = E1000_PBA_26K;
break;
+ case e1000_82575:
+ pba = E1000_PBA_32K;
+ break;
+ case e1000_82576:
+ case e1000_vfadapt:
+ pba = E1000_READ_REG(hw, E1000_RXPBS);
+ pba &= E1000_RXPBS_SIZE_MASK_82576;
+ break;
+ case e1000_82580:
+ case e1000_i350:
+ case e1000_i354:
+ case e1000_vfadapt_i350:
+ pba = E1000_READ_REG(hw, E1000_RXPBS);
+ pba = e1000_rxpbs_adjust_82580(pba);
+ break;
+ case e1000_i210:
+ case e1000_i211:
+ pba = E1000_PBA_34K;
+ break;
default:
if (adapter->hw.mac.max_frame_size > 8192)
pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
else
pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */
}
- E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba);
+
+ /* Special needs in case of Jumbo frames */
+ if ((hw->mac.type == e1000_82575) && (ifp->if_mtu > ETHERMTU)) {
+ u32 tx_space, min_tx, min_rx;
+ pba = E1000_READ_REG(hw, E1000_PBA);
+ tx_space = pba >> 16;
+ pba &= 0xffff;
+ min_tx = (adapter->hw.mac.max_frame_size +
+ sizeof(struct e1000_tx_desc) - ETHERNET_FCS_SIZE) * 2;
+ min_tx = roundup2(min_tx, 1024);
+ min_tx >>= 10;
+ min_rx = adapter->hw.mac.max_frame_size;
+ min_rx = roundup2(min_rx, 1024);
+ min_rx >>= 10;
+ if (tx_space < min_tx &&
+ ((min_tx - tx_space) < pba)) {
+ pba = pba - (min_tx - tx_space);
+ /*
+ * if short on rx space, rx wins
+ * and must trump tx adjustment
+ */
+ if (pba < min_rx)
+ pba = min_rx;
+ }
+ E1000_WRITE_REG(hw, E1000_PBA, pba);
+ }
+
+ if (hw->mac.type < igb_mac_min)
+ E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba);
+
+ INIT_DEBUGOUT1("em_reset: pba=%dK",pba);
/*
* These parameters control the automatic generation (Tx) and
@@ -2258,7 +2309,7 @@ em_reset(if_ctx_t ctx)
* by 1500.
* - The pause time is fairly large at 1000 x 512ns = 512 usec.
*/
- rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 );
+ rx_buffer_size = (pba & 0xffff) << 10;
hw->fc.high_water = rx_buffer_size -
roundup2(adapter->hw.mac.max_frame_size, 1024);
hw->fc.low_water = hw->fc.high_water - 1500;
@@ -2303,6 +2354,21 @@ em_reset(if_ctx_t ctx)
else
E1000_WRITE_REG(hw, E1000_PBA, 26);
break;
+ case e1000_82575:
+ case e1000_82576:
+ /* 8-byte granularity */
+ hw->fc.low_water = hw->fc.high_water - 8;
+ break;
+ case e1000_82580:
+ case e1000_i350:
+ case e1000_i354:
+ case e1000_i210:
+ case e1000_i211:
+ case e1000_vfadapt:
+ case e1000_vfadapt_i350:
+ /* 16-byte granularity */
+ hw->fc.low_water = hw->fc.high_water - 16;
+ break;
case e1000_ich9lan:
case e1000_ich10lan:
if (if_getmtu(ifp) > ETHERMTU) {
@@ -2973,9 +3039,7 @@ em_initialize_receive_unit(if_ctx_t ctx)
} else if (adapter->hw.mac.type >= igb_mac_min) {
u32 psize, srrctl = 0;
- if (ifp->if_mtu > ETHERMTU) {
- rctl |= E1000_RCTL_LPE;
-
+ if (if_getmtu(ifp) > ETHERMTU) {
/* Set maximum packet len */
psize = scctx->isc_max_frame_size;
if (psize <= 4096) {
@@ -2991,7 +3055,6 @@ em_initialize_receive_unit(if_ctx_t ctx)
psize += VLAN_TAG_SIZE;
E1000_WRITE_REG(&adapter->hw, E1000_RLPML, psize);
} else {
- rctl &= ~E1000_RCTL_LPE;
srrctl |= 2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
rctl |= E1000_RCTL_SZ_2048;
}
@@ -3037,8 +3100,7 @@ em_initialize_receive_unit(if_ctx_t ctx)
rxdctl |= IGB_RX_WTHRESH << 16;
E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl);
}
- }
- if (adapter->hw.mac.type >= e1000_pch2lan) {
+ } else if (adapter->hw.mac.type >= e1000_pch2lan) {
if (if_getmtu(ifp) > ETHERMTU)
e1000_lv_jumbo_workaround_ich8lan(hw, TRUE);
else
@@ -3048,15 +3110,18 @@ em_initialize_receive_unit(if_ctx_t ctx)
/* Make sure VLAN Filters are off */
rctl &= ~E1000_RCTL_VFE;
- if (adapter->rx_mbuf_sz == MCLBYTES)
- rctl |= E1000_RCTL_SZ_2048;
- else if (adapter->rx_mbuf_sz == MJUMPAGESIZE)
- rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX;
- else if (adapter->rx_mbuf_sz > MJUMPAGESIZE)
- rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX;
+ if (adapter->hw.mac.type < igb_mac_min) {
+ if (adapter->rx_mbuf_sz == MCLBYTES)
+ rctl |= E1000_RCTL_SZ_2048;
+ else if (adapter->rx_mbuf_sz == MJUMPAGESIZE)
+ rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX;
+ else if (adapter->rx_mbuf_sz > MJUMPAGESIZE)
+ rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX;
+
+ /* ensure we clear use DTYPE of 00 here */
+ rctl &= ~0x00000C00;
+ }
- /* ensure we clear use DTYPE of 00 here */
- rctl &= ~0x00000C00;
/* Write out the settings */
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c
index 1fb403793169..0730c964df08 100644
--- a/sys/dev/ed/if_ed.c
+++ b/sys/dev/ed/if_ed.c
@@ -751,7 +751,7 @@ outloop:
return;
}
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == 0) {
+ if (m == NULL) {
/*
* We are using the !OACTIVE flag to indicate to the outside
diff --git a/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c b/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
index 44b5807beaba..e3ea80fe2a1d 100644
--- a/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
+++ b/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
@@ -405,11 +405,38 @@ mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
MTKSWITCH_LOCK(sc);
/* First, see if we can accomodate the request at all */
val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
- if ((val & POC2_UNTAG_VLAN) == 0 ||
- sc->sc_switchtype == MTK_SWITCH_RT3050) {
+ if (sc->sc_switchtype == MTK_SWITCH_RT3050 ||
+ (val & POC2_UNTAG_VLAN) == 0) {
+ /*
+ * There are 2 things we can't support in per-port untagging
+ * mode:
+ * 1. Adding a port as an untagged member if the port is not
+ * set up to do untagging.
+ * 2. Adding a port as a tagged member if the port is set up
+ * to do untagging.
+ */
val &= VUB_MASK;
+
+ /* get all untagged members from the member list */
tmp = v->es_untagged_ports & v->es_member_ports;
- if (val != tmp) {
+ /* fail if untagged members are not a subset of all members */
+ if (tmp != v->es_untagged_ports) {
+ /* Cannot accomodate request */
+ MTKSWITCH_UNLOCK(sc);
+ return (ENOTSUP);
+ }
+
+ /* fail if any untagged member is set up to do tagging */
+ if ((tmp & val) != tmp) {
+ /* Cannot accomodate request */
+ MTKSWITCH_UNLOCK(sc);
+ return (ENOTSUP);
+ }
+
+ /* now, get the list of all tagged members */
+ tmp = v->es_member_ports & ~tmp;
+ /* fail if any tagged member is set up to do untagging */
+ if ((tmp & val) != 0) {
/* Cannot accomodate request */
MTKSWITCH_UNLOCK(sc);
return (ENOTSUP);
diff --git a/sys/dev/extres/clk/clk_div.c b/sys/dev/extres/clk/clk_div.c
index bf663f28c3a4..c9573dfabfe1 100644
--- a/sys/dev/extres/clk/clk_div.c
+++ b/sys/dev/extres/clk/clk_div.c
@@ -195,7 +195,8 @@ clknode_div_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout,
hw_i_div--;
*stop = 1;
- if (hw_i_div > sc->i_mask) {
+ if (hw_i_div > sc->i_mask &&
+ ((sc->div_flags & CLK_DIV_WITH_TABLE) == 0)) {
/* XXX Or only return error? */
printf("%s: %s integer divider is too big: %u\n",
clknode_get_name(clk), __func__, hw_i_div);
diff --git a/sys/dev/fatm/if_fatm.c b/sys/dev/fatm/if_fatm.c
index a530a44327d1..2a1dee685c3d 100644
--- a/sys/dev/fatm/if_fatm.c
+++ b/sys/dev/fatm/if_fatm.c
@@ -1501,7 +1501,7 @@ fatm_intr_drain_rx(struct fatm_softc *sc)
rpd->nseg = le32toh(rpd->nseg);
mlen = 0;
- m0 = last = 0;
+ m0 = last = NULL;
for (i = 0; i < rpd->nseg; i++) {
rb = sc->rbufs + rpd->segment[i].handle;
if (m0 == NULL) {
diff --git a/sys/dev/fdt/fdt_slicer.c b/sys/dev/fdt/fdt_slicer.c
index 7e385c15c5d3..2765f53aa1ba 100644
--- a/sys/dev/fdt/fdt_slicer.c
+++ b/sys/dev/fdt/fdt_slicer.c
@@ -30,10 +30,11 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/module.h>
#include <sys/slicer.h>
#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/openfirm.h>
#ifdef DEBUG
#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
@@ -42,8 +43,13 @@ __FBSDID("$FreeBSD$");
#define debugf(fmt, args...)
#endif
-int
-fdt_flash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num)
+static int fdt_flash_fill_slices(device_t dev, const char *provider,
+ struct flash_slice *slices, int *slices_num);
+static void fdt_slicer_init(void);
+
+static int
+fdt_flash_fill_slices(device_t dev, const char *provider __unused,
+ struct flash_slice *slices, int *slices_num)
{
char *slice_name;
phandle_t dt_node, dt_child;
@@ -90,8 +96,8 @@ fdt_flash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num)
(void **)&slice_name);
if (name_len <= 0) {
/* Use node name if no label defined */
- name_len = OF_getprop_alloc(dt_child, "name", sizeof(char),
- (void **)&slice_name);
+ name_len = OF_getprop_alloc(dt_child, "name",
+ sizeof(char), (void **)&slice_name);
if (name_len <= 0) {
debugf("slice i=%d with no name\n", i);
slice_name = NULL;
@@ -110,3 +116,23 @@ fdt_flash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num)
*slices_num = i;
return (0);
}
+
+static void
+fdt_slicer_init(void)
+{
+
+ flash_register_slicer(fdt_flash_fill_slices, FLASH_SLICES_TYPE_NAND,
+ FALSE);
+ flash_register_slicer(fdt_flash_fill_slices, FLASH_SLICES_TYPE_CFI,
+ FALSE);
+ flash_register_slicer(fdt_flash_fill_slices, FLASH_SLICES_TYPE_SPI,
+ FALSE);
+}
+
+/*
+ * Must be initialized after GEOM classes (SI_SUB_DRIVERS/SI_ORDER_FIRST),
+ * i. e. after g_init() is called, due to the use of the GEOM topology_lock
+ * in flash_register_slicer(). However, must be before SI_SUB_CONFIGURE.
+ */
+SYSINIT(fdt_slicer_rootconf, SI_SUB_DRIVERS, SI_ORDER_SECOND, fdt_slicer_init,
+ NULL);
diff --git a/sys/dev/fe/if_fe.c b/sys/dev/fe/if_fe.c
index e4a46011a9a3..94b83be3f9e8 100644
--- a/sys/dev/fe/if_fe.c
+++ b/sys/dev/fe/if_fe.c
@@ -2002,7 +2002,7 @@ fe_write_mbufs (struct fe_softc *sc, struct mbuf *m)
if ((sc->proto_dlcr6 & FE_D6_SBW) == FE_D6_SBW_BYTE)
{
/* 8-bit cards are easy. */
- for (mp = m; mp != 0; mp = mp->m_next) {
+ for (mp = m; mp != NULL; mp = mp->m_next) {
if (mp->m_len)
fe_outsb(sc, FE_BMPR8, mtod(mp, caddr_t),
mp->m_len);
@@ -2012,7 +2012,7 @@ fe_write_mbufs (struct fe_softc *sc, struct mbuf *m)
{
/* 16-bit cards are a pain. */
savebyte = NO_PENDING_BYTE;
- for (mp = m; mp != 0; mp = mp->m_next) {
+ for (mp = m; mp != NULL; mp = mp->m_next) {
/* Ignore empty mbuf. */
len = mp->m_len;
diff --git a/sys/dev/ffec/if_ffecreg.h b/sys/dev/ffec/if_ffecreg.h
index 2233df770046..bc44af3a5184 100644
--- a/sys/dev/ffec/if_ffecreg.h
+++ b/sys/dev/ffec/if_ffecreg.h
@@ -186,6 +186,27 @@ __FBSDID("$FreeBSD$");
#define FEC_RACC_PADREM (1 << 0)
/*
+ * IEEE-1588 timer registers
+ */
+
+#define FEC_ATCR_REG 0x0400
+#define FEC_ATCR_SLAVE (1u << 13)
+#define FEC_ATCR_CAPTURE (1u << 11)
+#define FEC_ATCR_RESTART (1u << 9)
+#define FEC_ATCR_PINPER (1u << 7)
+#define FEC_ATCR_PEREN (1u << 4)
+#define FEC_ATCR_OFFRST (1u << 3)
+#define FEC_ATCR_OFFEN (1u << 2)
+#define FEC_ATCR_EN (1u << 0)
+
+#define FEC_ATVR_REG 0x0404
+#define FEC_ATOFF_REG 0x0408
+#define FEC_ATPER_REG 0x040c
+#define FEC_ATCOR_REG 0x0410
+#define FEC_ATINC_REG 0x0414
+#define FEC_ATSTMP_REG 0x0418
+
+/*
* Statistics registers
*/
#define FEC_RMON_T_DROP 0x200
diff --git a/sys/dev/firewire/if_fwip.c b/sys/dev/firewire/if_fwip.c
index 0a958b2b2c0d..3928ef13ae5b 100644
--- a/sys/dev/firewire/if_fwip.c
+++ b/sys/dev/firewire/if_fwip.c
@@ -575,7 +575,7 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
*/
mtag = m_tag_locate(m, MTAG_FIREWIRE, MTAG_FIREWIRE_HWADDR, 0);
if (mtag == NULL)
- destfw = 0;
+ destfw = NULL;
else
destfw = (struct fw_hwaddr *) (mtag + 1);
diff --git a/sys/dev/hptiop/hptiop.c b/sys/dev/hptiop/hptiop.c
index 81b4c694d6d2..a20def6ef00b 100644
--- a/sys/dev/hptiop/hptiop.c
+++ b/sys/dev/hptiop/hptiop.c
@@ -330,7 +330,7 @@ static void hptiop_request_callback_itl(struct hpt_iop_hba * hba,
u_int32_t index)
{
struct hpt_iop_srb *srb;
- struct hpt_iop_request_scsi_command *req=0;
+ struct hpt_iop_request_scsi_command *req=NULL;
union ccb *ccb;
u_int8_t *cdb;
u_int32_t result, temp, dxfer;
diff --git a/sys/dev/hptmv/entry.c b/sys/dev/hptmv/entry.c
index 8f60be25a2b8..167f82a46e87 100644
--- a/sys/dev/hptmv/entry.c
+++ b/sys/dev/hptmv/entry.c
@@ -138,8 +138,8 @@ static MV_BOOLEAN hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter,
static struct sx hptmv_list_lock;
SX_SYSINIT(hptmv_list_lock, &hptmv_list_lock, "hptmv list");
-IAL_ADAPTER_T *gIal_Adapter = 0;
-IAL_ADAPTER_T *pCurAdapter = 0;
+IAL_ADAPTER_T *gIal_Adapter = NULL;
+IAL_ADAPTER_T *pCurAdapter = NULL;
static MV_SATA_CHANNEL gMvSataChannels[MAX_VBUS][MV_SATA_CHANNELS_NUM];
typedef struct st_HPT_DPC {
@@ -1262,7 +1262,7 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
sx_xlock(&hptmv_list_lock);
pAdapter->next = 0;
- if(gIal_Adapter == 0){
+ if(gIal_Adapter == NULL){
gIal_Adapter = pAdapter;
pCurAdapter = gIal_Adapter;
}
@@ -2289,10 +2289,6 @@ hpt_action(struct cam_sim *sim, union ccb *ccb)
break;
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
case XPT_TERM_IO: /* Terminate the I/O process */
/* XXX Implement */
@@ -2431,7 +2427,7 @@ static void hpt_worker_thread(void)
sx_slock(&hptmv_list_lock);
pAdapter = gIal_Adapter;
- while(pAdapter != 0){
+ while(pAdapter != NULL){
mtx_lock(&pAdapter->lock);
_vbus_p = &pAdapter->VBus;
diff --git a/sys/dev/hptmv/gui_lib.c b/sys/dev/hptmv/gui_lib.c
index 359a41edcd3c..bc57239c217b 100644
--- a/sys/dev/hptmv/gui_lib.c
+++ b/sys/dev/hptmv/gui_lib.c
@@ -74,7 +74,7 @@ check_VDevice_valid(PVDevice p)
PVBus _vbus_p;
IAL_ADAPTER_T *pAdapter = gIal_Adapter;
- while(pAdapter != 0)
+ while(pAdapter != NULL)
{
for (i = 0; i < MV_SATA_CHANNELS_NUM; i++)
if(&(pAdapter->VDevices[i]) == p) return 0;
@@ -83,7 +83,7 @@ check_VDevice_valid(PVDevice p)
#ifdef SUPPORT_ARRAY
pAdapter = gIal_Adapter;
- while(pAdapter != 0)
+ while(pAdapter != NULL)
{
_vbus_p = &pAdapter->VBus;
for (i=0;i<MAX_ARRAY_PER_VBUS;i++)
@@ -403,7 +403,7 @@ int hpt_get_controller_count(void)
IAL_ADAPTER_T *pAdapTemp = gIal_Adapter;
int iControllerCount = 0;
- while(pAdapTemp != 0)
+ while(pAdapTemp != NULL)
{
iControllerCount++;
pAdapTemp = pAdapTemp->next;
@@ -448,7 +448,7 @@ int hpt_get_channel_info(int id, int bus, PCHANNEL_INFO pInfo)
IAL_ADAPTER_T *pAdapTemp = gIal_Adapter;
int i,iControllerCount = 0;
- while(pAdapTemp != 0)
+ while(pAdapTemp != NULL)
{
if (iControllerCount++==id)
goto found;
diff --git a/sys/dev/hptmv/hptproc.c b/sys/dev/hptmv/hptproc.c
index 9e897567e079..d9ded9fd0e1a 100644
--- a/sys/dev/hptmv/hptproc.c
+++ b/sys/dev/hptmv/hptproc.c
@@ -427,7 +427,7 @@ static void
hpt_copy_array_info(HPT_GET_INFO *pinfo, int nld, PVDevice pArray)
{
int i;
- char *sType=0, *sStatus=0;
+ char *sType = NULL, *sStatus = NULL;
char buf[32];
PVDevice pTmpArray;
diff --git a/sys/dev/hptmv/ioctl.c b/sys/dev/hptmv/ioctl.c
index 50a82aed1cb8..671d64c86bcf 100644
--- a/sys/dev/hptmv/ioctl.c
+++ b/sys/dev/hptmv/ioctl.c
@@ -691,7 +691,7 @@ hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
PCommand pCmd;
UINT result;
int needsync=0, retry=0, needdelete=0;
- void *buffer = 0;
+ void *buffer = NULL;
_VBUS_INST(&pAdapter->VBus)
diff --git a/sys/dev/iicbus/if_ic.c b/sys/dev/iicbus/if_ic.c
index 0df2f4a45eee..323b0f7c29bb 100644
--- a/sys/dev/iicbus/if_ic.c
+++ b/sys/dev/iicbus/if_ic.c
@@ -251,7 +251,7 @@ icioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCADDMULTI:
case SIOCDELMULTI:
- if (ifr == 0)
+ if (ifr == NULL)
return (EAFNOSUPPORT); /* XXX */
switch (ifr->ifr_addr.sa_family) {
case AF_INET:
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 2b338ee6508c..c502de6a7c79 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -41,12 +41,6 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_periph.h>
#include <cam/cam_xpt_periph.h>
-#if __FreeBSD_version < 800002
-#define THREAD_CREATE kthread_create
-#else
-#define THREAD_CREATE kproc_create
-#endif
-
MODULE_VERSION(isp, 1);
MODULE_DEPEND(isp, cam, 1, 1, 1);
int isp_announced = 0;
@@ -115,6 +109,9 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
struct ccb_setasync csa;
struct cam_sim *sim;
struct cam_path *path;
+#ifdef ISP_TARGET_MODE
+ int i;
+#endif
/*
* Construct our SIM entry.
@@ -153,6 +150,17 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
struct isp_spi *spi = ISP_SPI_PC(isp, chan);
spi->sim = sim;
spi->path = path;
+#ifdef ISP_TARGET_MODE
+ TAILQ_INIT(&spi->waitq);
+ STAILQ_INIT(&spi->ntfree);
+ for (i = 0; i < ATPDPSIZE; i++)
+ STAILQ_INSERT_TAIL(&spi->ntfree, &spi->ntpool[i], next);
+ LIST_INIT(&spi->atfree);
+ for (i = ATPDPSIZE-1; i >= 0; i--)
+ LIST_INSERT_HEAD(&spi->atfree, &spi->atpool[i], next);
+ for (i = 0; i < ATPDPHASHSIZE; i++)
+ LIST_INIT(&spi->atused[i]);
+#endif
} else {
fcparam *fcp = FCPARAM(isp, chan);
struct isp_fc *fc = ISP_FC_PC(isp, chan);
@@ -168,9 +176,21 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0);
TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc);
+#ifdef ISP_TARGET_MODE
+ TAILQ_INIT(&fc->waitq);
+ STAILQ_INIT(&fc->ntfree);
+ for (i = 0; i < ATPDPSIZE; i++)
+ STAILQ_INSERT_TAIL(&fc->ntfree, &fc->ntpool[i], next);
+ LIST_INIT(&fc->atfree);
+ for (i = ATPDPSIZE-1; i >= 0; i--)
+ LIST_INSERT_HEAD(&fc->atfree, &fc->atpool[i], next);
+ for (i = 0; i < ATPDPHASHSIZE; i++)
+ LIST_INIT(&fc->atused[i]);
+#endif
isp_loop_changed(isp, chan);
ISP_UNLOCK(isp);
- if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
+ if (kproc_create(isp_kthread, fc, &fc->kproc, 0, 0,
+ "%s_%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
xpt_free_path(fc->path);
ISP_LOCK(isp);
xpt_bus_deregister(cam_sim_path(fc->sim));
@@ -830,19 +850,15 @@ isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
* Put the target mode functions here, because some are inlines
*/
#ifdef ISP_TARGET_MODE
-static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
-static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t);
-static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *);
-static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **);
-static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t);
-static ISP_INLINE atio_private_data_t *isp_find_atpd(ispsoftc_t *, tstate_t *, uint32_t);
-static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *);
-static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *);
-static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t);
-static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *);
+static atio_private_data_t *isp_get_atpd(ispsoftc_t *, int, uint32_t);
+static atio_private_data_t *isp_find_atpd(ispsoftc_t *, int, uint32_t);
+static void isp_put_atpd(ispsoftc_t *, int, atio_private_data_t *);
+static inot_private_data_t *isp_get_ntpd(ispsoftc_t *, int);
+static inot_private_data_t *isp_find_ntpd(ispsoftc_t *, int, uint32_t, uint32_t);
+static void isp_put_ntpd(ispsoftc_t *, int, inot_private_data_t *);
static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
-static void destroy_lun_state(ispsoftc_t *, tstate_t *);
+static void destroy_lun_state(ispsoftc_t *, int, tstate_t *);
static void isp_enable_lun(ispsoftc_t *, union ccb *);
static void isp_disable_lun(ispsoftc_t *, union ccb *);
static timeout_t isp_refire_putback_atio;
@@ -858,43 +874,7 @@ static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp);
static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
-static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
-static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
-
-static ISP_INLINE int
-is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
-{
- tstate_t *tptr;
- struct tslist *lhp;
-
- ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
- SLIST_FOREACH(tptr, lhp, next) {
- if (tptr->ts_lun == lun) {
- return (1);
- }
- }
- return (0);
-}
-
-static void
-dump_tstates(ispsoftc_t *isp, int bus)
-{
- int i, j;
- struct tslist *lhp;
- tstate_t *tptr = NULL;
-
- if (bus >= isp->isp_nchan) {
- return;
- }
- for (i = 0; i < LUN_HASH_SIZE; i++) {
- ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
- j = 0;
- SLIST_FOREACH(tptr, lhp, next) {
- xpt_print(tptr->owner, "[%d, %d] atio_cnt=%d inot_cnt=%d\n", i, j, tptr->atio_count, tptr->inot_count);
- j++;
- }
- }
-}
+static void isp_target_mark_aborted_early(ispsoftc_t *, int chan, tstate_t *, uint32_t);
static ISP_INLINE tstate_t *
get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
@@ -905,208 +885,179 @@ get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
if (bus < isp->isp_nchan) {
ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
SLIST_FOREACH(tptr, lhp, next) {
- if (tptr->ts_lun == lun) {
- tptr->hold++;
+ if (tptr->ts_lun == lun)
return (tptr);
- }
- }
- }
- return (NULL);
-}
-
-static ISP_INLINE tstate_t *
-get_lun_statep_from_tag(ispsoftc_t *isp, int bus, uint32_t tagval)
-{
- tstate_t *tptr = NULL;
- atio_private_data_t *atp;
- struct tslist *lhp;
- int i;
-
- if (bus < isp->isp_nchan && tagval != 0) {
- for (i = 0; i < LUN_HASH_SIZE; i++) {
- ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
- SLIST_FOREACH(tptr, lhp, next) {
- atp = isp_find_atpd(isp, tptr, tagval);
- if (atp) {
- tptr->hold++;
- return (tptr);
- }
- }
}
}
return (NULL);
}
-static ISP_INLINE inot_private_data_t *
-get_ntp_from_tagdata(ispsoftc_t *isp, uint32_t tag_id, uint32_t seq_id, tstate_t **rslt)
+static int
+isp_atio_restart(ispsoftc_t *isp, int bus, tstate_t *tptr)
{
inot_private_data_t *ntp;
- tstate_t *tptr;
- struct tslist *lhp;
- int bus, i;
+ struct ntpdlist rq;
- for (bus = 0; bus < isp->isp_nchan; bus++) {
- for (i = 0; i < LUN_HASH_SIZE; i++) {
- ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
- SLIST_FOREACH(tptr, lhp, next) {
- ntp = isp_find_ntpd(isp, tptr, tag_id, seq_id);
- if (ntp) {
- *rslt = tptr;
- tptr->hold++;
- return (ntp);
- }
- }
+ if (STAILQ_EMPTY(&tptr->restart_queue))
+ return (0);
+ STAILQ_INIT(&rq);
+ STAILQ_CONCAT(&rq, &tptr->restart_queue);
+ while ((ntp = STAILQ_FIRST(&rq)) != NULL) {
+ STAILQ_REMOVE_HEAD(&rq, next);
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGTDEBUG0,
+ "%s: restarting resrc deprived %x", __func__,
+ ((at7_entry_t *)ntp->data)->at_rxid);
+ isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->data);
+ } else {
+ isp_prt(isp, ISP_LOGTDEBUG0,
+ "%s: restarting resrc deprived %x", __func__,
+ ((at2_entry_t *)ntp->data)->at_rxid);
+ isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->data);
}
+ isp_put_ntpd(isp, bus, ntp);
+ if (!STAILQ_EMPTY(&tptr->restart_queue))
+ break;
}
- return (NULL);
-}
-
-static ISP_INLINE void
-rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
-{
- KASSERT((tptr->hold), ("tptr not held"));
- tptr->hold--;
+ if (!STAILQ_EMPTY(&rq)) {
+ STAILQ_CONCAT(&rq, &tptr->restart_queue);
+ STAILQ_CONCAT(&tptr->restart_queue, &rq);
+ }
+ return (!STAILQ_EMPTY(&tptr->restart_queue));
}
static void
isp_tmcmd_restart(ispsoftc_t *isp)
{
- inot_private_data_t *ntp;
- inot_private_data_t *restart_queue;
tstate_t *tptr;
union ccb *ccb;
struct tslist *lhp;
+ struct isp_ccbq *waitq;
int bus, i;
for (bus = 0; bus < isp->isp_nchan; bus++) {
for (i = 0; i < LUN_HASH_SIZE; i++) {
ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
- SLIST_FOREACH(tptr, lhp, next) {
- if ((restart_queue = tptr->restart_queue) != NULL)
- tptr->restart_queue = NULL;
- while (restart_queue) {
- ntp = restart_queue;
- restart_queue = ntp->rd.nt.nt_hba;
- if (IS_24XX(isp)) {
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
- isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
- } else {
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
- isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
- }
- isp_put_ntpd(isp, tptr, ntp);
- if (tptr->restart_queue && restart_queue != NULL) {
- ntp = tptr->restart_queue;
- tptr->restart_queue = restart_queue;
- while (restart_queue->rd.nt.nt_hba) {
- restart_queue = restart_queue->rd.nt.nt_hba;
- }
- restart_queue->rd.nt.nt_hba = ntp;
- break;
- }
- }
- /*
- * We only need to do this once per tptr
- */
- if (!TAILQ_EMPTY(&tptr->waitq)) {
- ccb = (union ccb *)TAILQ_LAST(&tptr->waitq, isp_ccbq);
- TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
- isp_target_start_ctio(isp, ccb, FROM_TIMER);
- }
- }
+ SLIST_FOREACH(tptr, lhp, next)
+ isp_atio_restart(isp, bus, tptr);
+ }
+
+ /*
+ * We only need to do this once per channel.
+ */
+ ISP_GET_PC_ADDR(isp, bus, waitq, waitq);
+ ccb = (union ccb *)TAILQ_FIRST(waitq);
+ if (ccb != NULL) {
+ TAILQ_REMOVE(waitq, &ccb->ccb_h, periph_links.tqe);
+ isp_target_start_ctio(isp, ccb, FROM_TIMER);
}
}
}
-static ISP_INLINE atio_private_data_t *
-isp_get_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag)
+static atio_private_data_t *
+isp_get_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
{
+ struct atpdlist *atfree;
+ struct atpdlist *atused;
atio_private_data_t *atp;
- atp = LIST_FIRST(&tptr->atfree);
+ ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
+ atp = LIST_FIRST(atfree);
if (atp) {
LIST_REMOVE(atp, next);
atp->tag = tag;
- LIST_INSERT_HEAD(&tptr->atused[ATPDPHASH(tag)], atp, next);
+ ISP_GET_PC(isp, chan, atused, atused);
+ LIST_INSERT_HEAD(&atused[ATPDPHASH(tag)], atp, next);
}
return (atp);
}
-static ISP_INLINE atio_private_data_t *
-isp_find_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag)
+static atio_private_data_t *
+isp_find_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
{
+ struct atpdlist *atused;
atio_private_data_t *atp;
- LIST_FOREACH(atp, &tptr->atused[ATPDPHASH(tag)], next) {
+ ISP_GET_PC(isp, chan, atused, atused);
+ LIST_FOREACH(atp, &atused[ATPDPHASH(tag)], next) {
if (atp->tag == tag)
return (atp);
}
return (NULL);
}
-static ISP_INLINE void
-isp_put_atpd(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp)
+static void
+isp_put_atpd(ispsoftc_t *isp, int chan, atio_private_data_t *atp)
{
+ struct atpdlist *atfree;
+
if (atp->ests) {
isp_put_ecmd(isp, atp->ests);
}
LIST_REMOVE(atp, next);
memset(atp, 0, sizeof (*atp));
- LIST_INSERT_HEAD(&tptr->atfree, atp, next);
+ ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
+ LIST_INSERT_HEAD(atfree, atp, next);
}
static void
-isp_dump_atpd(ispsoftc_t *isp, tstate_t *tptr)
+isp_dump_atpd(ispsoftc_t *isp, int chan)
{
- atio_private_data_t *atp;
+ atio_private_data_t *atp, *atpool;
const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" };
- for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
- xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u lun %x nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n",
- atp->tag, atp->orig_datalen, atp->bytes_xfered, atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]);
+ ISP_GET_PC(isp, chan, atpool, atpool);
+ for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
+ if (atp->state == ATPD_STATE_FREE)
+ continue;
+ isp_prt(isp, ISP_LOGALL, "Chan %d ATP [0x%x] origdlen %u bytes_xfrd %u lun %jx nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s",
+ chan, atp->tag, atp->orig_datalen, atp->bytes_xfered, (uintmax_t)atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]);
}
}
-
-static ISP_INLINE inot_private_data_t *
-isp_get_ntpd(ispsoftc_t *isp, tstate_t *tptr)
+static inot_private_data_t *
+isp_get_ntpd(ispsoftc_t *isp, int chan)
{
+ struct ntpdlist *ntfree;
inot_private_data_t *ntp;
- ntp = tptr->ntfree;
- if (ntp) {
- tptr->ntfree = ntp->next;
- }
+
+ ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
+ ntp = STAILQ_FIRST(ntfree);
+ if (ntp)
+ STAILQ_REMOVE_HEAD(ntfree, next);
return (ntp);
}
-static ISP_INLINE inot_private_data_t *
-isp_find_ntpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id, uint32_t seq_id)
+static inot_private_data_t *
+isp_find_ntpd(ispsoftc_t *isp, int chan, uint32_t tag_id, uint32_t seq_id)
{
- inot_private_data_t *ntp;
- for (ntp = tptr->ntpool; ntp < &tptr->ntpool[ATPDPSIZE]; ntp++) {
- if (ntp->rd.tag_id == tag_id && ntp->rd.seq_id == seq_id) {
+ inot_private_data_t *ntp, *ntp2;
+
+ ISP_GET_PC(isp, chan, ntpool, ntp);
+ ISP_GET_PC_ADDR(isp, chan, ntpool[ATPDPSIZE], ntp2);
+ for (; ntp < ntp2; ntp++) {
+ if (ntp->tag_id == tag_id && ntp->seq_id == seq_id)
return (ntp);
- }
}
return (NULL);
}
-static ISP_INLINE void
-isp_put_ntpd(ispsoftc_t *isp, tstate_t *tptr, inot_private_data_t *ntp)
+static void
+isp_put_ntpd(ispsoftc_t *isp, int chan, inot_private_data_t *ntp)
{
- ntp->rd.tag_id = ntp->rd.seq_id = 0;
- ntp->next = tptr->ntfree;
- tptr->ntfree = ntp;
+ struct ntpdlist *ntfree;
+
+ ntp->tag_id = ntp->seq_id = 0;
+ ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
+ STAILQ_INSERT_HEAD(ntfree, ntp, next);
}
static cam_status
create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt)
{
- cam_status status;
lun_id_t lun;
struct tslist *lhp;
tstate_t *tptr;
- int i;
lun = xpt_path_lun_id(path);
if (lun != CAM_LUN_WILDCARD) {
@@ -1114,31 +1065,13 @@ create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rsl
return (CAM_LUN_INVALID);
}
}
- if (is_lun_enabled(isp, bus, lun)) {
- return (CAM_LUN_ALRDY_ENA);
- }
tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
if (tptr == NULL) {
return (CAM_RESRC_UNAVAIL);
}
tptr->ts_lun = lun;
- status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun);
- if (status != CAM_REQ_CMP) {
- free(tptr, M_DEVBUF);
- return (status);
- }
SLIST_INIT(&tptr->atios);
SLIST_INIT(&tptr->inots);
- TAILQ_INIT(&tptr->waitq);
- LIST_INIT(&tptr->atfree);
- for (i = ATPDPSIZE-1; i >= 0; i--)
- LIST_INSERT_HEAD(&tptr->atfree, &tptr->atpool[i], next);
- for (i = 0; i < ATPDPHASHSIZE; i++)
- LIST_INIT(&tptr->atused[i]);
- for (i = 0; i < ATPDPSIZE-1; i++)
- tptr->ntpool[i].next = &tptr->ntpool[i+1];
- tptr->ntfree = tptr->ntpool;
- tptr->hold = 1;
ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
SLIST_INSERT_HEAD(lhp, tptr, next);
*rslt = tptr;
@@ -1146,34 +1079,30 @@ create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rsl
return (CAM_REQ_CMP);
}
-static ISP_INLINE void
-destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
+static void
+destroy_lun_state(ispsoftc_t *isp, int bus, tstate_t *tptr)
{
union ccb *ccb;
struct tslist *lhp;
+ inot_private_data_t *ntp;
- KASSERT((tptr->hold != 0), ("tptr is not held"));
- KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold));
- do {
- ccb = (union ccb *)SLIST_FIRST(&tptr->atios);
- if (ccb) {
- SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
- ccb->ccb_h.status = CAM_REQ_ABORTED;
- xpt_done(ccb);
- }
- } while (ccb);
- do {
- ccb = (union ccb *)SLIST_FIRST(&tptr->inots);
- if (ccb) {
- SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
- ccb->ccb_h.status = CAM_REQ_ABORTED;
- xpt_done(ccb);
- }
- } while (ccb);
- ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp);
+ while ((ccb = (union ccb *)SLIST_FIRST(&tptr->atios)) != NULL) {
+ SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
+ ccb->ccb_h.status = CAM_REQ_ABORTED;
+ xpt_done(ccb);
+ };
+ while ((ccb = (union ccb *)SLIST_FIRST(&tptr->inots)) != NULL) {
+ SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
+ ccb->ccb_h.status = CAM_REQ_ABORTED;
+ xpt_done(ccb);
+ }
+ while ((ntp = STAILQ_FIRST(&tptr->restart_queue)) != NULL) {
+ isp_endcmd(isp, ntp->data, NIL_HANDLE, bus, SCSI_STATUS_BUSY, 0);
+ STAILQ_REMOVE_HEAD(&tptr->restart_queue, next);
+ isp_put_ntpd(isp, bus, ntp);
+ }
+ ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp);
SLIST_REMOVE(lhp, tptr, tstate, next);
- ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "destroyed tstate\n");
- xpt_free_path(tptr->owner);
free(tptr, M_DEVBUF);
}
@@ -1220,7 +1149,6 @@ isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
return;
}
- rls_lun_statep(isp, tptr);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
}
@@ -1251,7 +1179,7 @@ isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
return;
}
- destroy_lun_state(isp, tptr);
+ destroy_lun_state(isp, bus, tptr);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
}
@@ -1260,43 +1188,33 @@ static void
isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
{
int fctape, sendstatus, resid;
- tstate_t *tptr;
fcparam *fcp;
atio_private_data_t *atp;
struct ccb_scsiio *cso;
+ struct isp_ccbq *waitq;
uint32_t dmaresult, handle, xfrlen, sense_length, tmp;
uint8_t local[QENTRY_LEN];
- tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
- if (tptr == NULL) {
- tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
- if (tptr == NULL) {
- isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find tstate pointer", __func__, ccb->csio.tag_id);
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
- xpt_done(ccb);
- return;
- }
- }
isp_prt(isp, ISP_LOGTDEBUG0, "%s: ENTRY[0x%x] how %u xfrlen %u sendstatus %d sense_len %u", __func__, ccb->csio.tag_id, how, ccb->csio.dxfer_len,
(ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0));
+ ISP_GET_PC_ADDR(isp, XS_CHANNEL(ccb), waitq, waitq);
switch (how) {
- case FROM_TIMER:
case FROM_CAM:
/*
* Insert at the tail of the list, if any, waiting CTIO CCBs
*/
- TAILQ_INSERT_TAIL(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_TAIL(waitq, &ccb->ccb_h, periph_links.tqe);
break;
+ case FROM_TIMER:
case FROM_SRR:
case FROM_CTIO_DONE:
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
- while (TAILQ_FIRST(&tptr->waitq) != NULL) {
- ccb = (union ccb *) TAILQ_FIRST(&tptr->waitq);
- TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ while ((ccb = (union ccb *) TAILQ_FIRST(waitq)) != NULL) {
+ TAILQ_REMOVE(waitq, &ccb->ccb_h, periph_links.tqe);
cso = &ccb->csio;
xfrlen = cso->dxfer_len;
@@ -1309,10 +1227,10 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
}
}
- atp = isp_find_atpd(isp, tptr, cso->tag_id);
+ atp = isp_find_atpd(isp, XS_CHANNEL(ccb), cso->tag_id);
if (atp == NULL) {
isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find private data adjunct in %s", __func__, cso->tag_id, __func__);
- isp_dump_atpd(isp, tptr);
+ isp_dump_atpd(isp, XS_CHANNEL(ccb));
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
xpt_done(ccb);
continue;
@@ -1345,7 +1263,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
*/
if (atp->ctcnt >= ATPD_CCB_OUTSTANDING) {
isp_prt(isp, ISP_LOGTINFO, "[0x%x] handling only %d CCBs at a time (flags for this ccb: 0x%x)", cso->tag_id, ATPD_CCB_OUTSTANDING, ccb->ccb_h.flags);
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
@@ -1462,7 +1380,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
if (atp->ests == NULL) {
atp->ests = isp_get_ecmd(isp);
if (atp->ests == NULL) {
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
}
@@ -1617,7 +1535,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
if (atp->ests == NULL) {
atp->ests = isp_get_ecmd(isp);
if (atp->ests == NULL) {
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
}
@@ -1706,13 +1624,13 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
if (isp_get_pcmd(isp, ccb)) {
ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "out of PCMDs\n");
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
handle = isp_allocate_handle(isp, ccb, ISP_HANDLE_TARGET);
if (handle == 0) {
ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
isp_free_pcmd(isp, ccb);
break;
}
@@ -1742,7 +1660,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
isp_destroy_handle(isp, handle);
isp_free_pcmd(isp, ccb);
if (dmaresult == CMD_EAGAIN) {
- TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
+ TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
@@ -1759,7 +1677,6 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
atp->ctcnt++;
atp->seqno++;
}
- rls_lun_statep(isp, tptr);
}
static void
@@ -1856,7 +1773,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
*/
if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status);
- isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
+ isp_endcmd(isp, aep, NIL_HANDLE, 0, SCSI_STATUS_BUSY, 0);
return;
}
@@ -1880,9 +1797,9 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
if (tptr == NULL) {
isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %jx or wildcard", __func__, aep->at_rxid, (uintmax_t)lun);
if (lun == 0) {
- isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
+ isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
} else {
- isp_endcmd(isp, aep, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
+ isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
}
return;
}
@@ -1891,38 +1808,15 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
/*
* Start any commands pending resources first.
*/
- if (tptr->restart_queue) {
- inot_private_data_t *restart_queue = tptr->restart_queue;
- tptr->restart_queue = NULL;
- while (restart_queue) {
- ntp = restart_queue;
- restart_queue = ntp->rd.nt.nt_hba;
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
- isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
- isp_put_ntpd(isp, tptr, ntp);
- /*
- * If a recursion caused the restart queue to start to fill again,
- * stop and splice the new list on top of the old list and restore
- * it and go to noresrc.
- */
- if (tptr->restart_queue) {
- ntp = tptr->restart_queue;
- tptr->restart_queue = restart_queue;
- while (restart_queue->rd.nt.nt_hba) {
- restart_queue = restart_queue->rd.nt.nt_hba;
- }
- restart_queue->rd.nt.nt_hba = ntp;
- goto noresrc;
- }
- }
- }
+ if (isp_atio_restart(isp, 0, tptr))
+ goto noresrc;
atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
if (atiop == NULL) {
goto noresrc;
}
- atp = isp_get_atpd(isp, tptr, aep->at_rxid);
+ atp = isp_get_atpd(isp, 0, aep->at_rxid);
if (atp == NULL) {
goto noresrc;
}
@@ -1997,19 +1891,15 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
atp->state = ATPD_STATE_CAM;
xpt_done((union ccb *)atiop);
isp_prt(isp, ISP_LOGTDEBUG0, "ATIO2[0x%x] CDB=0x%x lun %jx datalen %u", aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen);
- rls_lun_statep(isp, tptr);
return;
noresrc:
- ntp = isp_get_ntpd(isp, tptr);
+ ntp = isp_get_ntpd(isp, 0);
if (ntp == NULL) {
- rls_lun_statep(isp, tptr);
- isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
+ isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
return;
}
- memcpy(ntp->rd.data, aep, QENTRY_LEN);
- ntp->rd.nt.nt_hba = tptr->restart_queue;
- tptr->restart_queue = ntp;
- rls_lun_statep(isp, tptr);
+ memcpy(ntp->data, aep, QENTRY_LEN);
+ STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
}
static void
@@ -2114,40 +2004,13 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
/*
* Start any commands pending resources first.
*/
- if (tptr->restart_queue) {
- inot_private_data_t *restart_queue = tptr->restart_queue;
- tptr->restart_queue = NULL;
- while (restart_queue) {
- ntp = restart_queue;
- restart_queue = ntp->rd.nt.nt_hba;
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
- isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
- isp_put_ntpd(isp, tptr, ntp);
- /*
- * If a recursion caused the restart queue to start to fill again,
- * stop and splice the new list on top of the old list and restore
- * it and go to noresrc.
- */
- if (tptr->restart_queue) {
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: restart queue refilling", __func__);
- if (restart_queue) {
- ntp = tptr->restart_queue;
- tptr->restart_queue = restart_queue;
- while (restart_queue->rd.nt.nt_hba) {
- restart_queue = restart_queue->rd.nt.nt_hba;
- }
- restart_queue->rd.nt.nt_hba = ntp;
- }
- goto noresrc;
- }
- }
- }
+ if (isp_atio_restart(isp, chan, tptr))
+ goto noresrc;
/*
* If the f/w is out of resources, just send a BUSY status back.
*/
if (aep->at_rxid == AT7_NORESRC_RXID) {
- rls_lun_statep(isp, tptr);
isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
return;
}
@@ -2161,7 +2024,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
goto noresrc;
}
- oatp = isp_find_atpd(isp, tptr, aep->at_rxid);
+ oatp = isp_find_atpd(isp, chan, aep->at_rxid);
if (oatp) {
isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] tag wraparound in isp_handle_platforms_atio7 (N-Port Handle 0x%04x S_ID 0x%04x OX_ID 0x%04x) oatp state %d",
aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state);
@@ -2170,7 +2033,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
*/
goto noresrc;
}
- atp = isp_get_atpd(isp, tptr, aep->at_rxid);
+ atp = isp_get_atpd(isp, chan, aep->at_rxid);
if (atp == NULL) {
isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid);
goto noresrc;
@@ -2226,22 +2089,17 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %jx datalen %u",
aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen);
xpt_done((union ccb *)atiop);
- rls_lun_statep(isp, tptr);
return;
noresrc:
- if (atp) {
- isp_put_atpd(isp, tptr, atp);
- }
- ntp = isp_get_ntpd(isp, tptr);
+ if (atp)
+ isp_put_atpd(isp, chan, atp);
+ ntp = isp_get_ntpd(isp, chan);
if (ntp == NULL) {
- rls_lun_statep(isp, tptr);
isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
return;
}
- memcpy(ntp->rd.data, aep, QENTRY_LEN);
- ntp->rd.nt.nt_hba = tptr->restart_queue;
- tptr->restart_queue = ntp;
- rls_lun_statep(isp, tptr);
+ memcpy(ntp->data, aep, QENTRY_LEN);
+ STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
}
@@ -2252,7 +2110,7 @@ noresrc:
* transaction.
*/
static void
-isp_handle_srr_start(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp)
+isp_handle_srr_start(ispsoftc_t *isp, atio_private_data_t *atp)
{
in_fcentry_24xx_t *inot;
uint32_t srr_off, ccb_off, ccb_len, ccb_end;
@@ -2352,7 +2210,6 @@ mdp:
static void
isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw)
{
- tstate_t *tptr;
in_fcentry_24xx_t *inot = inot_raw;
atio_private_data_t *atp;
uint32_t tag = inot->in_rxid;
@@ -2363,15 +2220,8 @@ isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw)
return;
}
- tptr = get_lun_statep_from_tag(isp, bus, tag);
- if (tptr == NULL) {
- isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x in SRR Notify", __func__, tag);
- isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
- return;
- }
- atp = isp_find_atpd(isp, tptr, tag);
+ atp = isp_find_atpd(isp, bus, tag);
if (atp == NULL) {
- rls_lun_statep(isp, tptr);
isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify", __func__, tag);
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
return;
@@ -2381,8 +2231,7 @@ isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw)
isp_prt(isp, ISP_LOGTINFO /* ISP_LOGTDEBUG0 */, "SRR[0x%x] inot->in_rxid flags 0x%x srr_iu=%x reloff 0x%x", inot->in_rxid, inot->in_flags, inot->in_srr_iu,
inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16));
if (atp->srr_ccb)
- isp_handle_srr_start(isp, tptr, atp);
- rls_lun_statep(isp, tptr);
+ isp_handle_srr_start(isp, atp);
}
static void
@@ -2390,7 +2239,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
{
union ccb *ccb;
int sentstatus = 0, ok = 0, notify_cam = 0, resid = 0, failure = 0;
- tstate_t *tptr = NULL;
atio_private_data_t *atp = NULL;
int bus;
uint32_t handle, moved_data = 0, data_requested;
@@ -2409,19 +2257,10 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
}
bus = XS_CHANNEL(ccb);
- tptr = get_lun_statep(isp, bus, XS_LUN(ccb));
- if (tptr == NULL) {
- tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
- }
- if (tptr == NULL) {
- isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x after I/O", __func__, ccb->csio.tag_id);
- return;
- }
-
if (IS_24XX(isp)) {
- atp = isp_find_atpd(isp, tptr, ((ct7_entry_t *)arg)->ct_rxid);
+ atp = isp_find_atpd(isp, bus, ((ct7_entry_t *)arg)->ct_rxid);
} else {
- atp = isp_find_atpd(isp, tptr, ((ct2_entry_t *)arg)->ct_rxid);
+ atp = isp_find_atpd(isp, bus, ((ct2_entry_t *)arg)->ct_rxid);
}
if (atp == NULL) {
/*
@@ -2429,10 +2268,9 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
* ct_rxid value, filling only ct_syshandle. Workaround
* that using tag_id from the CCB, pointed by ct_syshandle.
*/
- atp = isp_find_atpd(isp, tptr, ccb->csio.tag_id);
+ atp = isp_find_atpd(isp, bus, ccb->csio.tag_id);
}
if (atp == NULL) {
- rls_lun_statep(isp, tptr);
isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id);
return;
}
@@ -2447,8 +2285,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
if (ct->ct_nphdl == CT7_SRR) {
atp->srr_ccb = ccb;
if (atp->srr_notify_rcvd)
- isp_handle_srr_start(isp, tptr, atp);
- rls_lun_statep(isp, tptr);
+ isp_handle_srr_start(isp, atp);
return;
}
if (ct->ct_nphdl == CT_HBA_RESET) {
@@ -2469,8 +2306,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
if (ct->ct_status == CT_SRR) {
atp->srr_ccb = ccb;
if (atp->srr_notify_rcvd)
- isp_handle_srr_start(isp, tptr, atp);
- rls_lun_statep(isp, tptr);
+ isp_handle_srr_start(isp, atp);
isp_target_putback_atio(ccb);
return;
}
@@ -2505,7 +2341,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
}
atp->state = ATPD_STATE_PDON;
- rls_lun_statep(isp, tptr);
/*
* We never *not* notify CAM when there has been any error (ok == 0),
@@ -2521,6 +2356,12 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
}
/*
+ * If we sent status or error happened, we are done with this ATIO.
+ */
+ if (sentstatus || !ok)
+ isp_put_atpd(isp, bus, atp);
+
+ /*
* We're telling CAM we're done with this CTIO transaction.
*
* 24XX cards never need an ATIO put back.
@@ -2560,13 +2401,11 @@ isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
break;
case IN_ABORT_TASK:
{
- tstate_t *tptr;
uint16_t nphdl, lun;
uint32_t sid;
uint64_t wwn;
- atio_private_data_t *atp;
fcportdb_t *lp;
- struct ccb_immediate_notify *inot = NULL;
+ isp_notify_t tmp, *nt = &tmp;
if (ISP_CAP_SCCFW(isp)) {
lun = inp->in_scclun;
@@ -2588,47 +2427,25 @@ isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
wwn = INI_ANY;
sid = PORT_ANY;
}
- tptr = get_lun_statep(isp, 0, lun);
- if (tptr == NULL) {
- tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
- if (tptr == NULL) {
- isp_prt(isp, ISP_LOGWARN, "ABORT TASK for lun %x, but no tstate", lun);
- return;
- }
- }
- atp = isp_find_atpd(isp, tptr, inp->in_seqid);
-
- if (atp) {
- inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots);
- isp_prt(isp, ISP_LOGTDEBUG0, "ABORT TASK RX_ID %x WWN 0x%016llx state %d", inp->in_seqid, (unsigned long long) wwn, atp->state);
- if (inot) {
- tptr->inot_count--;
- SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
- ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count);
- } else {
- ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "out of INOT structures\n");
- }
- } else {
- ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "abort task RX_ID %x from wwn 0x%016llx, state unknown\n", inp->in_seqid, wwn);
- }
- if (inot) {
- isp_notify_t tmp, *nt = &tmp;
- ISP_MEMZERO(nt, sizeof (isp_notify_t));
- nt->nt_hba = isp;
- nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn;
- nt->nt_wwn = wwn;
- nt->nt_nphdl = nphdl;
- nt->nt_sid = sid;
- nt->nt_did = PORT_ANY;
- nt->nt_lun = lun;
- nt->nt_need_ack = 1;
- nt->nt_channel = 0;
- nt->nt_ncode = NT_ABORT_TASK;
- nt->nt_lreserved = inot;
- isp_handle_platform_target_tmf(isp, nt);
- needack = 0;
- }
- rls_lun_statep(isp, tptr);
+ isp_prt(isp, ISP_LOGTDEBUG0, "ABORT TASK RX_ID %x WWN 0x%016llx",
+ inp->in_seqid, (unsigned long long) wwn);
+
+ ISP_MEMZERO(nt, sizeof (isp_notify_t));
+ nt->nt_hba = isp;
+ nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn;
+ nt->nt_wwn = wwn;
+ nt->nt_nphdl = nphdl;
+ nt->nt_sid = sid;
+ nt->nt_did = PORT_ANY;
+ nt->nt_lun = lun;
+ nt->nt_tagval = inp->in_seqid;
+ nt->nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
+ nt->nt_need_ack = 1;
+ nt->nt_channel = 0;
+ nt->nt_ncode = NT_ABORT_TASK;
+ nt->nt_lreserved = inp;
+ isp_handle_platform_target_tmf(isp, nt);
+ needack = 0;
break;
}
default:
@@ -2924,11 +2741,11 @@ isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
switch (notify->nt_ncode) {
case NT_ABORT_TASK:
- isp_target_mark_aborted_early(isp, tptr, inot->tag_id);
+ isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, inot->tag_id);
inot->arg = MSG_ABORT_TASK;
break;
case NT_ABORT_TASK_SET:
- isp_target_mark_aborted_early(isp, tptr, TAG_ANY);
+ isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, TAG_ANY);
inot->arg = MSG_ABORT_TASK_SET;
break;
case NT_CLEAR_ACA:
@@ -2954,30 +2771,26 @@ isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
goto bad;
}
- ntp = isp_get_ntpd(isp, tptr);
+ ntp = isp_get_ntpd(isp, notify->nt_channel);
if (ntp == NULL) {
isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__);
goto bad;
}
- ISP_MEMCPY(&ntp->rd.nt, notify, sizeof (isp_notify_t));
+ ISP_MEMCPY(&ntp->nt, notify, sizeof (isp_notify_t));
if (notify->nt_lreserved) {
- ISP_MEMCPY(&ntp->rd.data, notify->nt_lreserved, QENTRY_LEN);
- ntp->rd.nt.nt_lreserved = &ntp->rd.data;
+ ISP_MEMCPY(&ntp->data, notify->nt_lreserved, QENTRY_LEN);
+ ntp->nt.nt_lreserved = &ntp->data;
}
- ntp->rd.seq_id = notify->nt_tagval;
- ntp->rd.tag_id = notify->nt_tagval >> 32;
+ ntp->seq_id = notify->nt_tagval;
+ ntp->tag_id = notify->nt_tagval >> 32;
tptr->inot_count--;
SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
- rls_lun_statep(isp, tptr);
ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count);
inot->ccb_h.status = CAM_MESSAGE_RECV;
xpt_done((union ccb *)inot);
return;
bad:
- if (tptr) {
- rls_lun_statep(isp, tptr);
- }
if (notify->nt_need_ack && notify->nt_lreserved) {
if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) {
@@ -2989,72 +2802,39 @@ bad:
}
}
-/*
- * Find the associated private data and mark it as dead so
- * we don't try to work on it any further.
- */
static void
-isp_target_mark_aborted(ispsoftc_t *isp, union ccb *ccb)
+isp_target_mark_aborted_early(ispsoftc_t *isp, int chan, tstate_t *tptr, uint32_t tag_id)
{
- tstate_t *tptr;
- atio_private_data_t *atp;
- union ccb *accb = ccb->cab.abort_ccb;
-
- tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
- if (tptr == NULL) {
- tptr = get_lun_statep(isp, XS_CHANNEL(accb), CAM_LUN_WILDCARD);
- if (tptr == NULL) {
- ccb->ccb_h.status = CAM_REQ_INVALID;
- return;
- }
- }
-
- atp = isp_find_atpd(isp, tptr, accb->atio.tag_id);
- if (atp == NULL) {
- ccb->ccb_h.status = CAM_REQ_INVALID;
- } else {
- atp->dead = 1;
- ccb->ccb_h.status = CAM_REQ_CMP;
- }
- rls_lun_statep(isp, tptr);
-}
-
-static void
-isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id)
-{
- atio_private_data_t *atp;
- inot_private_data_t *restart_queue = tptr->restart_queue;
+ atio_private_data_t *atp, *atpool;
+ inot_private_data_t *ntp, *tmp;
+ uint32_t this_tag_id;
/*
* First, clean any commands pending restart
*/
- tptr->restart_queue = NULL;
- while (restart_queue) {
- uint32_t this_tag_id;
- inot_private_data_t *ntp = restart_queue;
-
- restart_queue = ntp->rd.nt.nt_hba;
-
- if (IS_24XX(isp)) {
- this_tag_id = ((at7_entry_t *)ntp->rd.data)->at_rxid;
- } else {
- this_tag_id = ((at2_entry_t *)ntp->rd.data)->at_rxid;
- }
+ STAILQ_FOREACH_SAFE(ntp, &tptr->restart_queue, next, tmp) {
+ if (IS_24XX(isp))
+ this_tag_id = ((at7_entry_t *)ntp->data)->at_rxid;
+ else
+ this_tag_id = ((at2_entry_t *)ntp->data)->at_rxid;
if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) {
- isp_put_ntpd(isp, tptr, ntp);
- } else {
- ntp->rd.nt.nt_hba = tptr->restart_queue;
- tptr->restart_queue = ntp;
+ isp_endcmd(isp, ntp->data, NIL_HANDLE, chan,
+ ECMD_TERMINATE, 0);
+ isp_put_ntpd(isp, chan, ntp);
+ STAILQ_REMOVE(&tptr->restart_queue, ntp,
+ inot_private_data, next);
}
}
/*
* Now mark other ones dead as well.
*/
- for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
- if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id) {
+ ISP_GET_PC(isp, chan, atpool, atpool);
+ for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
+ if (atp->lun != tptr->ts_lun)
+ continue;
+ if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id)
atp->dead = 1;
- }
}
}
#endif
@@ -3453,6 +3233,77 @@ isp_kthread(void *arg)
kthread_exit();
}
+#ifdef ISP_TARGET_MODE
+static void
+isp_abort_atio(ispsoftc_t *isp, union ccb *ccb)
+{
+ atio_private_data_t *atp;
+ union ccb *accb = ccb->cab.abort_ccb;
+ struct ccb_hdr *sccb;
+ tstate_t *tptr;
+
+ tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
+ if (tptr != NULL) {
+ /* Search for the ATIO among queueued. */
+ SLIST_FOREACH(sccb, &tptr->atios, sim_links.sle) {
+ if (sccb != &accb->ccb_h)
+ continue;
+ SLIST_REMOVE(&tptr->atios, sccb, ccb_hdr, sim_links.sle);
+ tptr->atio_count--;
+ accb->ccb_h.status = CAM_REQ_ABORTED;
+ xpt_done(accb);
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ return;
+ }
+ }
+
+ /* Search for the ATIO among running. */
+ atp = isp_find_atpd(isp, XS_CHANNEL(accb), accb->atio.tag_id);
+ if (atp != NULL) {
+ /* XXX Send TERMINATE to firmware here. */
+ isp_put_atpd(isp, XS_CHANNEL(accb), atp);
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ } else {
+ ccb->ccb_h.status = CAM_UA_ABORT;
+ }
+}
+
+static void
+isp_abort_inot(ispsoftc_t *isp, union ccb *ccb)
+{
+ inot_private_data_t *ntp;
+ union ccb *accb = ccb->cab.abort_ccb;
+ struct ccb_hdr *sccb;
+ tstate_t *tptr;
+
+ tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
+ if (tptr != NULL) {
+ /* Search for the INOT among queueued. */
+ SLIST_FOREACH(sccb, &tptr->inots, sim_links.sle) {
+ if (sccb != &accb->ccb_h)
+ continue;
+ SLIST_REMOVE(&tptr->inots, sccb, ccb_hdr, sim_links.sle);
+ tptr->inot_count--;
+ accb->ccb_h.status = CAM_REQ_ABORTED;
+ xpt_done(accb);
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ return;
+ }
+ }
+
+ /* Search for the INOT among running. */
+ ntp = isp_find_ntpd(isp, XS_CHANNEL(accb), accb->cin1.tag_id, accb->cin1.seq_id);
+ if (ntp != NULL) {
+ isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, ntp->data);
+ isp_put_ntpd(isp, XS_CHANNEL(accb), ntp);
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ } else {
+ ccb->ccb_h.status = CAM_UA_ABORT;
+ return;
+ }
+}
+#endif
+
static void
isp_action(struct cam_sim *sim, union ccb *ccb)
{
@@ -3565,27 +3416,20 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
isp_disable_lun(isp, ccb);
}
break;
- case XPT_IMMED_NOTIFY:
case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */
case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */
{
tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
if (tptr == NULL) {
- tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
- }
- if (tptr == NULL) {
const char *str;
- uint32_t tag;
- if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
+ if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY)
str = "XPT_IMMEDIATE_NOTIFY";
- tag = ccb->cin1.seq_id;
- } else {
- tag = ccb->atio.tag_id;
+ else
str = "XPT_ACCEPT_TARGET_IO";
- }
- ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] no state pointer found for %s\n", __func__, tag, str);
- dump_tstates(isp, XS_CHANNEL(ccb));
+ ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path,
+ "%s: [0x%x] no state pointer found for %s\n",
+ __func__, str);
ccb->ccb_h.status = CAM_DEV_NOT_THERE;
break;
}
@@ -3593,46 +3437,23 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
ccb->ccb_h.spriv_ptr1 = isp;
if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
- if (ccb->atio.tag_id) {
- atio_private_data_t *atp = isp_find_atpd(isp, tptr, ccb->atio.tag_id);
- if (atp) {
- isp_put_atpd(isp, tptr, atp);
- }
- }
+ ccb->atio.tag_id = 0;
tptr->atio_count++;
SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
- ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n",
- ccb->atio.tag_id, tptr->atio_count);
- ccb->atio.tag_id = 0;
+ ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path,
+ "Put FREE ATIO, count now %d\n", tptr->atio_count);
} else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
- if (ccb->cin1.tag_id) {
- inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id);
- if (ntp) {
- isp_put_ntpd(isp, tptr, ntp);
- }
- }
- tptr->inot_count++;
- SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
- ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
- ccb->cin1.seq_id, tptr->inot_count);
- ccb->cin1.seq_id = 0;
- } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
+ ccb->cin1.seq_id = ccb->cin1.tag_id = 0;
tptr->inot_count++;
SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
- ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n",
- ccb->cin1.seq_id, tptr->inot_count);
- ccb->cin1.seq_id = 0;
+ ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path,
+ "Put FREE INOT, count now %d\n", tptr->inot_count);
}
- rls_lun_statep(isp, tptr);
ccb->ccb_h.status = CAM_REQ_INPROG;
break;
}
- case XPT_NOTIFY_ACK:
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
- break;
case XPT_NOTIFY_ACKNOWLEDGE: /* notify ack */
{
- tstate_t *tptr;
inot_private_data_t *ntp;
/*
@@ -3643,7 +3464,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
* All the relevant path information is in the associated immediate notify
*/
ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] NOTIFY ACKNOWLEDGE for 0x%x seen\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
- ntp = get_ntp_from_tagdata(isp, ccb->cna2.tag_id, ccb->cna2.seq_id, &tptr);
+ ntp = isp_find_ntpd(isp, XS_CHANNEL(ccb), ccb->cna2.tag_id, ccb->cna2.seq_id);
if (ntp == NULL) {
ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] XPT_NOTIFY_ACKNOWLEDGE of 0x%x cannot find ntp private data\n", __func__,
ccb->cna2.tag_id, ccb->cna2.seq_id);
@@ -3651,17 +3472,15 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
xpt_done(ccb);
break;
}
- if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt,
+ if (isp_handle_platform_target_notify_ack(isp, &ntp->nt,
(ccb->ccb_h.flags & CAM_SEND_STATUS) ? ccb->cna2.arg : 0)) {
- rls_lun_statep(isp, tptr);
cam_freeze_devq(ccb->ccb_h.path);
cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
ccb->ccb_h.status |= CAM_REQUEUE_REQ;
break;
}
- isp_put_ntpd(isp, tptr, ntp);
- rls_lun_statep(isp, tptr);
+ isp_put_ntpd(isp, XS_CHANNEL(ccb), ntp);
ccb->ccb_h.status = CAM_REQ_CMP;
ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] calling xpt_done for tag 0x%x\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
xpt_done(ccb);
@@ -3698,7 +3517,10 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
switch (accb->ccb_h.func_code) {
#ifdef ISP_TARGET_MODE
case XPT_ACCEPT_TARGET_IO:
- isp_target_mark_aborted(isp, ccb);
+ isp_abort_atio(isp, ccb);
+ break;
+ case XPT_IMMEDIATE_NOTIFY:
+ isp_abort_inot(isp, ccb);
break;
#endif
case XPT_SCSI_IO:
@@ -4486,7 +4308,7 @@ changed:
{
abts_t *abts = (abts_t *)hp;
isp_notify_t notify, *nt = &notify;
- tstate_t *tptr;
+ atio_private_data_t *atp;
fcportdb_t *lp;
uint16_t chan;
uint32_t sid, did;
@@ -4513,13 +4335,8 @@ changed:
/*
* Try hard to find the lun for this command.
*/
- tptr = get_lun_statep_from_tag(isp, chan, abts->abts_rxid_task);
- if (tptr) {
- nt->nt_lun = tptr->ts_lun;
- rls_lun_statep(isp, tptr);
- } else {
- nt->nt_lun = LUN_ANY;
- }
+ atp = isp_find_atpd(isp, chan, abts->abts_rxid_task);
+ nt->nt_lun = atp ? atp->lun : LUN_ANY;
nt->nt_need_ack = 1;
nt->nt_tagval = abts->abts_rxid_task;
nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32);
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index d6c62a291608..e50ee16d1030 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -88,14 +88,6 @@ isp_ecmd_t * isp_get_ecmd(struct ispsoftc *);
void isp_put_ecmd(struct ispsoftc *, isp_ecmd_t *);
#ifdef ISP_TARGET_MODE
-/* Not quite right, but there was no bump for this change */
-#if __FreeBSD_version < 225469
-#define SDFIXED(x) (&x)
-#else
-#define SDFIXED(x) ((struct scsi_sense_data_fixed *)(&x))
-#endif
-
-#define ISP_TARGET_FUNCTIONS 1
#define ATPDPSIZE 4096
#define ATPDPHASHSIZE 32
#define ATPDPHASH(x) ((((x) >> 24) ^ ((x) >> 16) ^ ((x) >> 8) ^ (x)) & \
@@ -108,7 +100,7 @@ typedef struct atio_private_data {
uint32_t bytes_xfered;
uint32_t bytes_in_transit;
uint32_t tag; /* typically f/w RX_ID */
- uint32_t lun;
+ lun_id_t lun;
uint32_t nphdl;
uint32_t sid;
uint32_t portid;
@@ -147,14 +139,12 @@ typedef struct atio_private_data {
#define ATPD_GET_SEQNO(hdrp) (((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_MASK)
#define ATPD_GET_NCAM(hdrp) ((((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0)
-typedef union inot_private_data inot_private_data_t;
-union inot_private_data {
- inot_private_data_t *next;
- struct {
- isp_notify_t nt; /* must be first! */
- uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */
- uint32_t tag_id, seq_id;
- } rd;
+typedef struct inot_private_data inot_private_data_t;
+struct inot_private_data {
+ STAILQ_ENTRY(inot_private_data) next;
+ isp_notify_t nt;
+ uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */
+ uint32_t tag_id, seq_id;
};
typedef struct isp_timed_notify_ack {
void *isp;
@@ -163,23 +153,15 @@ typedef struct isp_timed_notify_ack {
struct callout timer;
} isp_tna_t;
-TAILQ_HEAD(isp_ccbq, ccb_hdr);
+STAILQ_HEAD(ntpdlist, inot_private_data);
typedef struct tstate {
- SLIST_ENTRY(tstate) next;
- lun_id_t ts_lun;
- struct cam_path *owner;
- struct isp_ccbq waitq; /* waiting CCBs */
- struct ccb_hdr_slist atios;
- struct ccb_hdr_slist inots;
- uint32_t hold;
+ SLIST_ENTRY(tstate) next;
+ lun_id_t ts_lun;
+ struct ccb_hdr_slist atios;
+ struct ccb_hdr_slist inots;
+ struct ntpdlist restart_queue;
uint16_t atio_count;
uint16_t inot_count;
- inot_private_data_t * restart_queue;
- inot_private_data_t * ntfree;
- inot_private_data_t ntpool[ATPDPSIZE];
- LIST_HEAD(, atio_private_data) atfree;
- LIST_HEAD(, atio_private_data) atused[ATPDPHASHSIZE];
- atio_private_data_t atpool[ATPDPSIZE];
} tstate_t;
#define LUN_HASH_SIZE 32
@@ -220,6 +202,8 @@ struct isp_nexus {
* Per channel information
*/
SLIST_HEAD(tslist, tstate);
+TAILQ_HEAD(isp_ccbq, ccb_hdr);
+LIST_HEAD(atpdlist, atio_private_data);
struct isp_fc {
struct cam_sim *sim;
@@ -249,7 +233,13 @@ struct isp_fc {
struct callout gdt; /* gone device timer */
struct task gtask;
#ifdef ISP_TARGET_MODE
- struct tslist lun_hash[LUN_HASH_SIZE];
+ struct tslist lun_hash[LUN_HASH_SIZE];
+ struct isp_ccbq waitq; /* waiting CCBs */
+ struct ntpdlist ntfree;
+ inot_private_data_t ntpool[ATPDPSIZE];
+ struct atpdlist atfree;
+ struct atpdlist atused[ATPDPHASHSIZE];
+ atio_private_data_t atpool[ATPDPSIZE];
#if defined(DEBUG)
unsigned int inject_lost_data_frame;
#endif
@@ -264,7 +254,13 @@ struct isp_spi {
simqfrozen : 3,
iid : 4;
#ifdef ISP_TARGET_MODE
- struct tslist lun_hash[LUN_HASH_SIZE];
+ struct tslist lun_hash[LUN_HASH_SIZE];
+ struct isp_ccbq waitq; /* waiting CCBs */
+ struct ntpdlist ntfree;
+ inot_private_data_t ntpool[ATPDPSIZE];
+ struct atpdlist atfree;
+ struct atpdlist atused[ATPDPHASHSIZE];
+ atio_private_data_t atpool[ATPDPSIZE];
#endif
int num_threads;
};
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index b0acd9605b75..8a51cf511a75 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -583,10 +583,10 @@ isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
name, &tval) == 0 && tval != 0) {
isp->isp_confopts |= ISP_CFG_FULL_DUPLEX;
}
- sptr = 0;
+ sptr = NULL;
snprintf(name, sizeof(name), "%stopology", prefix);
if (resource_string_value(device_get_name(dev), device_get_unit(dev),
- name, (const char **) &sptr) == 0 && sptr != 0) {
+ name, (const char **) &sptr) == 0 && sptr != NULL) {
if (strcmp(sptr, "lport") == 0) {
isp->isp_confopts |= ISP_CFG_LPORT;
} else if (strcmp(sptr, "nport") == 0) {
@@ -631,12 +631,12 @@ isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
* hint replacement to specify WWN strings with a leading
* 'w' (e..g w50000000aaaa0001). Sigh.
*/
- sptr = 0;
+ sptr = NULL;
snprintf(name, sizeof(name), "%sportwwn", prefix);
tval = resource_string_value(device_get_name(dev), device_get_unit(dev),
name, (const char **) &sptr);
- if (tval == 0 && sptr != 0 && *sptr++ == 'w') {
- char *eptr = 0;
+ if (tval == 0 && sptr != NULL && *sptr++ == 'w') {
+ char *eptr = NULL;
ISP_FC_PC(isp, chan)->def_wwpn = strtouq(sptr, &eptr, 16);
if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwpn == -1) {
device_printf(dev, "mangled portwwn hint '%s'\n", sptr);
@@ -644,12 +644,12 @@ isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
}
}
- sptr = 0;
+ sptr = NULL;
snprintf(name, sizeof(name), "%snodewwn", prefix);
tval = resource_string_value(device_get_name(dev), device_get_unit(dev),
name, (const char **) &sptr);
- if (tval == 0 && sptr != 0 && *sptr++ == 'w') {
- char *eptr = 0;
+ if (tval == 0 && sptr != NULL && *sptr++ == 'w') {
+ char *eptr = NULL;
ISP_FC_PC(isp, chan)->def_wwnn = strtouq(sptr, &eptr, 16);
if (eptr < sptr + 16 || ISP_FC_PC(isp, chan)->def_wwnn == 0) {
device_printf(dev, "mangled nodewwn hint '%s'\n", sptr);
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c
index c5c277f0772c..5a31ea766540 100644
--- a/sys/dev/isp/isp_target.c
+++ b/sys/dev/isp/isp_target.c
@@ -503,11 +503,11 @@ isp_endcmd(ispsoftc_t *isp, ...)
ct7_entry_t _ctio7;
} un;
va_list ap;
+ int vpidx, nphdl;
ISP_MEMZERO(&un, sizeof un);
if (IS_24XX(isp)) {
- int vpidx, nphdl;
at7_entry_t *aep;
ct7_entry_t *cto = &un._ctio7;
@@ -573,6 +573,9 @@ isp_endcmd(ispsoftc_t *isp, ...)
va_start(ap, isp);
aep = va_arg(ap, at2_entry_t *);
+ /* nphdl and vpidx are unused here. */
+ nphdl = va_arg(ap, int);
+ vpidx = va_arg(ap, int);
code = va_arg(ap, uint32_t);
hdl = va_arg(ap, uint32_t);
va_end(ap);
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c
index f1116f61e0f4..8e049e36ec0f 100644
--- a/sys/dev/iwi/if_iwi.c
+++ b/sys/dev/iwi/if_iwi.c
@@ -1979,9 +1979,9 @@ iwi_start(struct iwi_softc *sc)
}
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (iwi_tx_start(sc, m, ni, ac) != 0) {
- ieee80211_free_node(ni);
if_inc_counter(ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
break;
}
sc->sc_tx_timer = 5;
diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
index 54f325e7031f..9a9ce9242a9d 100644
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -152,6 +152,7 @@ __FBSDID("$FreeBSD$");
#include <dev/iwm/if_iwmreg.h>
#include <dev/iwm/if_iwmvar.h>
+#include <dev/iwm/if_iwm_config.h>
#include <dev/iwm/if_iwm_debug.h>
#include <dev/iwm/if_iwm_notif_wait.h>
#include <dev/iwm/if_iwm_util.h>
@@ -166,68 +167,6 @@ __FBSDID("$FreeBSD$");
#include <dev/iwm/if_iwm_pcie_trans.h>
#include <dev/iwm/if_iwm_led.h>
-#define IWM_NVM_HW_SECTION_NUM_FAMILY_7000 0
-#define IWM_NVM_HW_SECTION_NUM_FAMILY_8000 10
-
-/* lower blocks contain EEPROM image and calibration data */
-#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(uint16_t)) /* 16 KB */
-#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(uint16_t)) /* 32 KB */
-
-#define IWM7260_FW "iwm7260fw"
-#define IWM3160_FW "iwm3160fw"
-#define IWM7265_FW "iwm7265fw"
-#define IWM7265D_FW "iwm7265Dfw"
-#define IWM8000_FW "iwm8000Cfw"
-
-#define IWM_DEVICE_7000_COMMON \
- .device_family = IWM_DEVICE_FAMILY_7000, \
- .eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000, \
- .nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000, \
- .apmg_wake_up_wa = 1
-
-const struct iwm_cfg iwm7260_cfg = {
- .fw_name = IWM7260_FW,
- IWM_DEVICE_7000_COMMON,
- .host_interrupt_operation_mode = 1,
-};
-
-const struct iwm_cfg iwm3160_cfg = {
- .fw_name = IWM3160_FW,
- IWM_DEVICE_7000_COMMON,
- .host_interrupt_operation_mode = 1,
-};
-
-const struct iwm_cfg iwm3165_cfg = {
- /* XXX IWM7265D_FW doesn't seem to work properly yet */
- .fw_name = IWM7265_FW,
- IWM_DEVICE_7000_COMMON,
- .host_interrupt_operation_mode = 0,
-};
-
-const struct iwm_cfg iwm7265_cfg = {
- .fw_name = IWM7265_FW,
- IWM_DEVICE_7000_COMMON,
- .host_interrupt_operation_mode = 0,
-};
-
-const struct iwm_cfg iwm7265d_cfg = {
- /* XXX IWM7265D_FW doesn't seem to work properly yet */
- .fw_name = IWM7265_FW,
- IWM_DEVICE_7000_COMMON,
- .host_interrupt_operation_mode = 0,
-};
-
-#define IWM_DEVICE_8000_COMMON \
- .device_family = IWM_DEVICE_FAMILY_8000, \
- .eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000, \
- .nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_8000
-
-const struct iwm_cfg iwm8260_cfg = {
- .fw_name = IWM8000_FW,
- IWM_DEVICE_8000_COMMON,
- .host_interrupt_operation_mode = 0,
-};
-
const uint8_t iwm_nvm_channels[] = {
/* 2.4 GHz */
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
@@ -285,8 +224,14 @@ struct iwm_nvm_section {
uint8_t *data;
};
+#define IWM_MVM_UCODE_ALIVE_TIMEOUT hz
#define IWM_MVM_UCODE_CALIB_TIMEOUT (2*hz)
+struct iwm_mvm_alive_data {
+ int valid;
+ uint32_t scd_base_addr;
+};
+
static int iwm_store_cscheme(struct iwm_softc *, const uint8_t *, size_t);
static int iwm_firmware_store_section(struct iwm_softc *,
enum iwm_ucode_type,
@@ -294,10 +239,6 @@ static int iwm_firmware_store_section(struct iwm_softc *,
static int iwm_set_default_calib(struct iwm_softc *, const void *);
static void iwm_fw_info_free(struct iwm_fw_info *);
static int iwm_read_firmware(struct iwm_softc *, enum iwm_ucode_type);
-static void iwm_dma_map_addr(void *, bus_dma_segment_t *, int, int);
-static int iwm_dma_contig_alloc(bus_dma_tag_t, struct iwm_dma_info *,
- bus_size_t, bus_size_t);
-static void iwm_dma_contig_free(struct iwm_dma_info *);
static int iwm_alloc_fwmem(struct iwm_softc *);
static int iwm_alloc_sched(struct iwm_softc *);
static int iwm_alloc_kw(struct iwm_softc *);
@@ -320,7 +261,7 @@ static int iwm_nic_rx_init(struct iwm_softc *);
static int iwm_nic_tx_init(struct iwm_softc *);
static int iwm_nic_init(struct iwm_softc *);
static int iwm_enable_txq(struct iwm_softc *, int, int, int);
-static int iwm_post_alive(struct iwm_softc *);
+static int iwm_trans_pcie_fw_alive(struct iwm_softc *, uint32_t);
static int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
uint16_t, uint8_t *, uint16_t *);
static int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
@@ -353,16 +294,21 @@ static void iwm_set_radio_cfg(const struct iwm_softc *,
static struct iwm_nvm_data *
iwm_parse_nvm_sections(struct iwm_softc *, struct iwm_nvm_section *);
static int iwm_nvm_init(struct iwm_softc *);
-static int iwm_firmware_load_sect(struct iwm_softc *, uint32_t,
- const uint8_t *, uint32_t);
-static int iwm_firmware_load_chunk(struct iwm_softc *, uint32_t,
- const uint8_t *, uint32_t);
-static int iwm_load_firmware_7000(struct iwm_softc *, enum iwm_ucode_type);
-static int iwm_load_cpu_sections_8000(struct iwm_softc *,
- struct iwm_fw_sects *, int , int *);
-static int iwm_load_firmware_8000(struct iwm_softc *, enum iwm_ucode_type);
-static int iwm_load_firmware(struct iwm_softc *, enum iwm_ucode_type);
-static int iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type);
+static int iwm_pcie_load_section(struct iwm_softc *, uint8_t,
+ const struct iwm_fw_desc *);
+static int iwm_pcie_load_firmware_chunk(struct iwm_softc *, uint32_t,
+ bus_addr_t, uint32_t);
+static int iwm_pcie_load_cpu_sections_8000(struct iwm_softc *sc,
+ const struct iwm_fw_sects *,
+ int, int *);
+static int iwm_pcie_load_cpu_sections(struct iwm_softc *,
+ const struct iwm_fw_sects *,
+ int, int *);
+static int iwm_pcie_load_given_ucode_8000(struct iwm_softc *,
+ const struct iwm_fw_sects *);
+static int iwm_pcie_load_given_ucode(struct iwm_softc *,
+ const struct iwm_fw_sects *);
+static int iwm_start_fw(struct iwm_softc *, const struct iwm_fw_sects *);
static int iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t);
static int iwm_send_phy_cfg_cmd(struct iwm_softc *);
static int iwm_mvm_load_ucode_wait_alive(struct iwm_softc *,
@@ -485,7 +431,7 @@ iwm_firmware_store_section(struct iwm_softc *sc,
enum iwm_ucode_type type, const uint8_t *data, size_t dlen)
{
struct iwm_fw_sects *fws;
- struct iwm_fw_onesect *fwone;
+ struct iwm_fw_desc *fwone;
if (type >= IWM_UCODE_TYPE_MAX)
return EINVAL;
@@ -499,11 +445,11 @@ iwm_firmware_store_section(struct iwm_softc *sc,
fwone = &fws->fw_sect[fws->fw_count];
/* first 32bit are device load offset */
- memcpy(&fwone->fws_devoff, data, sizeof(uint32_t));
+ memcpy(&fwone->offset, data, sizeof(uint32_t));
/* rest is data */
- fwone->fws_data = data + sizeof(uint32_t);
- fwone->fws_len = dlen - sizeof(uint32_t);
+ fwone->data = data + sizeof(uint32_t);
+ fwone->len = dlen - sizeof(uint32_t);
fws->fw_count++;
@@ -559,6 +505,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
const uint8_t *data;
uint32_t usniffer_img;
uint32_t paging_mem_size;
+ int num_of_cpus;
int error = 0;
size_t len;
@@ -699,18 +646,24 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
goto parse_out;
}
break;
- case IWM_UCODE_TLV_NUM_OF_CPU: {
- uint32_t num_cpu;
+ case IWM_UCODE_TLV_NUM_OF_CPU:
if (tlv_len != sizeof(uint32_t)) {
device_printf(sc->sc_dev,
- "%s: IWM_UCODE_TLV_NUM_OF_CPU: tlv_len (%d) < sizeof(uint32_t)\n",
+ "%s: IWM_UCODE_TLV_NUM_OF_CPU: tlv_len (%d) != sizeof(uint32_t)\n",
__func__,
(int) tlv_len);
error = EINVAL;
goto parse_out;
}
- num_cpu = le32toh(*(const uint32_t *)tlv_data);
- if (num_cpu < 1 || num_cpu > 2) {
+ num_of_cpus = le32toh(*(const uint32_t *)tlv_data);
+ if (num_of_cpus == 2) {
+ fw->fw_sects[IWM_UCODE_REGULAR].is_dual_cpus =
+ TRUE;
+ fw->fw_sects[IWM_UCODE_INIT].is_dual_cpus =
+ TRUE;
+ fw->fw_sects[IWM_UCODE_WOWLAN].is_dual_cpus =
+ TRUE;
+ } else if ((num_of_cpus > 2) || (num_of_cpus < 1)) {
device_printf(sc->sc_dev,
"%s: Driver supports only 1 or 2 CPUs\n",
__func__);
@@ -718,7 +671,6 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
goto parse_out;
}
break;
- }
case IWM_UCODE_TLV_SEC_RT:
if ((error = iwm_firmware_store_section(sc,
IWM_UCODE_REGULAR, tlv_data, tlv_len)) != 0) {
@@ -937,78 +889,13 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
* DMA resource routines
*/
-static void
-iwm_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
-{
- if (error != 0)
- return;
- KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
- *(bus_addr_t *)arg = segs[0].ds_addr;
-}
-
-static int
-iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
- bus_size_t size, bus_size_t alignment)
-{
- int error;
-
- dma->tag = NULL;
- dma->map = NULL;
- dma->size = size;
- dma->vaddr = NULL;
-
- error = bus_dma_tag_create(tag, alignment,
- 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
- 1, size, 0, NULL, NULL, &dma->tag);
- if (error != 0)
- goto fail;
-
- error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
- BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map);
- if (error != 0)
- goto fail;
-
- error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size,
- iwm_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT);
- if (error != 0) {
- bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
- dma->vaddr = NULL;
- goto fail;
- }
-
- bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
-
- return 0;
-
-fail:
- iwm_dma_contig_free(dma);
-
- return error;
-}
-
-static void
-iwm_dma_contig_free(struct iwm_dma_info *dma)
-{
- if (dma->vaddr != NULL) {
- bus_dmamap_sync(dma->tag, dma->map,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(dma->tag, dma->map);
- bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
- dma->vaddr = NULL;
- }
- if (dma->tag != NULL) {
- bus_dma_tag_destroy(dma->tag);
- dma->tag = NULL;
- }
-}
-
/* fwmem is used to load firmware onto the card */
static int
iwm_alloc_fwmem(struct iwm_softc *sc)
{
/* Must be aligned on a 16-byte boundary. */
return iwm_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma,
- sc->sc_fwdmasegsz, 16);
+ IWM_FH_MEM_TB_MAX_LENGTH, 16);
}
/* tx scheduler rings. not used? */
@@ -1622,20 +1509,33 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
(0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
| (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+ iwm_nic_unlock(sc);
+
iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
+ if (!iwm_nic_lock(sc)) {
+ device_printf(sc->sc_dev,
+ "%s: cannot enable txq %d\n", __func__, qid);
+ return EBUSY;
+ }
iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
+ iwm_nic_unlock(sc);
- iwm_write_mem32(sc, sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
+ iwm_write_mem32(sc, sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
/* Set scheduler window size and frame limit. */
iwm_write_mem32(sc,
- sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
+ sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
sizeof(uint32_t),
((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+ if (!iwm_nic_lock(sc)) {
+ device_printf(sc->sc_dev,
+ "%s: cannot enable txq %d\n", __func__, qid);
+ return EBUSY;
+ }
iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
(1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
(fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
@@ -1679,33 +1579,37 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
}
static int
-iwm_post_alive(struct iwm_softc *sc)
+iwm_trans_pcie_fw_alive(struct iwm_softc *sc, uint32_t scd_base_addr)
{
- int nwords;
int error, chnl;
- uint32_t base;
+
+ int clear_dwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
+ IWM_SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(uint32_t);
if (!iwm_nic_lock(sc))
return EBUSY;
- base = iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR);
- if (sc->sched_base != base) {
+ iwm_ict_reset(sc);
+
+ iwm_nic_unlock(sc);
+
+ sc->scd_base_addr = iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR);
+ if (scd_base_addr != 0 &&
+ scd_base_addr != sc->scd_base_addr) {
device_printf(sc->sc_dev,
"%s: sched addr mismatch: alive: 0x%x prph: 0x%x\n",
- __func__, sc->sched_base, base);
+ __func__, sc->scd_base_addr, scd_base_addr);
}
- iwm_ict_reset(sc);
-
- /* Clear TX scheduler state in SRAM. */
- nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
- IWM_SCD_CONTEXT_MEM_LOWER_BOUND)
- / sizeof(uint32_t);
+ /* reset context data, TX status and translation data */
error = iwm_write_mem(sc,
- sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND,
- NULL, nwords);
+ sc->scd_base_addr + IWM_SCD_CONTEXT_MEM_LOWER_BOUND,
+ NULL, clear_dwords);
if (error)
- goto out;
+ return EBUSY;
+
+ if (!iwm_nic_lock(sc))
+ return EBUSY;
/* Set physical address of TX scheduler rings (1KB aligned). */
iwm_write_prph(sc, IWM_SCD_DRAM_BASE_ADDR, sc->sched_dma.paddr >> 10);
@@ -1734,14 +1638,14 @@ iwm_post_alive(struct iwm_softc *sc)
IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
+ iwm_nic_unlock(sc);
+
/* Enable L1-Active */
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) {
iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
}
- out:
- iwm_nic_unlock(sc);
return error;
}
@@ -2414,52 +2318,67 @@ iwm_nvm_init(struct iwm_softc *sc)
return 0;
}
-/*
- * Firmware loading gunk. This is kind of a weird hybrid between the
- * iwn driver and the Linux iwlwifi driver.
- */
-
static int
-iwm_firmware_load_sect(struct iwm_softc *sc, uint32_t dst_addr,
- const uint8_t *section, uint32_t byte_cnt)
+iwm_pcie_load_section(struct iwm_softc *sc, uint8_t section_num,
+ const struct iwm_fw_desc *section)
{
- int error = EINVAL;
- uint32_t chunk_sz, offset;
+ struct iwm_dma_info *dma = &sc->fw_dma;
+ uint8_t *v_addr;
+ bus_addr_t p_addr;
+ uint32_t offset, chunk_sz = MIN(IWM_FH_MEM_TB_MAX_LENGTH, section->len);
+ int ret = 0;
+
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+ "%s: [%d] uCode section being loaded...\n",
+ __func__, section_num);
- chunk_sz = MIN(IWM_FH_MEM_TB_MAX_LENGTH, byte_cnt);
+ v_addr = dma->vaddr;
+ p_addr = dma->paddr;
- for (offset = 0; offset < byte_cnt; offset += chunk_sz) {
- uint32_t addr, len;
- const uint8_t *data;
+ for (offset = 0; offset < section->len; offset += chunk_sz) {
+ uint32_t copy_size, dst_addr;
+ int extended_addr = FALSE;
- addr = dst_addr + offset;
- len = MIN(chunk_sz, byte_cnt - offset);
- data = section + offset;
+ copy_size = MIN(chunk_sz, section->len - offset);
+ dst_addr = section->offset + offset;
- error = iwm_firmware_load_chunk(sc, addr, data, len);
- if (error)
+ if (dst_addr >= IWM_FW_MEM_EXTENDED_START &&
+ dst_addr <= IWM_FW_MEM_EXTENDED_END)
+ extended_addr = TRUE;
+
+ if (extended_addr)
+ iwm_set_bits_prph(sc, IWM_LMPM_CHICK,
+ IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
+
+ memcpy(v_addr, (const uint8_t *)section->data + offset,
+ copy_size);
+ bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
+ ret = iwm_pcie_load_firmware_chunk(sc, dst_addr, p_addr,
+ copy_size);
+
+ if (extended_addr)
+ iwm_clear_bits_prph(sc, IWM_LMPM_CHICK,
+ IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
+
+ if (ret) {
+ device_printf(sc->sc_dev,
+ "%s: Could not load the [%d] uCode section\n",
+ __func__, section_num);
break;
+ }
}
- return error;
+ return ret;
}
+/*
+ * ucode
+ */
static int
-iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
- const uint8_t *chunk, uint32_t byte_cnt)
+iwm_pcie_load_firmware_chunk(struct iwm_softc *sc, uint32_t dst_addr,
+ bus_addr_t phy_addr, uint32_t byte_cnt)
{
- struct iwm_dma_info *dma = &sc->fw_dma;
- int error;
-
- /* Copy firmware chunk into pre-allocated DMA-safe memory. */
- memcpy(dma->vaddr, chunk, byte_cnt);
- bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
-
- if (dst_addr >= IWM_FW_MEM_EXTENDED_START &&
- dst_addr <= IWM_FW_MEM_EXTENDED_END) {
- iwm_set_bits_prph(sc, IWM_LMPM_CHICK,
- IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
- }
+ int ret;
sc->sc_fw_chunk_done = 0;
@@ -2468,17 +2387,22 @@ iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
+
IWM_WRITE(sc, IWM_FH_SRVC_CHNL_SRAM_ADDR_REG(IWM_FH_SRVC_CHNL),
dst_addr);
+
IWM_WRITE(sc, IWM_FH_TFDIB_CTRL0_REG(IWM_FH_SRVC_CHNL),
- dma->paddr & IWM_FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
+ phy_addr & IWM_FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
+
IWM_WRITE(sc, IWM_FH_TFDIB_CTRL1_REG(IWM_FH_SRVC_CHNL),
- (iwm_get_dma_hi_addr(dma->paddr)
- << IWM_FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
+ (iwm_get_dma_hi_addr(phy_addr)
+ << IWM_FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
+
IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_BUF_STS_REG(IWM_FH_SRVC_CHNL),
1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
+
IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
@@ -2486,37 +2410,31 @@ iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
iwm_nic_unlock(sc);
- /* wait 1s for this segment to load */
- while (!sc->sc_fw_chunk_done)
- if ((error = msleep(&sc->sc_fw, &sc->sc_mtx, 0, "iwmfw", hz)) != 0)
+ /* wait up to 5s for this segment to load */
+ ret = 0;
+ while (!sc->sc_fw_chunk_done) {
+ ret = msleep(&sc->sc_fw, &sc->sc_mtx, 0, "iwmfw", hz);
+ if (ret)
break;
+ }
- if (!sc->sc_fw_chunk_done) {
+ if (ret != 0) {
device_printf(sc->sc_dev,
"fw chunk addr 0x%x len %d failed to load\n",
dst_addr, byte_cnt);
+ return ETIMEDOUT;
}
- if (dst_addr >= IWM_FW_MEM_EXTENDED_START &&
- dst_addr <= IWM_FW_MEM_EXTENDED_END && iwm_nic_lock(sc)) {
- iwm_clear_bits_prph(sc, IWM_LMPM_CHICK,
- IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
- iwm_nic_unlock(sc);
- }
-
- return error;
+ return 0;
}
-int
-iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
- int cpu, int *first_ucode_section)
+static int
+iwm_pcie_load_cpu_sections_8000(struct iwm_softc *sc,
+ const struct iwm_fw_sects *image, int cpu, int *first_ucode_section)
{
int shift_param;
- int i, error = 0, sec_num = 0x1;
+ int i, ret = 0, sec_num = 0x1;
uint32_t val, last_read_idx = 0;
- const void *data;
- uint32_t dlen;
- uint32_t offset;
if (cpu == 1) {
shift_param = 0;
@@ -2528,9 +2446,6 @@ iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
for (i = *first_ucode_section; i < IWM_UCODE_SECTION_MAX; i++) {
last_read_idx = i;
- data = fws->fw_sect[i].fws_data;
- dlen = fws->fw_sect[i].fws_len;
- offset = fws->fw_sect[i].fws_devoff;
/*
* CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between
@@ -2538,27 +2453,17 @@ iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
* PAGING_SEPARATOR_SECTION delimiter - separate between
* CPU2 non paged to CPU2 paging sec.
*/
- if (!data || offset == IWM_CPU1_CPU2_SEPARATOR_SECTION ||
- offset == IWM_PAGING_SEPARATOR_SECTION)
- break;
-
- IWM_DPRINTF(sc, IWM_DEBUG_RESET,
- "LOAD FIRMWARE chunk %d offset 0x%x len %d for cpu %d\n",
- i, offset, dlen, cpu);
-
- if (dlen > sc->sc_fwdmasegsz) {
+ if (!image->fw_sect[i].data ||
+ image->fw_sect[i].offset == IWM_CPU1_CPU2_SEPARATOR_SECTION ||
+ image->fw_sect[i].offset == IWM_PAGING_SEPARATOR_SECTION) {
IWM_DPRINTF(sc, IWM_DEBUG_RESET,
- "chunk %d too large (%d bytes)\n", i, dlen);
- error = EFBIG;
- } else {
- error = iwm_firmware_load_sect(sc, offset, data, dlen);
- }
- if (error) {
- device_printf(sc->sc_dev,
- "could not load firmware chunk %d (error %d)\n",
- i, error);
- return error;
+ "Break since Data not valid or Empty section, sec = %d\n",
+ i);
+ break;
}
+ ret = iwm_pcie_load_section(sc, i, &image->fw_sect[i]);
+ if (ret)
+ return ret;
/* Notify the ucode of the loaded section number and status */
if (iwm_nic_lock(sc)) {
@@ -2567,16 +2472,13 @@ iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, val);
sec_num = (sec_num << 1) | 0x1;
iwm_nic_unlock(sc);
-
- /*
- * The firmware won't load correctly without this delay.
- */
- DELAY(8000);
}
}
*first_ucode_section = last_read_idx;
+ iwm_enable_interrupts(sc);
+
if (iwm_nic_lock(sc)) {
if (cpu == 1)
IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, 0xFFFF);
@@ -2588,120 +2490,170 @@ iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
return 0;
}
-int
-iwm_load_firmware_8000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
+static int
+iwm_pcie_load_cpu_sections(struct iwm_softc *sc,
+ const struct iwm_fw_sects *image, int cpu, int *first_ucode_section)
{
- struct iwm_fw_sects *fws;
- int error = 0;
- int first_ucode_section;
+ int shift_param;
+ int i, ret = 0;
+ uint32_t last_read_idx = 0;
- IWM_DPRINTF(sc, IWM_DEBUG_RESET, "loading ucode type %d\n",
- ucode_type);
+ if (cpu == 1) {
+ shift_param = 0;
+ *first_ucode_section = 0;
+ } else {
+ shift_param = 16;
+ (*first_ucode_section)++;
+ }
- fws = &sc->sc_fw.fw_sects[ucode_type];
+ for (i = *first_ucode_section; i < IWM_UCODE_SECTION_MAX; i++) {
+ last_read_idx = i;
- /* configure the ucode to be ready to get the secured image */
- /* release CPU reset */
- iwm_write_prph(sc, IWM_RELEASE_CPU_RESET, IWM_RELEASE_CPU_RESET_BIT);
+ /*
+ * CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between
+ * CPU1 to CPU2.
+ * PAGING_SEPARATOR_SECTION delimiter - separate between
+ * CPU2 non paged to CPU2 paging sec.
+ */
+ if (!image->fw_sect[i].data ||
+ image->fw_sect[i].offset == IWM_CPU1_CPU2_SEPARATOR_SECTION ||
+ image->fw_sect[i].offset == IWM_PAGING_SEPARATOR_SECTION) {
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+ "Break since Data not valid or Empty section, sec = %d\n",
+ i);
+ break;
+ }
- /* load to FW the binary Secured sections of CPU1 */
- error = iwm_load_cpu_sections_8000(sc, fws, 1, &first_ucode_section);
- if (error)
- return error;
+ ret = iwm_pcie_load_section(sc, i, &image->fw_sect[i]);
+ if (ret)
+ return ret;
+ }
+
+ if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000)
+ iwm_set_bits_prph(sc,
+ IWM_CSR_UCODE_LOAD_STATUS_ADDR,
+ (IWM_LMPM_CPU_UCODE_LOADING_COMPLETED |
+ IWM_LMPM_CPU_HDRS_LOADING_COMPLETED |
+ IWM_LMPM_CPU_UCODE_LOADING_STARTED) <<
+ shift_param);
+
+ *first_ucode_section = last_read_idx;
+
+ return 0;
- /* load to FW the binary sections of CPU2 */
- return iwm_load_cpu_sections_8000(sc, fws, 2, &first_ucode_section);
}
static int
-iwm_load_firmware_7000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
+iwm_pcie_load_given_ucode(struct iwm_softc *sc,
+ const struct iwm_fw_sects *image)
{
- struct iwm_fw_sects *fws;
- int error, i;
- const void *data;
- uint32_t dlen;
- uint32_t offset;
-
- sc->sc_uc.uc_intr = 0;
-
- fws = &sc->sc_fw.fw_sects[ucode_type];
- for (i = 0; i < fws->fw_count; i++) {
- data = fws->fw_sect[i].fws_data;
- dlen = fws->fw_sect[i].fws_len;
- offset = fws->fw_sect[i].fws_devoff;
- IWM_DPRINTF(sc, IWM_DEBUG_FIRMWARE_TLV,
- "LOAD FIRMWARE type %d offset %u len %d\n",
- ucode_type, offset, dlen);
- if (dlen > sc->sc_fwdmasegsz) {
- IWM_DPRINTF(sc, IWM_DEBUG_FIRMWARE_TLV,
- "chunk %d too large (%d bytes)\n", i, dlen);
- error = EFBIG;
- } else {
- error = iwm_firmware_load_sect(sc, offset, data, dlen);
- }
- if (error) {
- device_printf(sc->sc_dev,
- "could not load firmware chunk %u of %u "
- "(error=%d)\n", i, fws->fw_count, error);
- return error;
- }
+ int ret = 0;
+ int first_ucode_section;
+
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET, "working with %s CPU\n",
+ image->is_dual_cpus ? "Dual" : "Single");
+
+ /* load to FW the binary non secured sections of CPU1 */
+ ret = iwm_pcie_load_cpu_sections(sc, image, 1, &first_ucode_section);
+ if (ret)
+ return ret;
+
+ if (image->is_dual_cpus) {
+ /* set CPU2 header address */
+ iwm_write_prph(sc,
+ IWM_LMPM_SECURE_UCODE_LOAD_CPU2_HDR_ADDR,
+ IWM_LMPM_SECURE_CPU2_HDR_MEM_SPACE);
+
+ /* load to FW the binary sections of CPU2 */
+ ret = iwm_pcie_load_cpu_sections(sc, image, 2,
+ &first_ucode_section);
+ if (ret)
+ return ret;
}
+ iwm_enable_interrupts(sc);
+
+ /* release CPU reset */
IWM_WRITE(sc, IWM_CSR_RESET, 0);
return 0;
}
-static int
-iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
+int
+iwm_pcie_load_given_ucode_8000(struct iwm_softc *sc,
+ const struct iwm_fw_sects *image)
{
- int error, w;
+ int ret = 0;
+ int first_ucode_section;
- if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000)
- error = iwm_load_firmware_8000(sc, ucode_type);
- else
- error = iwm_load_firmware_7000(sc, ucode_type);
- if (error)
- return error;
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET, "working with %s CPU\n",
+ image->is_dual_cpus ? "Dual" : "Single");
- /* wait for the firmware to load */
- for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++) {
- error = msleep(&sc->sc_uc, &sc->sc_mtx, 0, "iwmuc", hz/10);
- }
- if (error || !sc->sc_uc.uc_ok) {
- device_printf(sc->sc_dev, "could not load firmware\n");
- if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
- device_printf(sc->sc_dev, "cpu1 status: 0x%x\n",
- iwm_read_prph(sc, IWM_SB_CPU_1_STATUS));
- device_printf(sc->sc_dev, "cpu2 status: 0x%x\n",
- iwm_read_prph(sc, IWM_SB_CPU_2_STATUS));
- }
- }
+ /* configure the ucode to be ready to get the secured image */
+ /* release CPU reset */
+ iwm_write_prph(sc, IWM_RELEASE_CPU_RESET, IWM_RELEASE_CPU_RESET_BIT);
- return error;
+ /* load to FW the binary Secured sections of CPU1 */
+ ret = iwm_pcie_load_cpu_sections_8000(sc, image, 1,
+ &first_ucode_section);
+ if (ret)
+ return ret;
+
+ /* load to FW the binary sections of CPU2 */
+ return iwm_pcie_load_cpu_sections_8000(sc, image, 2,
+ &first_ucode_section);
}
-/* iwlwifi: pcie/trans.c */
-static int
-iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
+/* XXX Get rid of this definition */
+static inline void
+iwm_enable_fw_load_int(struct iwm_softc *sc)
{
- int error;
+ IWM_DPRINTF(sc, IWM_DEBUG_INTR, "Enabling FW load interrupt\n");
+ sc->sc_intmask = IWM_CSR_INT_BIT_FH_TX;
+ IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
+}
- IWM_WRITE(sc, IWM_CSR_INT, ~0);
+/* XXX Add proper rfkill support code */
+static int
+iwm_start_fw(struct iwm_softc *sc,
+ const struct iwm_fw_sects *fw)
+{
+ int ret;
- if ((error = iwm_nic_init(sc)) != 0) {
- device_printf(sc->sc_dev, "unable to init nic\n");
- return error;
+ /* This may fail if AMT took ownership of the device */
+ if (iwm_prepare_card_hw(sc)) {
+ device_printf(sc->sc_dev,
+ "%s: Exit HW not ready\n", __func__);
+ ret = EIO;
+ goto out;
}
+ IWM_WRITE(sc, IWM_CSR_INT, 0xFFFFFFFF);
+
+ iwm_disable_interrupts(sc);
+
/* make sure rfkill handshake bits are cleared */
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR,
IWM_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
/* clear (again), then enable host interrupts */
- IWM_WRITE(sc, IWM_CSR_INT, ~0);
- iwm_enable_interrupts(sc);
+ IWM_WRITE(sc, IWM_CSR_INT, 0xFFFFFFFF);
+
+ ret = iwm_nic_init(sc);
+ if (ret) {
+ device_printf(sc->sc_dev, "%s: Unable to init nic\n", __func__);
+ goto out;
+ }
+
+ /*
+ * Now, we load the firmware and don't want to be interrupted, even
+ * by the RF-Kill interrupt (hence mask all the interrupt besides the
+ * FH_TX interrupt which is needed to load the firmware). If the
+ * RF-Kill switch is toggled, we will find out after having loaded
+ * the firmware and return the proper value to the caller.
+ */
+ iwm_enable_fw_load_int(sc);
/* really make sure rfkill handshake bits are cleared */
/* maybe we should write a few times more? just to make sure */
@@ -2709,7 +2661,15 @@ iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
/* Load the given image to the HW */
- return iwm_load_firmware(sc, ucode_type);
+ if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000)
+ ret = iwm_pcie_load_given_ucode_8000(sc, fw);
+ else
+ ret = iwm_pcie_load_given_ucode(sc, fw);
+
+ /* XXX re-check RF-Kill state */
+
+out:
+ return ret;
}
static int
@@ -2728,7 +2688,7 @@ static int
iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
{
struct iwm_phy_cfg_cmd phy_cfg_cmd;
- enum iwm_ucode_type ucode_type = sc->sc_uc_current;
+ enum iwm_ucode_type ucode_type = sc->cur_ucode;
/* Set parameters */
phy_cfg_cmd.phy_cfg = htole32(iwm_mvm_get_phy_config(sc));
@@ -2744,6 +2704,83 @@ iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
}
static int
+iwm_alive_fn(struct iwm_softc *sc, struct iwm_rx_packet *pkt, void *data)
+{
+ struct iwm_mvm_alive_data *alive_data = data;
+ struct iwm_mvm_alive_resp_ver1 *palive1;
+ struct iwm_mvm_alive_resp_ver2 *palive2;
+ struct iwm_mvm_alive_resp *palive;
+
+ if (iwm_rx_packet_payload_len(pkt) == sizeof(*palive1)) {
+ palive1 = (void *)pkt->data;
+
+ sc->support_umac_log = FALSE;
+ sc->error_event_table =
+ le32toh(palive1->error_event_table_ptr);
+ sc->log_event_table =
+ le32toh(palive1->log_event_table_ptr);
+ alive_data->scd_base_addr = le32toh(palive1->scd_base_ptr);
+
+ alive_data->valid = le16toh(palive1->status) ==
+ IWM_ALIVE_STATUS_OK;
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+ "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
+ le16toh(palive1->status), palive1->ver_type,
+ palive1->ver_subtype, palive1->flags);
+ } else if (iwm_rx_packet_payload_len(pkt) == sizeof(*palive2)) {
+ palive2 = (void *)pkt->data;
+ sc->error_event_table =
+ le32toh(palive2->error_event_table_ptr);
+ sc->log_event_table =
+ le32toh(palive2->log_event_table_ptr);
+ alive_data->scd_base_addr = le32toh(palive2->scd_base_ptr);
+ sc->umac_error_event_table =
+ le32toh(palive2->error_info_addr);
+
+ alive_data->valid = le16toh(palive2->status) ==
+ IWM_ALIVE_STATUS_OK;
+ if (sc->umac_error_event_table)
+ sc->support_umac_log = TRUE;
+
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+ "Alive VER2 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
+ le16toh(palive2->status), palive2->ver_type,
+ palive2->ver_subtype, palive2->flags);
+
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+ "UMAC version: Major - 0x%x, Minor - 0x%x\n",
+ palive2->umac_major, palive2->umac_minor);
+ } else if (iwm_rx_packet_payload_len(pkt) == sizeof(*palive)) {
+ palive = (void *)pkt->data;
+
+ sc->error_event_table =
+ le32toh(palive->error_event_table_ptr);
+ sc->log_event_table =
+ le32toh(palive->log_event_table_ptr);
+ alive_data->scd_base_addr = le32toh(palive->scd_base_ptr);
+ sc->umac_error_event_table =
+ le32toh(palive->error_info_addr);
+
+ alive_data->valid = le16toh(palive->status) ==
+ IWM_ALIVE_STATUS_OK;
+ if (sc->umac_error_event_table)
+ sc->support_umac_log = TRUE;
+
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+ "Alive VER3 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
+ le16toh(palive->status), palive->ver_type,
+ palive->ver_subtype, palive->flags);
+
+ IWM_DPRINTF(sc, IWM_DEBUG_RESET,
+ "UMAC version: Major - 0x%x, Minor - 0x%x\n",
+ le32toh(palive->umac_major),
+ le32toh(palive->umac_minor));
+ }
+
+ return TRUE;
+}
+
+static int
iwm_wait_phy_db_entry(struct iwm_softc *sc,
struct iwm_rx_packet *pkt, void *data)
{
@@ -2769,27 +2806,76 @@ static int
iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
enum iwm_ucode_type ucode_type)
{
- enum iwm_ucode_type old_type = sc->sc_uc_current;
+ struct iwm_notification_wait alive_wait;
+ struct iwm_mvm_alive_data alive_data;
+ const struct iwm_fw_sects *fw;
+ enum iwm_ucode_type old_type = sc->cur_ucode;
int error;
+ static const uint16_t alive_cmd[] = { IWM_MVM_ALIVE };
if ((error = iwm_read_firmware(sc, ucode_type)) != 0) {
device_printf(sc->sc_dev, "iwm_read_firmware: failed %d\n",
error);
return error;
}
+ fw = &sc->sc_fw.fw_sects[ucode_type];
+ sc->cur_ucode = ucode_type;
+ sc->ucode_loaded = FALSE;
+
+ memset(&alive_data, 0, sizeof(alive_data));
+ iwm_init_notification_wait(sc->sc_notif_wait, &alive_wait,
+ alive_cmd, nitems(alive_cmd),
+ iwm_alive_fn, &alive_data);
- sc->sc_uc_current = ucode_type;
- error = iwm_start_fw(sc, ucode_type);
+ error = iwm_start_fw(sc, fw);
if (error) {
device_printf(sc->sc_dev, "iwm_start_fw: failed %d\n", error);
- sc->sc_uc_current = old_type;
+ sc->cur_ucode = old_type;
+ iwm_remove_notification(sc->sc_notif_wait, &alive_wait);
return error;
}
- error = iwm_post_alive(sc);
+ /*
+ * Some things may run in the background now, but we
+ * just wait for the ALIVE notification here.
+ */
+ IWM_UNLOCK(sc);
+ error = iwm_wait_notification(sc->sc_notif_wait, &alive_wait,
+ IWM_MVM_UCODE_ALIVE_TIMEOUT);
+ IWM_LOCK(sc);
if (error) {
- device_printf(sc->sc_dev, "iwm_fw_alive: failed %d\n", error);
+ if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
+ device_printf(sc->sc_dev,
+ "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
+ iwm_read_prph(sc, IWM_SB_CPU_1_STATUS),
+ iwm_read_prph(sc, IWM_SB_CPU_2_STATUS));
+ }
+ sc->cur_ucode = old_type;
+ return error;
+ }
+
+ if (!alive_data.valid) {
+ device_printf(sc->sc_dev, "%s: Loaded ucode is not valid\n",
+ __func__);
+ sc->cur_ucode = old_type;
+ return EIO;
}
+
+ iwm_trans_pcie_fw_alive(sc, alive_data.scd_base_addr);
+
+ /*
+ * configure and operate fw paging mechanism.
+ * driver configures the paging flow only once, CPU2 paging image
+ * included in the IWM_UCODE_INIT image.
+ */
+ if (fw->paging_mem_size) {
+ /* XXX implement FW paging */
+ device_printf(sc->sc_dev,
+ "%s: XXX FW paging not implemented yet\n", __func__);
+ }
+
+ if (!error)
+ sc->ucode_loaded = TRUE;
return error;
}
@@ -3295,11 +3381,6 @@ iwm_mvm_rx_tx_cmd(struct iwm_softc *sc,
if (--ring->queued < IWM_TX_RING_LOMARK) {
sc->qfullmsk &= ~(1 << ring->qid);
if (sc->qfullmsk == 0) {
- /*
- * Well, we're in interrupt context, but then again
- * I guess net80211 does all sorts of stunts in
- * interrupt context, so maybe this is no biggie.
- */
iwm_start(sc);
}
}
@@ -5139,7 +5220,7 @@ iwm_nic_umac_error(struct iwm_softc *sc)
struct iwm_umac_error_event_table table;
uint32_t base;
- base = sc->sc_uc.uc_umac_error_event_table;
+ base = sc->umac_error_event_table;
if (base < 0x800000) {
device_printf(sc->sc_dev, "Invalid error log pointer 0x%08x\n",
@@ -5194,7 +5275,7 @@ iwm_nic_error(struct iwm_softc *sc)
uint32_t base;
device_printf(sc->sc_dev, "dumping device error log\n");
- base = sc->sc_uc.uc_error_event_table;
+ base = sc->error_event_table;
if (base < 0x800000) {
device_printf(sc->sc_dev,
"Invalid error log pointer 0x%08x\n", base);
@@ -5256,7 +5337,7 @@ iwm_nic_error(struct iwm_softc *sc)
device_printf(sc->sc_dev, "%08X | timestamp\n", table.u_timestamp);
device_printf(sc->sc_dev, "%08X | flow_handler\n", table.flow_handler);
- if (sc->sc_uc.uc_umac_error_event_table)
+ if (sc->umac_error_event_table)
iwm_nic_umac_error(sc);
}
#endif
@@ -5366,57 +5447,8 @@ iwm_notif_intr(struct iwm_softc *sc)
case IWM_MFUART_LOAD_NOTIFICATION:
break;
- case IWM_MVM_ALIVE: {
- struct iwm_mvm_alive_resp_v1 *resp1;
- struct iwm_mvm_alive_resp_v2 *resp2;
- struct iwm_mvm_alive_resp_v3 *resp3;
-
- if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp1)) {
- resp1 = (void *)pkt->data;
- sc->sc_uc.uc_error_event_table
- = le32toh(resp1->error_event_table_ptr);
- sc->sc_uc.uc_log_event_table
- = le32toh(resp1->log_event_table_ptr);
- sc->sched_base = le32toh(resp1->scd_base_ptr);
- if (resp1->status == IWM_ALIVE_STATUS_OK)
- sc->sc_uc.uc_ok = 1;
- else
- sc->sc_uc.uc_ok = 0;
- }
-
- if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp2)) {
- resp2 = (void *)pkt->data;
- sc->sc_uc.uc_error_event_table
- = le32toh(resp2->error_event_table_ptr);
- sc->sc_uc.uc_log_event_table
- = le32toh(resp2->log_event_table_ptr);
- sc->sched_base = le32toh(resp2->scd_base_ptr);
- sc->sc_uc.uc_umac_error_event_table
- = le32toh(resp2->error_info_addr);
- if (resp2->status == IWM_ALIVE_STATUS_OK)
- sc->sc_uc.uc_ok = 1;
- else
- sc->sc_uc.uc_ok = 0;
- }
-
- if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp3)) {
- resp3 = (void *)pkt->data;
- sc->sc_uc.uc_error_event_table
- = le32toh(resp3->error_event_table_ptr);
- sc->sc_uc.uc_log_event_table
- = le32toh(resp3->log_event_table_ptr);
- sc->sched_base = le32toh(resp3->scd_base_ptr);
- sc->sc_uc.uc_umac_error_event_table
- = le32toh(resp3->error_info_addr);
- if (resp3->status == IWM_ALIVE_STATUS_OK)
- sc->sc_uc.uc_ok = 1;
- else
- sc->sc_uc.uc_ok = 0;
- }
-
- sc->sc_uc.uc_intr = 1;
- wakeup(&sc->sc_uc);
- break; }
+ case IWM_MVM_ALIVE:
+ break;
case IWM_CALIB_RES_NOTIF_PHY_DB:
break;
@@ -5668,8 +5700,8 @@ iwm_intr(void *arg)
IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
- /* ignored */
- handled |= (r1 & (IWM_CSR_INT_BIT_ALIVE /*| IWM_CSR_INT_BIT_SCD*/));
+ /* Safely ignore these bits for debug checks below */
+ r1 &= ~(IWM_CSR_INT_BIT_ALIVE | IWM_CSR_INT_BIT_SCD);
if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
int i;
@@ -5788,19 +5820,19 @@ iwm_intr(void *arg)
#define PCI_PRODUCT_INTEL_WL_8260_2 0x24f4
static const struct iwm_devices {
- uint16_t device;
- const char *name;
+ uint16_t device;
+ const struct iwm_cfg *cfg;
} iwm_devices[] = {
- { PCI_PRODUCT_INTEL_WL_3160_1, "Intel Dual Band Wireless AC 3160" },
- { PCI_PRODUCT_INTEL_WL_3160_2, "Intel Dual Band Wireless AC 3160" },
- { PCI_PRODUCT_INTEL_WL_3165_1, "Intel Dual Band Wireless AC 3165" },
- { PCI_PRODUCT_INTEL_WL_3165_2, "Intel Dual Band Wireless AC 3165" },
- { PCI_PRODUCT_INTEL_WL_7260_1, "Intel Dual Band Wireless AC 7260" },
- { PCI_PRODUCT_INTEL_WL_7260_2, "Intel Dual Band Wireless AC 7260" },
- { PCI_PRODUCT_INTEL_WL_7265_1, "Intel Dual Band Wireless AC 7265" },
- { PCI_PRODUCT_INTEL_WL_7265_2, "Intel Dual Band Wireless AC 7265" },
- { PCI_PRODUCT_INTEL_WL_8260_1, "Intel Dual Band Wireless AC 8260" },
- { PCI_PRODUCT_INTEL_WL_8260_2, "Intel Dual Band Wireless AC 8260" },
+ { PCI_PRODUCT_INTEL_WL_3160_1, &iwm3160_cfg },
+ { PCI_PRODUCT_INTEL_WL_3160_2, &iwm3160_cfg },
+ { PCI_PRODUCT_INTEL_WL_3165_1, &iwm3165_cfg },
+ { PCI_PRODUCT_INTEL_WL_3165_2, &iwm3165_cfg },
+ { PCI_PRODUCT_INTEL_WL_7260_1, &iwm7260_cfg },
+ { PCI_PRODUCT_INTEL_WL_7260_2, &iwm7260_cfg },
+ { PCI_PRODUCT_INTEL_WL_7265_1, &iwm7265_cfg },
+ { PCI_PRODUCT_INTEL_WL_7265_2, &iwm7265_cfg },
+ { PCI_PRODUCT_INTEL_WL_8260_1, &iwm8260_cfg },
+ { PCI_PRODUCT_INTEL_WL_8260_2, &iwm8260_cfg },
};
static int
@@ -5811,7 +5843,7 @@ iwm_probe(device_t dev)
for (i = 0; i < nitems(iwm_devices); i++) {
if (pci_get_vendor(dev) == PCI_VENDOR_INTEL &&
pci_get_device(dev) == iwm_devices[i].device) {
- device_set_desc(dev, iwm_devices[i].name);
+ device_set_desc(dev, iwm_devices[i].cfg->name);
return (BUS_PROBE_DEFAULT);
}
}
@@ -5823,41 +5855,25 @@ static int
iwm_dev_check(device_t dev)
{
struct iwm_softc *sc;
+ uint16_t devid;
+ int i;
sc = device_get_softc(dev);
- switch (pci_get_device(dev)) {
- case PCI_PRODUCT_INTEL_WL_3160_1:
- case PCI_PRODUCT_INTEL_WL_3160_2:
- sc->cfg = &iwm3160_cfg;
- sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
- return (0);
- case PCI_PRODUCT_INTEL_WL_3165_1:
- case PCI_PRODUCT_INTEL_WL_3165_2:
- sc->cfg = &iwm3165_cfg;
- sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
- return (0);
- case PCI_PRODUCT_INTEL_WL_7260_1:
- case PCI_PRODUCT_INTEL_WL_7260_2:
- sc->cfg = &iwm7260_cfg;
- sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
- return (0);
- case PCI_PRODUCT_INTEL_WL_7265_1:
- case PCI_PRODUCT_INTEL_WL_7265_2:
- sc->cfg = &iwm7265_cfg;
- sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
- return (0);
- case PCI_PRODUCT_INTEL_WL_8260_1:
- case PCI_PRODUCT_INTEL_WL_8260_2:
- sc->cfg = &iwm8260_cfg;
- sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
- return (0);
- default:
- device_printf(dev, "unknown adapter type\n");
- return ENXIO;
+ devid = pci_get_device(dev);
+ for (i = 0; i < nitems(iwm_devices); i++) {
+ if (iwm_devices[i].device == devid) {
+ sc->cfg = iwm_devices[i].cfg;
+ return (0);
+ }
}
+ device_printf(dev, "unknown adapter type\n");
+ return ENXIO;
}
+/* PCI registers */
+#define PCI_CFG_RETRY_TIMEOUT 0x041
+
static int
iwm_pci_attach(device_t dev)
{
@@ -5867,9 +5883,9 @@ iwm_pci_attach(device_t dev)
sc = device_get_softc(dev);
- /* Clear device-specific "PCI retry timeout" register (41h). */
- reg = pci_read_config(dev, 0x40, sizeof(reg));
- pci_write_config(dev, 0x40, reg & ~0xff00, sizeof(reg));
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state */
+ pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
/* Enable bus-mastering and hardware bug workaround. */
pci_enable_busmaster(dev);
@@ -6377,11 +6393,12 @@ iwm_resume(device_t dev)
{
struct iwm_softc *sc = device_get_softc(dev);
int do_reinit = 0;
- uint16_t reg;
- /* Clear device-specific "PCI retry timeout" register (41h). */
- reg = pci_read_config(dev, 0x40, sizeof(reg));
- pci_write_config(dev, 0x40, reg & ~0xff00, sizeof(reg));
+ /*
+ * We disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state.
+ */
+ pci_write_config(dev, PCI_CFG_RETRY_TIMEOUT, 0x00, 1);
iwm_init_task(device_get_softc(dev));
IWM_LOCK(sc);
diff --git a/sys/dev/iwm/if_iwm_7000.c b/sys/dev/iwm/if_iwm_7000.c
new file mode 100644
index 000000000000..3bcb1724e72b
--- /dev/null
+++ b/sys/dev/iwm/if_iwm_7000.c
@@ -0,0 +1,126 @@
+/*-
+ * Based on BSD-licensed source modules in the Linux iwlwifi driver,
+ * which were used as the reference documentation for this implementation.
+ *
+ ******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2015 Intel Deutschland GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <linuxwifi@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2015 Intel Deutschland GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include "if_iwm_config.h"
+
+#define IWM7260_FW "iwm7260fw"
+#define IWM3160_FW "iwm3160fw"
+#define IWM7265_FW "iwm7265fw"
+#define IWM7265D_FW "iwm7265Dfw"
+
+#define IWM_NVM_HW_SECTION_NUM_FAMILY_7000 0
+
+#define IWM_DEVICE_7000_COMMON \
+ .device_family = IWM_DEVICE_FAMILY_7000, \
+ .eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000, \
+ .nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000, \
+ .apmg_wake_up_wa = 1
+
+const struct iwm_cfg iwm7260_cfg = {
+ .name = "Intel(R) Dual Band Wireless AC 7260",
+ .fw_name = IWM7260_FW,
+ IWM_DEVICE_7000_COMMON,
+ .host_interrupt_operation_mode = 1,
+};
+
+const struct iwm_cfg iwm3160_cfg = {
+ .name = "Intel(R) Dual Band Wireless AC 3160",
+ .fw_name = IWM3160_FW,
+ IWM_DEVICE_7000_COMMON,
+ .host_interrupt_operation_mode = 1,
+};
+
+const struct iwm_cfg iwm3165_cfg = {
+ .name = "Intel(R) Dual Band Wireless AC 3165",
+ .fw_name = IWM7265D_FW,
+ IWM_DEVICE_7000_COMMON,
+ .host_interrupt_operation_mode = 0,
+};
+
+const struct iwm_cfg iwm7265_cfg = {
+ .name = "Intel(R) Dual Band Wireless AC 7265",
+ .fw_name = IWM7265_FW,
+ IWM_DEVICE_7000_COMMON,
+ .host_interrupt_operation_mode = 0,
+};
+
+const struct iwm_cfg iwm7265d_cfg = {
+ .name = "Intel(R) Dual Band Wireless AC 7265",
+ .fw_name = IWM7265D_FW,
+ IWM_DEVICE_7000_COMMON,
+ .host_interrupt_operation_mode = 0,
+};
+
diff --git a/sys/dev/iwm/if_iwm_8000.c b/sys/dev/iwm/if_iwm_8000.c
new file mode 100644
index 000000000000..e567e73939a7
--- /dev/null
+++ b/sys/dev/iwm/if_iwm_8000.c
@@ -0,0 +1,92 @@
+/*-
+ * Based on BSD-licensed source modules in the Linux iwlwifi driver,
+ * which were used as the reference documentation for this implementation.
+ *
+ ******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 Intel Deutschland GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <linuxwifi@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include "if_iwm_config.h"
+
+#define IWM8000_FW "iwm8000Cfw"
+
+#define IWM_NVM_HW_SECTION_NUM_FAMILY_8000 10
+
+#define IWM_DEVICE_8000_COMMON \
+ .device_family = IWM_DEVICE_FAMILY_8000, \
+ .eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000, \
+ .nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_8000
+
+const struct iwm_cfg iwm8260_cfg = {
+ .name = "Intel(R) Dual Band Wireless AC 8260",
+ .fw_name = IWM8000_FW,
+ IWM_DEVICE_8000_COMMON,
+ .host_interrupt_operation_mode = 0,
+};
diff --git a/sys/dev/iwm/if_iwm_config.h b/sys/dev/iwm/if_iwm_config.h
new file mode 100644
index 000000000000..74f34ba62f02
--- /dev/null
+++ b/sys/dev/iwm/if_iwm_config.h
@@ -0,0 +1,135 @@
+/*-
+ * Based on BSD-licensed source modules in the Linux iwlwifi driver,
+ * which were used as the reference documentation for this implementation.
+ *
+ ******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2016 Intel Deutschland GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <linuxwifi@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2016 Intel Deutschland GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+/*
+ * $FreeBSD$
+ */
+
+#ifndef __IWM_CONFIG_H__
+#define __IWM_CONFIG_H__
+
+enum iwm_device_family {
+ IWM_DEVICE_FAMILY_UNDEFINED,
+ IWM_DEVICE_FAMILY_7000,
+ IWM_DEVICE_FAMILY_8000,
+};
+
+/* Antenna presence definitions */
+#define IWM_ANT_NONE 0x0
+#define IWM_ANT_A (1 << 0)
+#define IWM_ANT_B (1 << 1)
+#define IWM_ANT_C (1 << 2)
+#define IWM_ANT_AB (IWM_ANT_A | IWM_ANT_B)
+#define IWM_ANT_AC (IWM_ANT_A | IWM_ANT_C)
+#define IWM_ANT_BC (IWM_ANT_B | IWM_ANT_C)
+#define IWM_ANT_ABC (IWM_ANT_A | IWM_ANT_B | IWM_ANT_C)
+
+static inline uint8_t num_of_ant(uint8_t mask)
+{
+ return !!((mask) & IWM_ANT_A) +
+ !!((mask) & IWM_ANT_B) +
+ !!((mask) & IWM_ANT_C);
+}
+
+/* lower blocks contain EEPROM image and calibration data */
+#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(uint16_t)) /* 16 KB */
+#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(uint16_t)) /* 32 KB */
+#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_9000 IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000
+
+/**
+ * struct iwm_cfg
+ * @name: Official name of the device
+ * @fw_name: Firmware filename.
+ * @host_interrupt_operation_mode: device needs host interrupt operation
+ * mode set
+ * @nvm_hw_section_num: the ID of the HW NVM section
+ * @apmg_wake_up_wa: should the MAC access REQ be asserted when a command
+ * is in flight. This is due to a HW bug in 7260, 3160 and 7265.
+ */
+struct iwm_cfg {
+ const char *name;
+ const char *fw_name;
+ uint16_t eeprom_size;
+ enum iwm_device_family device_family;
+ int host_interrupt_operation_mode;
+ uint8_t nvm_hw_section_num;
+ int apmg_wake_up_wa;
+};
+
+/*
+ * This list declares the config structures for all devices.
+ */
+extern const struct iwm_cfg iwm7260_cfg;
+extern const struct iwm_cfg iwm3160_cfg;
+extern const struct iwm_cfg iwm3165_cfg;
+extern const struct iwm_cfg iwm7265_cfg;
+extern const struct iwm_cfg iwm7265d_cfg;
+extern const struct iwm_cfg iwm8260_cfg;
+
+#endif /* __IWM_CONFIG_H__ */
diff --git a/sys/dev/iwm/if_iwm_pcie_trans.c b/sys/dev/iwm/if_iwm_pcie_trans.c
index 62bf1edabf59..c9dae6680e56 100644
--- a/sys/dev/iwm/if_iwm_pcie_trans.c
+++ b/sys/dev/iwm/if_iwm_pcie_trans.c
@@ -152,6 +152,7 @@ __FBSDID("$FreeBSD$");
#include <dev/iwm/if_iwmreg.h>
#include <dev/iwm/if_iwmvar.h>
+#include <dev/iwm/if_iwm_config.h>
#include <dev/iwm/if_iwm_debug.h>
#include <dev/iwm/if_iwm_pcie_trans.h>
diff --git a/sys/dev/iwm/if_iwm_util.c b/sys/dev/iwm/if_iwm_util.c
index c3e1d0618f4b..206021a77fc2 100644
--- a/sys/dev/iwm/if_iwm_util.c
+++ b/sys/dev/iwm/if_iwm_util.c
@@ -421,3 +421,68 @@ iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
sc->sc_wantresp = -1;
wakeup(&sc->sc_wantresp);
}
+
+static void
+iwm_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+ if (error != 0)
+ return;
+ KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
+ *(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+int
+iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
+ bus_size_t size, bus_size_t alignment)
+{
+ int error;
+
+ dma->tag = NULL;
+ dma->map = NULL;
+ dma->size = size;
+ dma->vaddr = NULL;
+
+ error = bus_dma_tag_create(tag, alignment,
+ 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
+ 1, size, 0, NULL, NULL, &dma->tag);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
+ BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size,
+ iwm_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
+ dma->vaddr = NULL;
+ goto fail;
+ }
+
+ bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
+
+ return 0;
+
+fail:
+ iwm_dma_contig_free(dma);
+
+ return error;
+}
+
+void
+iwm_dma_contig_free(struct iwm_dma_info *dma)
+{
+ if (dma->vaddr != NULL) {
+ bus_dmamap_sync(dma->tag, dma->map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(dma->tag, dma->map);
+ bus_dmamem_free(dma->tag, dma->vaddr, dma->map);
+ dma->vaddr = NULL;
+ }
+ if (dma->tag != NULL) {
+ bus_dma_tag_destroy(dma->tag);
+ dma->tag = NULL;
+ }
+}
diff --git a/sys/dev/iwm/if_iwm_util.h b/sys/dev/iwm/if_iwm_util.h
index 4c62ec9df61e..4544466ae79b 100644
--- a/sys/dev/iwm/if_iwm_util.h
+++ b/sys/dev/iwm/if_iwm_util.h
@@ -116,6 +116,10 @@ extern int iwm_mvm_send_cmd_pdu_status(struct iwm_softc *sc, uint8_t id,
uint16_t len, const void *data, uint32_t *status);
extern void iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd);
+extern int iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
+ bus_size_t size, bus_size_t alignment);
+extern void iwm_dma_contig_free(struct iwm_dma_info *);
+
static inline uint8_t
iwm_mvm_get_valid_tx_ant(struct iwm_softc *sc)
{
diff --git a/sys/dev/iwm/if_iwmreg.h b/sys/dev/iwm/if_iwmreg.h
index df9b6d238293..9e6abf50936e 100644
--- a/sys/dev/iwm/if_iwmreg.h
+++ b/sys/dev/iwm/if_iwmreg.h
@@ -2141,7 +2141,7 @@ enum {
#define IWM_ALIVE_FLG_RFKILL (1 << 0)
-struct iwm_mvm_alive_resp_v1 {
+struct iwm_mvm_alive_resp_ver1 {
uint16_t status;
uint16_t flags;
uint8_t ucode_minor;
@@ -2163,7 +2163,7 @@ struct iwm_mvm_alive_resp_v1 {
uint32_t scd_base_ptr; /* SRAM address for SCD */
} __packed; /* IWM_ALIVE_RES_API_S_VER_1 */
-struct iwm_mvm_alive_resp_v2 {
+struct iwm_mvm_alive_resp_ver2 {
uint16_t status;
uint16_t flags;
uint8_t ucode_minor;
@@ -2185,14 +2185,14 @@ struct iwm_mvm_alive_resp_v2 {
uint32_t scd_base_ptr; /* SRAM address for SCD */
uint32_t st_fwrd_addr; /* pointer to Store and forward */
uint32_t st_fwrd_size;
- uint8_t umac_minor; /* UMAC version: minor */
- uint8_t umac_major; /* UMAC version: major */
- uint16_t umac_id; /* UMAC version: id */
- uint32_t error_info_addr; /* SRAM address for UMAC error log */
+ uint8_t umac_minor; /* UMAC version: minor */
+ uint8_t umac_major; /* UMAC version: major */
+ uint16_t umac_id; /* UMAC version: id */
+ uint32_t error_info_addr; /* SRAM address for UMAC error log */
uint32_t dbg_print_buff_addr;
} __packed; /* ALIVE_RES_API_S_VER_2 */
-struct iwm_mvm_alive_resp_v3 {
+struct iwm_mvm_alive_resp {
uint16_t status;
uint16_t flags;
uint32_t ucode_minor;
@@ -2212,7 +2212,7 @@ struct iwm_mvm_alive_resp_v3 {
uint32_t st_fwrd_size;
uint32_t umac_minor; /* UMAC version: minor */
uint32_t umac_major; /* UMAC version: major */
- uint32_t error_info_addr; /* SRAM address for UMAC error log */
+ uint32_t error_info_addr; /* SRAM address for UMAC error log */
uint32_t dbg_print_buff_addr;
} __packed; /* ALIVE_RES_API_S_VER_3 */
diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h
index 141101ddfd40..a3fe896caaea 100644
--- a/sys/dev/iwm/if_iwmvar.h
+++ b/sys/dev/iwm/if_iwmvar.h
@@ -138,10 +138,6 @@ struct iwm_tx_radiotap_header {
#define IWM_UCODE_SECTION_MAX 16
-#define IWM_FWDMASEGSZ (192*1024)
-#define IWM_FWDMASEGSZ_8000 (320*1024)
-/* sanity check value */
-#define IWM_FWMAXSIZE (2*1024*1024)
/*
* fw_status is used to determine if we've already parsed the firmware file
@@ -170,17 +166,21 @@ enum iwm_ucode_type {
IWM_UCODE_TYPE_MAX
};
+/* one for each uCode image (inst/data, init/runtime/wowlan) */
+struct iwm_fw_desc {
+ const void *data; /* vmalloc'ed data */
+ uint32_t len; /* size in bytes */
+ uint32_t offset; /* offset in the device */
+};
+
struct iwm_fw_info {
const struct firmware *fw_fp;
int fw_status;
struct iwm_fw_sects {
- struct iwm_fw_onesect {
- const void *fws_data;
- uint32_t fws_len;
- uint32_t fws_devoff;
- } fw_sect[IWM_UCODE_SECTION_MAX];
+ struct iwm_fw_desc fw_sect[IWM_UCODE_SECTION_MAX];
int fw_count;
+ int is_dual_cpus;
uint32_t paging_mem_size;
} fw_sects[IWM_UCODE_TYPE_MAX];
@@ -295,15 +295,6 @@ struct iwm_rx_ring {
int cur;
};
-struct iwm_ucode_status {
- uint32_t uc_error_event_table;
- uint32_t uc_umac_error_event_table;
- uint32_t uc_log_event_table;
-
- int uc_ok;
- int uc_intr;
-};
-
#define IWM_CMD_RESP_MAX PAGE_SIZE
#define IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
@@ -377,29 +368,7 @@ struct iwm_node {
#define IWM_ICT_COUNT (IWM_ICT_SIZE / sizeof (uint32_t))
#define IWM_ICT_PADDR_SHIFT 12
-enum iwm_device_family {
- IWM_DEVICE_FAMILY_UNDEFINED,
- IWM_DEVICE_FAMILY_7000,
- IWM_DEVICE_FAMILY_8000,
-};
-
-/**
- * struct iwm_cfg
- * @fw_name: Firmware filename.
- * @host_interrupt_operation_mode: device needs host interrupt operation
- * mode set
- * @nvm_hw_section_num: the ID of the HW NVM section
- * @apmg_wake_up_wa: should the MAC access REQ be asserted when a command
- * is in flight. This is due to a HW bug in 7260, 3160 and 7265.
- */
-struct iwm_cfg {
- const char *fw_name;
- uint16_t eeprom_size;
- enum iwm_device_family device_family;
- int host_interrupt_operation_mode;
- uint8_t nvm_hw_section_num;
- int apmg_wake_up_wa;
-};
+struct iwm_cfg;
struct iwm_softc {
device_t sc_dev;
@@ -436,7 +405,7 @@ struct iwm_softc {
/* TX scheduler rings. */
struct iwm_dma_info sched_dma;
- uint32_t sched_base;
+ uint32_t scd_base_addr;
/* TX/RX rings. */
struct iwm_tx_ring txq[IWM_MVM_MAX_QUEUES];
@@ -457,8 +426,8 @@ struct iwm_softc {
int sc_fw_chunk_done;
- struct iwm_ucode_status sc_uc;
- enum iwm_ucode_type sc_uc_current;
+ enum iwm_ucode_type cur_ucode;
+ int ucode_loaded;
char sc_fwver[32];
int sc_capaflags;
@@ -481,7 +450,6 @@ struct iwm_softc {
*/
int sc_generation;
- bus_size_t sc_fwdmasegsz;
struct iwm_fw_info sc_fw;
struct iwm_tlv_calib_ctrl sc_default_calib[IWM_UCODE_TYPE_MAX];
@@ -526,6 +494,12 @@ struct iwm_softc {
struct iwm_notif_wait_data *sc_notif_wait;
int cmd_hold_nic_awake;
+
+ /* Firmware status */
+ uint32_t error_event_table;
+ uint32_t log_event_table;
+ uint32_t umac_error_event_table;
+ int support_umac_log;
};
#define IWM_LOCK_INIT(_sc) \
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index a40e6223d5da..56d71e8029e9 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -4402,6 +4402,13 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tid = 0;
}
ac = M_WME_GETAC(m);
+
+ /*
+ * XXX TODO: Group addressed frames aren't aggregated and must
+ * go to the normal non-aggregation queue, and have a NONQOS TID
+ * assigned from net80211.
+ */
+
if (m->m_flags & M_AMPDU_MPDU) {
uint16_t seqno;
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac];
diff --git a/sys/dev/jedec_ts/jedec_ts.c b/sys/dev/jedec_ts/jedec_ts.c
index b65ef789173f..d1e9596c8769 100644
--- a/sys/dev/jedec_ts/jedec_ts.c
+++ b/sys/dev/jedec_ts/jedec_ts.c
@@ -104,7 +104,7 @@ ts_attach(device_t dev)
uint8_t addr;
addr = smbus_get_addr(dev);
- if ((addr & 0x30) != 0x30) {
+ if ((addr & 0xf0) != 0x30) {
/* Up to 8 slave devices starting at 0x30. */
return (ENXIO);
}
diff --git a/sys/dev/le/am7990.c b/sys/dev/le/am7990.c
index a21be28a4c13..32c2e1e65e80 100644
--- a/sys/dev/le/am7990.c
+++ b/sys/dev/le/am7990.c
@@ -519,7 +519,7 @@ am7990_start_locked(struct lance_softc *sc)
}
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == 0)
+ if (m == NULL)
break;
/*
diff --git a/sys/dev/le/am79900.c b/sys/dev/le/am79900.c
index 74f9e5c802f3..cb6a31f30b5f 100644
--- a/sys/dev/le/am79900.c
+++ b/sys/dev/le/am79900.c
@@ -557,7 +557,7 @@ am79900_start_locked(struct lance_softc *sc)
}
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == 0)
+ if (m == NULL)
break;
/*
diff --git a/sys/dev/le/lance.c b/sys/dev/le/lance.c
index f8a333b9fd5c..2eee7af1b8ba 100644
--- a/sys/dev/le/lance.c
+++ b/sys/dev/le/lance.c
@@ -418,7 +418,7 @@ lance_get(struct lance_softc *sc, int boff, int totlen)
totlen -= len;
if (totlen > 0) {
MGET(newm, M_NOWAIT, MT_DATA);
- if (newm == 0)
+ if (newm == NULL)
goto bad;
len = MLEN;
m = m->m_next = newm;
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index c9c73bfafda4..2fd60544914b 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -153,7 +153,7 @@ static g_access_t g_md_access;
static void g_md_dumpconf(struct sbuf *sb, const char *indent,
struct g_geom *gp, struct g_consumer *cp __unused, struct g_provider *pp);
-static struct cdev *status_dev = 0;
+static struct cdev *status_dev = NULL;
static struct sx md_sx;
static struct unrhdr *md_uh;
diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c
index 85c2247fd3a8..9b48d445acbc 100644
--- a/sys/dev/mvs/mvs.c
+++ b/sys/dev/mvs/mvs.c
@@ -2288,10 +2288,6 @@ mvsaction(struct cam_sim *sim, union ccb *ccb)
}
mvs_begin_transaction(dev, ccb);
return;
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c
index 1027eb0524db..79172aaf7bd7 100644
--- a/sys/dev/mwl/if_mwl.c
+++ b/sys/dev/mwl/if_mwl.c
@@ -2434,13 +2434,13 @@ mwl_node_getmimoinfo(const struct ieee80211_node *ni,
if (mn->mn_ai.rssi_c > rssi_max)
rssi_max = mn->mn_ai.rssi_c;
- CVT(mi->rssi[0], mn->mn_ai.rssi_a);
- CVT(mi->rssi[1], mn->mn_ai.rssi_b);
- CVT(mi->rssi[2], mn->mn_ai.rssi_c);
+ CVT(mi->ch[0].rssi[0], mn->mn_ai.rssi_a);
+ CVT(mi->ch[1].rssi[0], mn->mn_ai.rssi_b);
+ CVT(mi->ch[2].rssi[0], mn->mn_ai.rssi_c);
- mi->noise[0] = mn->mn_ai.nf_a;
- mi->noise[1] = mn->mn_ai.nf_b;
- mi->noise[2] = mn->mn_ai.nf_c;
+ mi->ch[0].noise[0] = mn->mn_ai.nf_a;
+ mi->ch[1].noise[0] = mn->mn_ai.nf_b;
+ mi->ch[2].noise[0] = mn->mn_ai.nf_c;
#undef CVT
}
diff --git a/sys/dev/nand/nfc_rb.c b/sys/dev/nand/nfc_rb.c
index 38b28445add1..1102b3abb9c4 100644
--- a/sys/dev/nand/nfc_rb.c
+++ b/sys/dev/nand/nfc_rb.c
@@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
+#include <sys/slicer.h>
+
+#include <geom/geom_disk.h>
#include <machine/bus.h>
@@ -106,6 +109,40 @@ static const struct nand_ecc_data rb_ecc = {
};
#endif
+/* Slicer operates on the NAND controller, so we have to find the chip. */
+static int
+rb_nand_slicer(device_t dev, const char *provider __unused,
+ struct flash_slice *slices, int *nslices)
+{
+ struct nand_chip *chip;
+ device_t *children;
+ int n;
+
+ if (device_get_children(dev, &children, &n) != 0) {
+ panic("Slicer called on controller with no child!");
+ }
+ dev = children[0];
+ free(children, M_TEMP);
+
+ if (device_get_children(dev, &children, &n) != 0) {
+ panic("Slicer called on controller with nandbus but no child!");
+ }
+ dev = children[0];
+ free(children, M_TEMP);
+
+ chip = device_get_softc(dev);
+ *nslices = 2;
+ slices[0].base = 0;
+ slices[0].size = 4 * 1024 * 1024;
+ slices[0].label = "boot";
+
+ slices[1].base = 4 * 1024 * 1024;
+ slices[1].size = chip->ndisk->d_mediasize - slices[0].size;
+ slices[1].label = "rootfs";
+
+ return (0);
+}
+
static int
rb_nand_probe(device_t dev)
{
@@ -175,6 +212,8 @@ rb_nand_attach(device_t dev)
return (ENXIO);
}
+ flash_register_slicer(rb_nand_slicer, FLASH_SLICES_TYPE_NAND, TRUE);
+
nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL);
err = nandbus_create(dev);
diff --git a/sys/dev/ncr/ncr.c b/sys/dev/ncr/ncr.c
index b2bfcdba89e6..e125ee189a80 100644
--- a/sys/dev/ncr/ncr.c
+++ b/sys/dev/ncr/ncr.c
@@ -4152,10 +4152,6 @@ ncr_action (struct cam_sim *sim, union ccb *ccb)
break;
}
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
@@ -5210,7 +5206,7 @@ static void ncr_log_hard_error(ncb_p np, u_short sist, u_char dstat)
} else {
script_ofs = dsp;
script_size = 0;
- script_base = 0;
+ script_base = NULL;
script_name = "mem";
}
@@ -5813,7 +5809,7 @@ static void ncr_int_sir (ncb_p np)
u_char scntl3;
u_char chg, ofs, per, fak, wide;
u_char num = INB (nc_dsps);
- nccb_p cp=0;
+ nccb_p cp = NULL;
u_long dsa;
u_int target = INB (nc_sdid) & 0x0f;
tcb_p tp = &np->target[target];
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
index f51b8f74caf5..fbbd9b357342 100644
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -648,7 +648,7 @@ nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr,
&rid, 0, ~0, *mem_size, RF_ACTIVE);
if (ptn_dev->pci_mem == NULL) {
*nm_paddr = 0;
- *nm_addr = 0;
+ *nm_addr = NULL;
return ENOMEM;
}
diff --git a/sys/dev/netmap/netmap_mem2.c b/sys/dev/netmap/netmap_mem2.c
index ab89d3af65a5..922e5f32ff09 100644
--- a/sys/dev/netmap/netmap_mem2.c
+++ b/sys/dev/netmap/netmap_mem2.c
@@ -2143,7 +2143,7 @@ netmap_mem_pt_guest_deref(struct netmap_mem_d *nmd)
if (ptnmd->ptn_dev) {
nm_os_pt_memdev_iounmap(ptnmd->ptn_dev);
}
- ptnmd->nm_addr = 0;
+ ptnmd->nm_addr = NULL;
ptnmd->nm_paddr = 0;
}
}
diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c
index 397a3bc7110a..86b7710d8b5d 100644
--- a/sys/dev/nvme/nvme_sim.c
+++ b/sys/dev/nvme/nvme_sim.c
@@ -143,14 +143,6 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
*/
/*FALLTHROUGH*/
case XPT_ABORT: /* Abort the specified CCB */
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
- /*
- * Only target mode generates these, and only for SCSI. They are
- * all invalid/unsupported for NVMe.
- */
ccb->ccb_h.status = CAM_REQ_INVALID;
break;
case XPT_SET_TRAN_SETTINGS:
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index 84adfa14d178..01f5549bf331 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -963,7 +963,7 @@ ofw_bus_string_list_to_array(phandle_t node, const char *list_name,
i += len;
tptr += len;
}
- array[cnt] = 0;
+ array[cnt] = NULL;
*out_array = array;
return (cnt);
diff --git a/sys/dev/patm/if_patm_tx.c b/sys/dev/patm/if_patm_tx.c
index 1b9a8a50a1db..33ee8f183a2b 100644
--- a/sys/dev/patm/if_patm_tx.c
+++ b/sys/dev/patm/if_patm_tx.c
@@ -440,7 +440,7 @@ patm_tx_pad(struct patm_softc *sc, struct mbuf *m0)
}
}
MGET(m, M_NOWAIT, MT_DATA);
- if (m == 0) {
+ if (m == NULL) {
m_freem(m0);
if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
return (NULL);
diff --git a/sys/dev/pccard/pccard.c b/sys/dev/pccard/pccard.c
index 04dcc44bef72..4c80feae63ec 100644
--- a/sys/dev/pccard/pccard.c
+++ b/sys/dev/pccard/pccard.c
@@ -470,7 +470,7 @@ pccard_function_init(struct pccard_function *pf, int entry)
struct pccard_ivar *devi = PCCARD_IVAR(pf->dev);
struct resource_list *rl = &devi->resources;
struct resource_list_entry *rle;
- struct resource *r = 0;
+ struct resource *r = NULL;
struct pccard_ce_iospace *ios;
struct pccard_ce_memspace *mems;
device_t bus;
@@ -1115,7 +1115,7 @@ pccard_alloc_resource(device_t dev, device_t child, int type, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
struct pccard_ivar *dinfo;
- struct resource_list_entry *rle = 0;
+ struct resource_list_entry *rle = NULL;
int passthrough = (device_get_parent(child) != dev);
int isdefault = (RMAN_IS_DEFAULT_RANGE(start, end) && count == 1);
struct resource *r = NULL;
@@ -1165,7 +1165,7 @@ pccard_release_resource(device_t dev, device_t child, int type, int rid,
{
struct pccard_ivar *dinfo;
int passthrough = (device_get_parent(child) != dev);
- struct resource_list_entry *rle = 0;
+ struct resource_list_entry *rle = NULL;
if (passthrough)
return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
diff --git a/sys/dev/pms/RefTisa/sallsdk/spc/sainit.c b/sys/dev/pms/RefTisa/sallsdk/spc/sainit.c
index 367c75ab6446..6e112adb95a7 100644
--- a/sys/dev/pms/RefTisa/sallsdk/spc/sainit.c
+++ b/sys/dev/pms/RefTisa/sallsdk/spc/sainit.c
@@ -48,7 +48,7 @@ bit32 gLLSoftResetCounter = 0;
bit32 gPollForMissingInt;
#ifdef FW_EVT_LOG_TST
-void *eventLogAddress = 0;
+void *eventLogAddress = NULL;
#endif
extern bit32 gWait_3;
diff --git a/sys/dev/pms/RefTisa/tisa/sassata/common/tdioctl.c b/sys/dev/pms/RefTisa/tisa/sassata/common/tdioctl.c
index f1926806bfde..f1ee7927c9de 100644
--- a/sys/dev/pms/RefTisa/tisa/sassata/common/tdioctl.c
+++ b/sys/dev/pms/RefTisa/tisa/sassata/common/tdioctl.c
@@ -379,7 +379,7 @@ tiCOMMgntIOCTL(
bit32 Offset = 0;
bit32 RequestLength = 0; /* user request on how much data to pass to application */
agsaContext_t *agContext = NULL;
- bit8 *loc = 0;
+ bit8 *loc = NULL;
TI_DBG3(("tiCOMMgntIOCTL: start\n"));
diff --git a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c
index 2f5f963611fe..ac96eada9752 100644
--- a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c
+++ b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c
@@ -5032,7 +5032,7 @@ STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
int i;
U32 hdr_sz, ccb_sz;
- ccb_t *pccb = 0;
+ ccb_t *pccb = NULL;
int offset = 0;
int nsegs = 0;
int sgl_sz = 0;
@@ -5159,7 +5159,7 @@ STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
U32 max_ccb, size, ccb_sz, hdr_sz;
int no_allocs = 0, i;
- ccb_hdr_t *hdr = 0;
+ ccb_hdr_t *hdr = NULL;
AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
@@ -5395,7 +5395,7 @@ STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
{
- if ( agDev[devIdx] != 0 )
+ if ( agDev[devIdx] != NULL )
{
// AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
// devIdx, agDev[devIdx] );
@@ -5820,7 +5820,7 @@ STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
ccb_hdr_t *hdr;
U32 hdr_sz;
- ccb_t *pccb = 0;
+ ccb_t *pccb = NULL;
AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c
index 93a0da17307a..7a9d9b0e4579 100644
--- a/sys/dev/ppbus/if_plip.c
+++ b/sys/dev/ppbus/if_plip.c
@@ -245,7 +245,7 @@ lp_attach(device_t dev)
*/
lp->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE);
- if (lp->res_irq == 0) {
+ if (lp->res_irq == NULL) {
device_printf(dev, "cannot reserve interrupt, failed.\n");
return (ENXIO);
}
@@ -453,7 +453,7 @@ lpioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCADDMULTI:
case SIOCDELMULTI:
- if (ifr == 0) {
+ if (ifr == NULL) {
return (EAFNOSUPPORT); /* XXX */
}
switch (ifr->ifr_addr.sa_family) {
diff --git a/sys/dev/ppbus/ppbconf.c b/sys/dev/ppbus/ppbconf.c
index a2370dde098e..b5b74b46243a 100644
--- a/sys/dev/ppbus/ppbconf.c
+++ b/sys/dev/ppbus/ppbconf.c
@@ -206,7 +206,7 @@ search_token(char *str, int slen, char *token)
static int
ppb_pnp_detect(device_t bus)
{
- char *token, *class = 0;
+ char *token, *class = NULL;
int i, len, error;
int class_id = -1;
char str[PPB_PnP_STRING_SIZE+1];
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c
index 9515039036d9..cd9cf2148762 100644
--- a/sys/dev/ppc/ppc.c
+++ b/sys/dev/ppc/ppc.c
@@ -1324,9 +1324,9 @@ ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
register int reg;
register char mask;
register int accum = 0;
- register char *ptr = 0;
+ register char *ptr = NULL;
- struct ppb_microseq *stack = 0;
+ struct ppb_microseq *stack = NULL;
/* microsequence registers are equivalent to PC-like port registers */
@@ -1496,7 +1496,7 @@ ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
mi = stack;
/* reset the stack */
- stack = 0;
+ stack = NULL;
/* XXX return code */
diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c
index b7cda78f672f..77efe6d65782 100644
--- a/sys/dev/qlxgbe/ql_os.c
+++ b/sys/dev/qlxgbe/ql_os.c
@@ -735,6 +735,7 @@ ql_alloc_dmabuf_exit:
void
ql_free_dmabuf(qla_host_t *ha, qla_dma_t *dma_buf)
{
+ bus_dmamap_unload(dma_buf->dma_tag, dma_buf->dma_map);
bus_dmamem_free(dma_buf->dma_tag, dma_buf->dma_b, dma_buf->dma_map);
bus_dma_tag_destroy(dma_buf->dma_tag);
}
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index d4872cd50446..3e4d7fdde42a 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -1616,9 +1616,9 @@ rt2661_start(struct rt2661_softc *sc)
}
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (rt2661_tx_data(sc, m, ni, ac) != 0) {
- ieee80211_free_node(ni);
if_inc_counter(ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
break;
}
sc->sc_tx_timer = 5;
diff --git a/sys/dev/sbni/if_sbni_isa.c b/sys/dev/sbni/if_sbni_isa.c
index 61a239841b19..f1db8b1a984c 100644
--- a/sys/dev/sbni/if_sbni_isa.c
+++ b/sys/dev/sbni/if_sbni_isa.c
@@ -132,7 +132,7 @@ sbni_attach_isa(device_t dev)
} else {
struct sbni_softc *master;
- if ((master = connect_to_master(sc)) == 0) {
+ if ((master = connect_to_master(sc)) == NULL) {
device_printf(dev, "failed to alloc irq\n");
sbni_release_resources(sc);
return (ENXIO);
diff --git a/sys/dev/sdhci/sdhci_fdt_gpio.c b/sys/dev/sdhci/sdhci_fdt_gpio.c
index be9f629aacf6..2f2fb1864f22 100644
--- a/sys/dev/sdhci/sdhci_fdt_gpio.c
+++ b/sys/dev/sdhci/sdhci_fdt_gpio.c
@@ -192,7 +192,7 @@ wp_setup(struct sdhci_fdt_gpio *gpio, phandle_t node)
if (bootverbose)
device_printf(dev, "Write protect switch on %s pin %u\n",
- device_get_nameunit(gpio->cd_pin->dev), gpio->cd_pin->pin);
+ device_get_nameunit(gpio->wp_pin->dev), gpio->wp_pin->pin);
}
struct sdhci_fdt_gpio *
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 976952f13c0c..8b5b3c69d1ba 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -1835,10 +1835,6 @@ siisaction(struct cam_sim *sim, union ccb *ccb)
}
siis_begin_transaction(dev, ccb);
return;
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
case XPT_ABORT: /* Abort the specified CCB */
/* XXX Implement */
ccb->ccb_h.status = CAM_REQ_INVALID;
diff --git a/sys/dev/sn/if_sn.c b/sys/dev/sn/if_sn.c
index 7ac2a13170cd..0306089c8629 100644
--- a/sys/dev/sn/if_sn.c
+++ b/sys/dev/sn/if_sn.c
@@ -393,7 +393,7 @@ startagain:
* Sneak a peek at the next packet
*/
m = ifp->if_snd.ifq_head;
- if (m == 0)
+ if (m == NULL)
return;
/*
* Compute the frame length and set pad to give an overall even
@@ -509,7 +509,7 @@ startagain:
/*
* Push out the data to the card.
*/
- for (top = m; m != 0; m = m->m_next) {
+ for (top = m; m != NULL; m = m->m_next) {
/*
* Push out words.
@@ -607,7 +607,7 @@ snresume(struct ifnet *ifp)
* Sneak a peek at the next packet
*/
m = ifp->if_snd.ifq_head;
- if (m == 0) {
+ if (m == NULL) {
if_printf(ifp, "snresume() with nothing to send\n");
return;
}
@@ -708,7 +708,7 @@ snresume(struct ifnet *ifp)
/*
* Push out the data to the card.
*/
- for (top = m; m != 0; m = m->m_next) {
+ for (top = m; m != NULL; m = m->m_next) {
/*
* Push out words.
diff --git a/sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c
index a3a101ff5f06..a9c2070aeec6 100644
--- a/sys/dev/sym/sym_hipd.c
+++ b/sys/dev/sym/sym_hipd.c
@@ -3710,7 +3710,7 @@ static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat)
} else {
script_ofs = dsp;
script_size = 0;
- script_base = 0;
+ script_base = NULL;
script_name = "mem";
}
@@ -4296,7 +4296,7 @@ static void sym_int_ma (hcb_p np)
* try to find the interrupted script command,
* and the address at which to continue.
*/
- vdsp = 0;
+ vdsp = NULL;
nxtdsp = 0;
if (dsp > np->scripta_ba &&
dsp <= np->scripta_ba + np->scripta_sz) {
@@ -6673,7 +6673,7 @@ static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln)
lp->cb_tags = sym_calloc(SYM_CONF_MAX_TASK, "CB_TAGS");
if (!lp->cb_tags) {
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
- lp->itlq_tbl = 0;
+ lp->itlq_tbl = NULL;
return;
}
@@ -8090,11 +8090,6 @@ static void sym_action2(struct cam_sim *sim, union ccb *ccb)
sym_init (np, 1);
sym_xpt_done2(np, ccb, CAM_REQ_CMP);
break;
- case XPT_ACCEPT_TARGET_IO:
- case XPT_CONT_TARGET_IO:
- case XPT_EN_LUN:
- case XPT_NOTIFY_ACK:
- case XPT_IMMED_NOTIFY:
case XPT_TERM_IO:
default:
sym_xpt_done2(np, ccb, CAM_REQ_INVALID);
diff --git a/sys/dev/trm/trm.c b/sys/dev/trm/trm.c
index a205929c6ec9..5374807f2c11 100644
--- a/sys/dev/trm/trm.c
+++ b/sys/dev/trm/trm.c
@@ -543,11 +543,6 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
target_lun = pccb->ccb_h.target_lun;
switch (pccb->ccb_h.func_code) {
- case XPT_NOOP:
- TRM_DPRINTF(" XPT_NOOP \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
/*
* Execute the requested I/O operation
*/
@@ -623,16 +618,6 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
}
break;
}
- case XPT_GDEV_TYPE:
- TRM_DPRINTF(" XPT_GDEV_TYPE \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- case XPT_GDEVLIST:
- TRM_DPRINTF(" XPT_GDEVLIST \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
/*
* Path routing inquiry
* Path Inquiry CCB
@@ -661,76 +646,33 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
cpi->protocol_version = SCSI_REV_2;
cpi->ccb_h.status = CAM_REQ_CMP;
xpt_done(pccb);
- }
break;
+ }
/*
- * Release a frozen SIM queue
- * Release SIM Queue
+ * XPT_ABORT = 0x10, Abort the specified CCB
+ * Abort XPT request CCB
*/
- case XPT_REL_SIMQ:
- TRM_DPRINTF(" XPT_REL_SIMQ \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Set Asynchronous Callback Parameters
- * Set Asynchronous Callback CCB
- */
- case XPT_SASYNC_CB:
- TRM_DPRINTF(" XPT_SASYNC_CB \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Set device type information
- * Set Device Type CCB
- */
- case XPT_SDEV_TYPE:
- TRM_DPRINTF(" XPT_SDEV_TYPE \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Get EDT entries matching the given pattern
- */
- case XPT_DEV_MATCH:
- TRM_DPRINTF(" XPT_DEV_MATCH \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Turn on debugging for a bus, target or lun
- */
- case XPT_DEBUG:
- TRM_DPRINTF(" XPT_DEBUG \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * XPT_ABORT = 0x10, Abort the specified CCB
- * Abort XPT request CCB
- */
case XPT_ABORT:
TRM_DPRINTF(" XPT_ABORT \n");
pccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(pccb);
break;
/*
- * Reset the specified SCSI bus
- * Reset SCSI Bus CCB
- */
- case XPT_RESET_BUS: {
+ * Reset the specified SCSI bus
+ * Reset SCSI Bus CCB
+ */
+ case XPT_RESET_BUS: {
int i;
TRM_DPRINTF(" XPT_RESET_BUS \n");
- trm_reset(pACB);
+ trm_reset(pACB);
pACB->ACBFlag=0;
for (i=0; i<500; i++)
DELAY(1000);
pccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(pccb);
- }
break;
+ }
/*
* Bus Device Reset the specified SCSI device
* Reset SCSI Device CCB
@@ -929,92 +871,6 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
cam_calc_geometry(&pccb->ccg, /*extended*/1);
xpt_done(pccb);
break;
- case XPT_ENG_INQ:
- TRM_DPRINTF(" XPT_ENG_INQ \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * HBA execute engine request
- * This structure must match SCSIIO size
- */
- case XPT_ENG_EXEC:
- TRM_DPRINTF(" XPT_ENG_EXEC \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * XPT_EN_LUN = 0x30, Enable LUN as a target
- * Target mode structures.
- */
- case XPT_EN_LUN:
- /*
- * Don't (yet?) support vendor
- * specific commands.
- */
- TRM_DPRINTF(" XPT_EN_LUN \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Execute target I/O request
- */
- case XPT_TARGET_IO:
- /*
- * Don't (yet?) support vendor
- * specific commands.
- */
- TRM_DPRINTF(" XPT_TARGET_IO \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Accept Host Target Mode CDB
- */
- case XPT_ACCEPT_TARGET_IO:
- /*
- * Don't (yet?) support vendor
- * specific commands.
- */
- TRM_DPRINTF(" XPT_ACCEPT_TARGET_IO \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Continue Host Target I/O Connection
- */
- case XPT_CONT_TARGET_IO:
- /*
- * Don't (yet?) support vendor
- * specific commands.
- */
- TRM_DPRINTF(" XPT_CONT_TARGET_IO \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Notify Host Target driver of event
- */
- case XPT_IMMED_NOTIFY:
- TRM_DPRINTF(" XPT_IMMED_NOTIFY \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * Acknowledgement of event
- */
- case XPT_NOTIFY_ACK:
- TRM_DPRINTF(" XPT_NOTIFY_ACK \n");
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- /*
- * XPT_VUNIQUE = 0x80
- */
- case XPT_VUNIQUE:
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
default:
pccb->ccb_h.status = CAM_REQ_INVALID;
xpt_done(pccb);
diff --git a/sys/dev/usb/storage/cfumass.c b/sys/dev/usb/storage/cfumass.c
new file mode 100644
index 000000000000..0565fed142bd
--- /dev/null
+++ b/sys/dev/usb/storage/cfumass.c
@@ -0,0 +1,1075 @@
+/*-
+ * Copyright (c) 2016 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/*
+ * USB Mass Storage Class Bulk-Only (BBB) Transport target.
+ *
+ * http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
+ *
+ * This code implements the USB Mass Storage frontend driver for the CAM
+ * Target Layer (ctl(4)) subsystem.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/refcount.h>
+#include <sys/stdint.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include "usbdevs.h"
+#include "usb_if.h"
+
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_da.h>
+#include <cam/ctl/ctl_io.h>
+#include <cam/ctl/ctl.h>
+#include <cam/ctl/ctl_backend.h>
+#include <cam/ctl/ctl_error.h>
+#include <cam/ctl/ctl_frontend.h>
+#include <cam/ctl/ctl_debug.h>
+#include <cam/ctl/ctl_ha.h>
+#include <cam/ctl/ctl_ioctl.h>
+#include <cam/ctl/ctl_private.h>
+
+SYSCTL_NODE(_hw_usb, OID_AUTO, cfumass, CTLFLAG_RW, 0,
+ "CAM Target Layer USB Mass Storage Frontend");
+static int debug = 1;
+SYSCTL_INT(_hw_usb_cfumass, OID_AUTO, debug, CTLFLAG_RWTUN,
+ &debug, 1, "Enable debug messages");
+static int max_lun = 0;
+SYSCTL_INT(_hw_usb_cfumass, OID_AUTO, max_lun, CTLFLAG_RWTUN,
+ &max_lun, 1, "Maximum advertised LUN number");
+static int ignore_stop = 1;
+SYSCTL_INT(_hw_usb_cfumass, OID_AUTO, ignore_stop, CTLFLAG_RWTUN,
+ &ignore_stop, 1, "Ignore START STOP UNIT with START and LOEJ bits cleared");
+
+/*
+ * The driver uses a single, global CTL port. It could create its ports
+ * in cfumass_attach() instead, but that would make it impossible to specify
+ * "port cfumass0" in ctl.conf(5), as the port generally wouldn't exist
+ * at the time ctld(8) gets run.
+ */
+struct ctl_port cfumass_port;
+bool cfumass_port_online;
+volatile u_int cfumass_refcount;
+
+#ifndef CFUMASS_BULK_SIZE
+#define CFUMASS_BULK_SIZE (1U << 17) /* bytes */
+#endif
+
+/*
+ * USB transfer definitions.
+ */
+#define CFUMASS_T_COMMAND 0
+#define CFUMASS_T_DATA_OUT 1
+#define CFUMASS_T_DATA_IN 2
+#define CFUMASS_T_STATUS 3
+#define CFUMASS_T_MAX 4
+
+/*
+ * USB interface specific control requests.
+ */
+#define UR_RESET 0xff /* Bulk-Only Mass Storage Reset */
+#define UR_GET_MAX_LUN 0xfe /* Get Max LUN */
+
+/*
+ * Command Block Wrapper.
+ */
+struct cfumass_cbw_t {
+ uDWord dCBWSignature;
+#define CBWSIGNATURE 0x43425355 /* "USBC" */
+ uDWord dCBWTag;
+ uDWord dCBWDataTransferLength;
+ uByte bCBWFlags;
+#define CBWFLAGS_OUT 0x00
+#define CBWFLAGS_IN 0x80
+ uByte bCBWLUN;
+ uByte bCDBLength;
+#define CBWCBLENGTH 16
+ uByte CBWCB[CBWCBLENGTH];
+} __packed;
+
+#define CFUMASS_CBW_SIZE 31
+CTASSERT(sizeof(struct cfumass_cbw_t) == CFUMASS_CBW_SIZE);
+
+/*
+ * Command Status Wrapper.
+ */
+struct cfumass_csw_t {
+ uDWord dCSWSignature;
+#define CSWSIGNATURE 0x53425355 /* "USBS" */
+ uDWord dCSWTag;
+ uDWord dCSWDataResidue;
+ uByte bCSWStatus;
+#define CSWSTATUS_GOOD 0x0
+#define CSWSTATUS_FAILED 0x1
+#define CSWSTATUS_PHASE 0x2
+} __packed;
+
+#define CFUMASS_CSW_SIZE 13
+CTASSERT(sizeof(struct cfumass_csw_t) == CFUMASS_CSW_SIZE);
+
+struct cfumass_softc {
+ device_t sc_dev;
+ struct usb_device *sc_udev;
+ struct usb_xfer *sc_xfer[CFUMASS_T_MAX];
+
+ struct cfumass_cbw_t *sc_cbw;
+ struct cfumass_csw_t *sc_csw;
+
+ struct mtx sc_mtx;
+ int sc_online;
+ int sc_ctl_initid;
+
+ /*
+ * This is used to communicate between CTL callbacks
+ * and USB callbacks; basically, it holds the state
+ * for the current command ("the" command, since there
+ * is no queueing in USB Mass Storage).
+ */
+ bool sc_current_stalled;
+
+ /*
+ * The following are set upon receiving a SCSI command.
+ */
+ int sc_current_tag;
+ int sc_current_transfer_length;
+ int sc_current_flags;
+
+ /*
+ * The following are set in ctl_datamove().
+ */
+ int sc_current_residue;
+ union ctl_io *sc_ctl_io;
+
+ /*
+ * The following is set in cfumass_done().
+ */
+ int sc_current_status;
+
+ /*
+ * Number of requests queued to CTL.
+ */
+ volatile u_int sc_queued;
+};
+
+/*
+ * USB interface.
+ */
+static device_probe_t cfumass_probe;
+static device_attach_t cfumass_attach;
+static device_detach_t cfumass_detach;
+static device_suspend_t cfumass_suspend;
+static device_resume_t cfumass_resume;
+static usb_handle_request_t cfumass_handle_request;
+
+static usb_callback_t cfumass_t_command_callback;
+static usb_callback_t cfumass_t_data_out_callback;
+static usb_callback_t cfumass_t_data_in_callback;
+static usb_callback_t cfumass_t_status_callback;
+
+static device_method_t cfumass_methods[] = {
+
+ /* USB interface. */
+ DEVMETHOD(usb_handle_request, cfumass_handle_request),
+
+ /* Device interface. */
+ DEVMETHOD(device_probe, cfumass_probe),
+ DEVMETHOD(device_attach, cfumass_attach),
+ DEVMETHOD(device_detach, cfumass_detach),
+ DEVMETHOD(device_suspend, cfumass_suspend),
+ DEVMETHOD(device_resume, cfumass_resume),
+
+ DEVMETHOD_END
+};
+
+static driver_t cfumass_driver = {
+ .name = "cfumass",
+ .methods = cfumass_methods,
+ .size = sizeof(struct cfumass_softc),
+};
+
+static devclass_t cfumass_devclass;
+
+DRIVER_MODULE(cfumass, uhub, cfumass_driver, cfumass_devclass, NULL, 0);
+MODULE_VERSION(cfumass, 0);
+MODULE_DEPEND(cfumass, usb, 1, 1, 1);
+MODULE_DEPEND(cfumass, usb_template, 1, 1, 1);
+
+static struct usb_config cfumass_config[CFUMASS_T_MAX] = {
+
+ [CFUMASS_T_COMMAND] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .bufsize = sizeof(struct cfumass_cbw_t),
+ .callback = &cfumass_t_command_callback,
+ .usb_mode = USB_MODE_DEVICE,
+ },
+
+ [CFUMASS_T_DATA_OUT] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_OUT,
+ .bufsize = CFUMASS_BULK_SIZE,
+ .flags = {.proxy_buffer = 1, .short_xfer_ok = 1,
+ .ext_buffer = 1},
+ .callback = &cfumass_t_data_out_callback,
+ .usb_mode = USB_MODE_DEVICE,
+ },
+
+ [CFUMASS_T_DATA_IN] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .bufsize = CFUMASS_BULK_SIZE,
+ .flags = {.proxy_buffer = 1, .short_xfer_ok = 1,
+ .ext_buffer = 1},
+ .callback = &cfumass_t_data_in_callback,
+ .usb_mode = USB_MODE_DEVICE,
+ },
+
+ [CFUMASS_T_STATUS] = {
+ .type = UE_BULK,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .bufsize = sizeof(struct cfumass_csw_t),
+ .flags = {.short_xfer_ok = 1},
+ .callback = &cfumass_t_status_callback,
+ .usb_mode = USB_MODE_DEVICE,
+ },
+};
+
+/*
+ * CTL frontend interface.
+ */
+static int cfumass_init(void);
+static int cfumass_shutdown(void);
+static void cfumass_online(void *arg);
+static void cfumass_offline(void *arg);
+static void cfumass_datamove(union ctl_io *io);
+static void cfumass_done(union ctl_io *io);
+
+static struct ctl_frontend cfumass_frontend = {
+ .name = "umass",
+ .init = cfumass_init,
+ .shutdown = cfumass_shutdown,
+};
+CTL_FRONTEND_DECLARE(ctlcfumass, cfumass_frontend);
+
+#define CFUMASS_DEBUG(S, X, ...) \
+ do { \
+ if (debug > 1) { \
+ device_printf(S->sc_dev, "%s: " X "\n", \
+ __func__, ## __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define CFUMASS_WARN(S, X, ...) \
+ do { \
+ if (debug > 0) { \
+ device_printf(S->sc_dev, "WARNING: %s: " X "\n",\
+ __func__, ## __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define CFUMASS_LOCK(X) mtx_lock(&X->sc_mtx)
+#define CFUMASS_UNLOCK(X) mtx_unlock(&X->sc_mtx)
+
+static void cfumass_transfer_start(struct cfumass_softc *sc,
+ uint8_t xfer_index);
+static void cfumass_terminate(struct cfumass_softc *sc);
+
+static int
+cfumass_probe(device_t dev)
+{
+ struct usb_attach_arg *uaa;
+ struct usb_interface_descriptor *id;
+
+ uaa = device_get_ivars(dev);
+
+ if (uaa->usb_mode != USB_MODE_DEVICE)
+ return (ENXIO);
+
+ /*
+ * Check for a compliant device.
+ */
+ id = usbd_get_interface_descriptor(uaa->iface);
+ if ((id == NULL) ||
+ (id->bInterfaceClass != UICLASS_MASS) ||
+ (id->bInterfaceSubClass != UISUBCLASS_SCSI) ||
+ (id->bInterfaceProtocol != UIPROTO_MASS_BBB)) {
+ return (ENXIO);
+ }
+
+ return (BUS_PROBE_GENERIC);
+}
+
+static int
+cfumass_attach(device_t dev)
+{
+ struct cfumass_softc *sc;
+ struct usb_attach_arg *uaa;
+ int error;
+
+ sc = device_get_softc(dev);
+ uaa = device_get_ivars(dev);
+
+ sc->sc_dev = dev;
+ sc->sc_udev = uaa->device;
+
+ CFUMASS_DEBUG(sc, "go");
+
+ usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE);
+ device_set_usb_desc(dev);
+
+ mtx_init(&sc->sc_mtx, "cfumass", NULL, MTX_DEF);
+ refcount_acquire(&cfumass_refcount);
+
+ error = usbd_transfer_setup(uaa->device,
+ &uaa->info.bIfaceIndex, sc->sc_xfer, cfumass_config,
+ CFUMASS_T_MAX, sc, &sc->sc_mtx);
+ if (error != 0) {
+ CFUMASS_WARN(sc, "usbd_transfer_setup() failed: %s",
+ usbd_errstr(error));
+ refcount_release(&cfumass_refcount);
+ return (ENXIO);
+ }
+
+ sc->sc_cbw =
+ usbd_xfer_get_frame_buffer(sc->sc_xfer[CFUMASS_T_COMMAND], 0);
+ sc->sc_csw =
+ usbd_xfer_get_frame_buffer(sc->sc_xfer[CFUMASS_T_STATUS], 0);
+
+ sc->sc_ctl_initid = ctl_add_initiator(&cfumass_port, -1, 0, NULL);
+ if (sc->sc_ctl_initid < 0) {
+ CFUMASS_WARN(sc, "ctl_add_initiator() failed with error %d",
+ sc->sc_ctl_initid);
+ usbd_transfer_unsetup(sc->sc_xfer, CFUMASS_T_MAX);
+ refcount_release(&cfumass_refcount);
+ return (ENXIO);
+ }
+
+ refcount_init(&sc->sc_queued, 0);
+
+ CFUMASS_LOCK(sc);
+ cfumass_transfer_start(sc, CFUMASS_T_COMMAND);
+ CFUMASS_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+cfumass_detach(device_t dev)
+{
+ struct cfumass_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ CFUMASS_DEBUG(sc, "go");
+
+ CFUMASS_LOCK(sc);
+ cfumass_terminate(sc);
+ CFUMASS_UNLOCK(sc);
+ usbd_transfer_unsetup(sc->sc_xfer, CFUMASS_T_MAX);
+
+ if (sc->sc_ctl_initid != -1) {
+ error = ctl_remove_initiator(&cfumass_port, sc->sc_ctl_initid);
+ if (error != 0) {
+ CFUMASS_WARN(sc, "ctl_remove_initiator() failed "
+ "with error %d", error);
+ }
+ sc->sc_ctl_initid = -1;
+ }
+
+ mtx_destroy(&sc->sc_mtx);
+ refcount_release(&cfumass_refcount);
+
+ return (0);
+}
+
+static int
+cfumass_suspend(device_t dev)
+{
+ struct cfumass_softc *sc;
+
+ sc = device_get_softc(dev);
+ CFUMASS_DEBUG(sc, "go");
+
+ return (0);
+}
+
+static int
+cfumass_resume(device_t dev)
+{
+ struct cfumass_softc *sc;
+
+ sc = device_get_softc(dev);
+ CFUMASS_DEBUG(sc, "go");
+
+ return (0);
+}
+
+static void
+cfumass_transfer_start(struct cfumass_softc *sc, uint8_t xfer_index)
+{
+
+ usbd_transfer_start(sc->sc_xfer[xfer_index]);
+}
+
+static void
+cfumass_transfer_stop_and_drain(struct cfumass_softc *sc, uint8_t xfer_index)
+{
+
+ usbd_transfer_stop(sc->sc_xfer[xfer_index]);
+ CFUMASS_UNLOCK(sc);
+ usbd_transfer_drain(sc->sc_xfer[xfer_index]);
+ CFUMASS_LOCK(sc);
+}
+
+static void
+cfumass_terminate(struct cfumass_softc *sc)
+{
+ int last;
+
+ for (;;) {
+ cfumass_transfer_stop_and_drain(sc, CFUMASS_T_COMMAND);
+ cfumass_transfer_stop_and_drain(sc, CFUMASS_T_DATA_IN);
+ cfumass_transfer_stop_and_drain(sc, CFUMASS_T_DATA_OUT);
+
+ if (sc->sc_ctl_io != NULL) {
+ CFUMASS_DEBUG(sc, "terminating CTL transfer");
+ ctl_set_data_phase_error(&sc->sc_ctl_io->scsiio);
+ sc->sc_ctl_io->scsiio.be_move_done(sc->sc_ctl_io);
+ sc->sc_ctl_io = NULL;
+ }
+
+ cfumass_transfer_stop_and_drain(sc, CFUMASS_T_STATUS);
+
+ refcount_acquire(&sc->sc_queued);
+ last = refcount_release(&sc->sc_queued);
+ if (last != 0)
+ break;
+
+ CFUMASS_DEBUG(sc, "%d CTL tasks pending", sc->sc_queued);
+ msleep(__DEVOLATILE(void *, &sc->sc_queued), &sc->sc_mtx,
+ 0, "cfumass_reset", hz / 100);
+ }
+}
+
+static int
+cfumass_handle_request(device_t dev,
+ const void *preq, void **pptr, uint16_t *plen,
+ uint16_t offset, uint8_t *pstate)
+{
+ static uint8_t max_lun_tmp;
+ struct cfumass_softc *sc;
+ const struct usb_device_request *req;
+ uint8_t is_complete;
+
+ sc = device_get_softc(dev);
+ req = preq;
+ is_complete = *pstate;
+
+ CFUMASS_DEBUG(sc, "go");
+
+ if (is_complete)
+ return (ENXIO);
+
+ if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) &&
+ (req->bRequest == UR_RESET)) {
+ CFUMASS_WARN(sc, "received Bulk-Only Mass Storage Reset");
+ *plen = 0;
+
+ CFUMASS_LOCK(sc);
+ cfumass_terminate(sc);
+ cfumass_transfer_start(sc, CFUMASS_T_COMMAND);
+ CFUMASS_UNLOCK(sc);
+
+ CFUMASS_DEBUG(sc, "Bulk-Only Mass Storage Reset done");
+ return (0);
+ }
+
+ if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
+ (req->bRequest == UR_GET_MAX_LUN)) {
+ CFUMASS_DEBUG(sc, "received Get Max LUN");
+ if (offset == 0) {
+ *plen = 1;
+ /*
+ * The protocol doesn't support LUN numbers higher
+ * than 15. Also, some initiators (namely Windows XP
+ * SP3 Version 2002) can't properly query the number
+ * of LUNs, resulting in inaccessible "fake" ones - thus
+ * the default limit of one LUN.
+ */
+ if (max_lun < 0 || max_lun > 15) {
+ CFUMASS_WARN(sc,
+ "invalid hw.usb.cfumass.max_lun, must be "
+ "between 0 and 15; defaulting to 0");
+ max_lun_tmp = 0;
+ } else {
+ max_lun_tmp = max_lun;
+ }
+ *pptr = &max_lun_tmp;
+ } else {
+ *plen = 0;
+ }
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
+static int
+cfumass_quirk(struct cfumass_softc *sc, unsigned char *cdb, int cdb_len)
+{
+ struct scsi_start_stop_unit *sssu;
+
+ switch (cdb[0]) {
+ case START_STOP_UNIT:
+ /*
+ * Some initiators - eg OSX, Darwin Kernel Version 15.6.0,
+ * root:xnu-3248.60.11~2/RELEASE_X86_64 - attempt to stop
+ * the unit on eject, but fail to start it when it's plugged
+ * back. Just ignore the command.
+ */
+
+ if (cdb_len < sizeof(*sssu)) {
+ CFUMASS_DEBUG(sc, "received START STOP UNIT with "
+ "bCDBLength %d, should be %zd",
+ cdb_len, sizeof(*sssu));
+ break;
+ }
+
+ sssu = (struct scsi_start_stop_unit *)cdb;
+ if ((sssu->how & SSS_PC_MASK) != 0)
+ break;
+
+ if ((sssu->how & SSS_START) != 0)
+ break;
+
+ if ((sssu->how & SSS_LOEJ) != 0)
+ break;
+
+ if (ignore_stop == 0) {
+ break;
+ } else if (ignore_stop == 1) {
+ CFUMASS_WARN(sc, "ignoring START STOP UNIT request");
+ } else {
+ CFUMASS_DEBUG(sc, "ignoring START STOP UNIT request");
+ }
+
+ sc->sc_current_status = 0;
+ cfumass_transfer_start(sc, CFUMASS_T_STATUS);
+
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+static void
+cfumass_t_command_callback(struct usb_xfer *xfer, usb_error_t usb_error)
+{
+ struct cfumass_softc *sc;
+ uint32_t signature;
+ union ctl_io *io;
+ int error = 0;
+
+ sc = usbd_xfer_softc(xfer);
+
+ KASSERT(sc->sc_ctl_io == NULL,
+ ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ CFUMASS_DEBUG(sc, "USB_ST_TRANSFERRED");
+
+ signature = UGETDW(sc->sc_cbw->dCBWSignature);
+ if (signature != CBWSIGNATURE) {
+ CFUMASS_WARN(sc, "wrong dCBWSignature 0x%08x, "
+ "should be 0x%08x", signature, CBWSIGNATURE);
+ break;
+ }
+
+ if (sc->sc_cbw->bCDBLength <= 0 ||
+ sc->sc_cbw->bCDBLength > sizeof(sc->sc_cbw->CBWCB)) {
+ CFUMASS_WARN(sc, "invalid bCDBLength %d, should be <= %zd",
+ sc->sc_cbw->bCDBLength, sizeof(sc->sc_cbw->CBWCB));
+ break;
+ }
+
+ sc->sc_current_stalled = false;
+ sc->sc_current_status = 0;
+ sc->sc_current_tag = UGETDW(sc->sc_cbw->dCBWTag);
+ sc->sc_current_transfer_length =
+ UGETDW(sc->sc_cbw->dCBWDataTransferLength);
+ sc->sc_current_flags = sc->sc_cbw->bCBWFlags;
+
+ /*
+ * Make sure to report proper residue if the datamove wasn't
+ * required, or wasn't called due to SCSI error.
+ */
+ sc->sc_current_residue = sc->sc_current_transfer_length;
+
+ if (cfumass_quirk(sc,
+ sc->sc_cbw->CBWCB, sc->sc_cbw->bCDBLength) != 0)
+ break;
+
+ if (!cfumass_port_online) {
+ CFUMASS_DEBUG(sc, "cfumass port is offline; stalling");
+ usbd_xfer_set_stall(xfer);
+ break;
+ }
+
+ /*
+ * Those CTL functions cannot be called with mutex held.
+ */
+ CFUMASS_UNLOCK(sc);
+ io = ctl_alloc_io(cfumass_port.ctl_pool_ref);
+ ctl_zero_io(io);
+ io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = sc;
+ io->io_hdr.io_type = CTL_IO_SCSI;
+ io->io_hdr.nexus.initid = sc->sc_ctl_initid;
+ io->io_hdr.nexus.targ_port = cfumass_port.targ_port;
+ io->io_hdr.nexus.targ_lun = ctl_decode_lun(sc->sc_cbw->bCBWLUN);
+ io->scsiio.tag_num = UGETDW(sc->sc_cbw->dCBWTag);
+ io->scsiio.tag_type = CTL_TAG_UNTAGGED;
+ io->scsiio.cdb_len = sc->sc_cbw->bCDBLength;
+ memcpy(io->scsiio.cdb, sc->sc_cbw->CBWCB, sc->sc_cbw->bCDBLength);
+ refcount_acquire(&sc->sc_queued);
+ error = ctl_queue(io);
+ if (error != CTL_RETVAL_COMPLETE) {
+ CFUMASS_WARN(sc,
+ "ctl_queue() failed; error %d; stalling", error);
+ ctl_free_io(io);
+ refcount_release(&sc->sc_queued);
+ CFUMASS_LOCK(sc);
+ usbd_xfer_set_stall(xfer);
+ break;
+ }
+
+ CFUMASS_LOCK(sc);
+ break;
+
+ case USB_ST_SETUP:
+tr_setup:
+ CFUMASS_DEBUG(sc, "USB_ST_SETUP");
+
+ usbd_xfer_set_frame_len(xfer, 0, sizeof(*sc->sc_cbw));
+ usbd_transfer_submit(xfer);
+ break;
+
+ default:
+ if (usb_error == USB_ERR_CANCELLED) {
+ CFUMASS_DEBUG(sc, "USB_ERR_CANCELLED");
+ break;
+ }
+
+ CFUMASS_DEBUG(sc, "USB_ST_ERROR: %s", usbd_errstr(usb_error));
+
+ goto tr_setup;
+ }
+}
+
+static void
+cfumass_t_data_out_callback(struct usb_xfer *xfer, usb_error_t usb_error)
+{
+ struct cfumass_softc *sc;
+ union ctl_io *io;
+ struct ctl_sg_entry ctl_sg_entry, *ctl_sglist;
+ int actlen, ctl_sg_count;
+
+ sc = usbd_xfer_softc(xfer);
+
+ CFUMASS_DEBUG(sc, "go");
+
+ usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+ io = sc->sc_ctl_io;
+
+ if (io->scsiio.kern_sg_entries > 0) {
+ ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
+ ctl_sg_count = io->scsiio.kern_sg_entries;
+ } else {
+ ctl_sglist = &ctl_sg_entry;
+ ctl_sglist->addr = io->scsiio.kern_data_ptr;
+ ctl_sglist->len = io->scsiio.kern_data_len;
+ ctl_sg_count = 1;
+ }
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ CFUMASS_DEBUG(sc, "USB_ST_TRANSFERRED");
+
+ /*
+ * If the host sent less data than required, zero-out
+ * the remaining buffer space, to prevent a malicious host
+ * to writing uninitialized kernel memory to the disk.
+ */
+ if (actlen != ctl_sglist[0].len) {
+ KASSERT(actlen <= ctl_sglist[0].len,
+ ("actlen %d > ctl_sglist.len %zd",
+ actlen, ctl_sglist[0].len));
+
+ CFUMASS_DEBUG(sc, "host transferred %d bytes"
+ "instead of expected %zd bytes",
+ actlen, ctl_sglist[0].len);
+
+ memset((char *)(ctl_sglist[0].addr) + actlen, 0,
+ ctl_sglist[0].len - actlen);
+ }
+
+ sc->sc_current_residue = 0;
+ io->scsiio.be_move_done(io);
+ sc->sc_ctl_io = NULL;
+ break;
+
+ case USB_ST_SETUP:
+tr_setup:
+ CFUMASS_DEBUG(sc, "USB_ST_SETUP");
+
+ CFUMASS_DEBUG(sc, "requested size %d, CTL segment size %zd",
+ sc->sc_current_transfer_length, ctl_sglist[0].len);
+
+ usbd_xfer_set_frame_data(xfer, 0, ctl_sglist[0].addr, ctl_sglist[0].len);
+ usbd_transfer_submit(xfer);
+ break;
+
+ default:
+ if (usb_error == USB_ERR_CANCELLED) {
+ CFUMASS_DEBUG(sc, "USB_ERR_CANCELLED");
+ break;
+ }
+
+ CFUMASS_DEBUG(sc, "USB_ST_ERROR: %s",
+ usbd_errstr(usb_error));
+
+ goto tr_setup;
+ }
+}
+
+static void
+cfumass_t_data_in_callback(struct usb_xfer *xfer, usb_error_t usb_error)
+{
+ struct cfumass_softc *sc;
+ union ctl_io *io;
+ uint32_t max_bulk;
+ struct ctl_sg_entry ctl_sg_entry, *ctl_sglist;
+ int ctl_sg_count;
+
+ sc = usbd_xfer_softc(xfer);
+ max_bulk = usbd_xfer_max_len(xfer);
+
+ io = sc->sc_ctl_io;
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ CFUMASS_DEBUG(sc, "USB_ST_TRANSFERRED");
+
+ io->scsiio.be_move_done(io);
+ sc->sc_ctl_io = NULL;
+ break;
+
+ case USB_ST_SETUP:
+tr_setup:
+ CFUMASS_DEBUG(sc, "USB_ST_SETUP");
+
+ if (io->scsiio.kern_sg_entries > 0) {
+ ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
+ ctl_sg_count = io->scsiio.kern_sg_entries;
+ } else {
+ ctl_sglist = &ctl_sg_entry;
+ ctl_sglist->addr = io->scsiio.kern_data_ptr;
+ ctl_sglist->len = io->scsiio.kern_data_len;
+ ctl_sg_count = 1;
+ }
+
+ if (sc->sc_current_transfer_length > io->scsiio.kern_total_len) {
+ CFUMASS_DEBUG(sc, "initiator requested %d bytes, "
+ "we will send %ju and stall",
+ sc->sc_current_transfer_length,
+ (uintmax_t)io->scsiio.kern_total_len);
+ sc->sc_current_residue = sc->sc_current_transfer_length -
+ io->scsiio.kern_total_len;
+ } else {
+ sc->sc_current_residue = 0;
+ }
+
+ CFUMASS_DEBUG(sc, "max_bulk %d, requested size %d, "
+ "CTL segment size %zd", max_bulk,
+ sc->sc_current_transfer_length, ctl_sglist[0].len);
+
+ if (max_bulk >= ctl_sglist[0].len)
+ max_bulk = ctl_sglist[0].len;
+
+ usbd_xfer_set_frame_data(xfer, 0, ctl_sglist[0].addr, max_bulk);
+ usbd_transfer_submit(xfer);
+
+ break;
+
+ default:
+ if (usb_error == USB_ERR_CANCELLED) {
+ CFUMASS_DEBUG(sc, "USB_ERR_CANCELLED");
+ break;
+ }
+
+ CFUMASS_DEBUG(sc, "USB_ST_ERROR: %s", usbd_errstr(usb_error));
+
+ goto tr_setup;
+ }
+}
+
+static void
+cfumass_t_status_callback(struct usb_xfer *xfer, usb_error_t usb_error)
+{
+ struct cfumass_softc *sc;
+
+ sc = usbd_xfer_softc(xfer);
+
+ KASSERT(sc->sc_ctl_io == NULL,
+ ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ CFUMASS_DEBUG(sc, "USB_ST_TRANSFERRED");
+
+ cfumass_transfer_start(sc, CFUMASS_T_COMMAND);
+ break;
+
+ case USB_ST_SETUP:
+tr_setup:
+ CFUMASS_DEBUG(sc, "USB_ST_SETUP");
+
+ if (sc->sc_current_residue > 0 && !sc->sc_current_stalled) {
+ CFUMASS_DEBUG(sc, "non-zero residue, stalling");
+ usbd_xfer_set_stall(xfer);
+ sc->sc_current_stalled = true;
+ }
+
+ USETDW(sc->sc_csw->dCSWSignature, CSWSIGNATURE);
+ USETDW(sc->sc_csw->dCSWTag, sc->sc_current_tag);
+ USETDW(sc->sc_csw->dCSWDataResidue, sc->sc_current_residue);
+ sc->sc_csw->bCSWStatus = sc->sc_current_status;
+
+ usbd_xfer_set_frame_len(xfer, 0, sizeof(*sc->sc_csw));
+ usbd_transfer_submit(xfer);
+ break;
+
+ default:
+ if (usb_error == USB_ERR_CANCELLED) {
+ CFUMASS_DEBUG(sc, "USB_ERR_CANCELLED");
+ break;
+ }
+
+ CFUMASS_DEBUG(sc, "USB_ST_ERROR: %s",
+ usbd_errstr(usb_error));
+
+ goto tr_setup;
+ }
+}
+
+static void
+cfumass_online(void *arg __unused)
+{
+
+ cfumass_port_online = true;
+}
+
+static void
+cfumass_offline(void *arg __unused)
+{
+
+ cfumass_port_online = false;
+}
+
+static void
+cfumass_datamove(union ctl_io *io)
+{
+ struct cfumass_softc *sc;
+
+ sc = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
+
+ CFUMASS_DEBUG(sc, "go");
+
+ CFUMASS_LOCK(sc);
+
+ KASSERT(sc->sc_ctl_io == NULL,
+ ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
+ sc->sc_ctl_io = io;
+
+ if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
+ /*
+ * Verify that CTL wants us to send the data in the direction
+ * expected by the initiator.
+ */
+ if (sc->sc_current_flags != CBWFLAGS_IN) {
+ CFUMASS_WARN(sc, "wrong bCBWFlags 0x%x, should be 0x%x",
+ sc->sc_current_flags, CBWFLAGS_IN);
+ goto fail;
+ }
+
+ cfumass_transfer_start(sc, CFUMASS_T_DATA_IN);
+ } else {
+ if (sc->sc_current_flags != CBWFLAGS_OUT) {
+ CFUMASS_WARN(sc, "wrong bCBWFlags 0x%x, should be 0x%x",
+ sc->sc_current_flags, CBWFLAGS_OUT);
+ goto fail;
+ }
+
+ /* We hadn't received anything during this datamove yet. */
+ io->scsiio.ext_data_filled = 0;
+ cfumass_transfer_start(sc, CFUMASS_T_DATA_OUT);
+ }
+
+ CFUMASS_UNLOCK(sc);
+ return;
+
+fail:
+ ctl_set_data_phase_error(&io->scsiio);
+ io->scsiio.be_move_done(io);
+ sc->sc_ctl_io = NULL;
+}
+
+static void
+cfumass_done(union ctl_io *io)
+{
+ struct cfumass_softc *sc;
+
+ sc = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
+
+ CFUMASS_DEBUG(sc, "go");
+
+ KASSERT(((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE),
+ ("invalid CTL status %#x", io->io_hdr.status));
+ KASSERT(sc->sc_ctl_io == NULL,
+ ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
+
+ if (io->io_hdr.io_type == CTL_IO_TASK &&
+ io->taskio.task_action == CTL_TASK_I_T_NEXUS_RESET) {
+ /*
+ * Implicit task termination has just completed; nothing to do.
+ */
+ ctl_free_io(io);
+ return;
+ }
+
+ /*
+ * Do not return status for aborted commands.
+ * There are exceptions, but none supported by CTL yet.
+ */
+ if (((io->io_hdr.flags & CTL_FLAG_ABORT) &&
+ (io->io_hdr.flags & CTL_FLAG_ABORT_STATUS) == 0) ||
+ (io->io_hdr.flags & CTL_FLAG_STATUS_SENT)) {
+ ctl_free_io(io);
+ return;
+ }
+
+ switch (io->scsiio.scsi_status) {
+ case SCSI_STATUS_OK:
+ sc->sc_current_status = 0;
+ break;
+ default:
+ sc->sc_current_status = 1;
+ break;
+ }
+
+ CFUMASS_LOCK(sc);
+ cfumass_transfer_start(sc, CFUMASS_T_STATUS);
+ CFUMASS_UNLOCK(sc);
+ ctl_free_io(io);
+
+ refcount_release(&sc->sc_queued);
+}
+
+int
+cfumass_init(void)
+{
+ int error;
+
+ cfumass_port.frontend = &cfumass_frontend;
+ cfumass_port.port_type = CTL_PORT_UMASS;
+ /* XXX KDM what should the real number be here? */
+ cfumass_port.num_requested_ctl_io = 4096;
+ cfumass_port.port_name = "cfumass";
+ cfumass_port.physical_port = 0;
+ cfumass_port.virtual_port = 0;
+ cfumass_port.port_online = cfumass_online;
+ cfumass_port.port_offline = cfumass_offline;
+ cfumass_port.onoff_arg = NULL;
+ cfumass_port.fe_datamove = cfumass_datamove;
+ cfumass_port.fe_done = cfumass_done;
+ cfumass_port.targ_port = -1;
+
+ error = ctl_port_register(&cfumass_port);
+ if (error != 0) {
+ printf("%s: ctl_port_register() failed "
+ "with error %d", __func__, error);
+ }
+
+ cfumass_port_online = true;
+ refcount_init(&cfumass_refcount, 0);
+
+ return (error);
+}
+
+int
+cfumass_shutdown(void)
+{
+ int error;
+
+ if (cfumass_refcount > 0) {
+ if (debug > 1) {
+ printf("%s: still have %u attachments; "
+ "returning EBUSY\n", __func__, cfumass_refcount);
+ }
+ return (EBUSY);
+ }
+
+ error = ctl_port_deregister(&cfumass_port);
+ if (error != 0) {
+ printf("%s: ctl_port_deregister() failed "
+ "with error %d\n", __func__, error);
+ }
+
+ return (error);
+}
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index b04cc3cfc4d9..f4ae7e7c6b74 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -2582,10 +2582,10 @@ zyd_start(struct zyd_softc *sc)
while (sc->tx_nfree > 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (zyd_tx_start(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
m_freem(m);
if_inc_counter(ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
break;
}
}
diff --git a/sys/dev/vmware/vmxnet3/if_vmxvar.h b/sys/dev/vmware/vmxnet3/if_vmxvar.h
index 861351603e2b..7d7c80cb8865 100644
--- a/sys/dev/vmware/vmxnet3/if_vmxvar.h
+++ b/sys/dev/vmware/vmxnet3/if_vmxvar.h
@@ -131,7 +131,7 @@ struct vmxnet3_txq_stats {
struct vmxnet3_txqueue {
struct mtx vxtxq_mtx;
struct vmxnet3_softc *vxtxq_sc;
-#ifndef VMXNET3_TX_LEGACY
+#ifndef VMXNET3_LEGACY_TX
struct buf_ring *vxtxq_br;
#endif
int vxtxq_id;
@@ -142,7 +142,7 @@ struct vmxnet3_txqueue {
struct vmxnet3_txq_stats vxtxq_stats;
struct vmxnet3_txq_shared *vxtxq_ts;
struct sysctl_oid_list *vxtxq_sysctl;
-#ifndef VMXNET3_TX_LEGACY
+#ifndef VMXNET3_LEGACY_TX
struct task vxtxq_defrtask;
#endif
char vxtxq_name[16];
diff --git a/sys/dev/vx/if_vx.c b/sys/dev/vx/if_vx.c
index 08d84a64f286..a1ba239a7b9e 100644
--- a/sys/dev/vx/if_vx.c
+++ b/sys/dev/vx/if_vx.c
@@ -350,7 +350,7 @@ vx_setlink(struct vx_softc *sc)
*/
i = sc->vx_connector; /* default in EEPROM */
reason = "default";
- warning = 0;
+ warning = NULL;
if (ifp->if_flags & IFF_LINK0) {
if (sc->vx_connectors & conn_tab[CONNECTOR_AUI].bit) {
@@ -729,7 +729,7 @@ again:
/* Pull packet off interface. */
m = vx_get(sc, len);
- if (m == 0) {
+ if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto abort;
}
diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c
index 0b26847b399d..2e94ce76fa5d 100644
--- a/sys/dev/xen/timer/timer.c
+++ b/sys/dev/xen/timer/timer.c
@@ -417,8 +417,20 @@ xentimer_attach(device_t dev)
/* Register the timecounter. */
sc->tc.tc_name = "XENTIMER";
sc->tc.tc_quality = XENTIMER_QUALITY;
- sc->tc.tc_flags = TC_FLAGS_SUSPEND_SAFE;
/*
+ * FIXME: due to the lack of ordering during resume, FreeBSD cannot
+ * guarantee that the Xen PV timer is resumed before any other device
+ * attempts to make use of it, so mark it as not safe for suspension
+ * (ie: remove the TC_FLAGS_SUSPEND_SAFE flag).
+ *
+ * NB: This was not a problem in previous FreeBSD versions because the
+ * timer was directly attached to the nexus, but it is an issue now
+ * that the timer is attached to the xenpv bus, and thus resumed
+ * later.
+ *
+ * sc->tc.tc_flags = TC_FLAGS_SUSPEND_SAFE;
+ */
+ /*
* The underlying resolution is in nanoseconds, since the timer info
* scales TSC frequencies using a fraction that represents time in
* terms of nanoseconds.