static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, struct ieee80211_rann_ie *rann) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct mesh_path *mpath; u8 ttl, flags, hopcount; u8 *orig_addr; u32 orig_sn, metric; u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; bool root_is_gate; ttl = rann->rann_ttl; if (ttl <= 1) { ifmsh->mshstats.dropped_frames_ttl++; return; } ttl--; flags = rann->rann_flags; root_is_gate = !!(flags & RANN_FLAG_IS_GATE); orig_addr = rann->rann_addr; orig_sn = rann->rann_seq; hopcount = rann->rann_hopcount; hopcount++; metric = rann->rann_metric; /* Ignore our own RANNs */ if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) return; mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr, root_is_gate); rcu_read_lock(); mpath = mesh_path_lookup(orig_addr, sdata); if (!mpath) { mesh_path_add(orig_addr, sdata); mpath = mesh_path_lookup(orig_addr, sdata); if (!mpath) { rcu_read_unlock(); sdata->u.mesh.mshstats.dropped_frames_no_route++; return; } } if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || time_after(jiffies, mpath->exp_time - 1*HZ)) && !(mpath->flags & MESH_PATH_FIXED)) { mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, orig_addr); mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); } if (mpath->sn < orig_sn) { mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, cpu_to_le32(orig_sn), 0, NULL, 0, broadcast_addr, hopcount, ttl, cpu_to_le32(interval), cpu_to_le32(metric + mpath->metric), 0, sdata); mpath->sn = orig_sn; } if (root_is_gate) mesh_path_add_gate(mpath); rcu_read_unlock(); }
void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, int create_ino) { struct super_block *sb; struct ocfs2_super *osb; int use_plocks = 1; sb = inode->i_sb; osb = OCFS2_SB(sb); if ((osb->s_mount_opt & OCFS2_MOUNT_LOCALFLOCKS) || ocfs2_mount_local(osb) || !ocfs2_stack_supports_plocks()) use_plocks = 0; /* * These have all been checked by ocfs2_read_inode_block() or set * by ocfs2_mknod_locked(), so a failure is a code bug. */ BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); /* This means that read_inode cannot create a superblock inode today. change if that is needed. */ BUG_ON(!(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))); BUG_ON(le32_to_cpu(fe->i_fs_generation) != osb->fs_generation); OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features); inode->i_version = 1; inode->i_generation = le32_to_cpu(fe->i_generation); inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); inode->i_mode = le16_to_cpu(fe->i_mode); i_uid_write(inode, le32_to_cpu(fe->i_uid)); i_gid_write(inode, le32_to_cpu(fe->i_gid)); /* Fast symlinks will have i_size but no allocated clusters. */ if (S_ISLNK(inode->i_mode) && !fe->i_clusters) { inode->i_blocks = 0; inode->i_mapping->a_ops = &ocfs2_fast_symlink_aops; } else { inode->i_blocks = ocfs2_inode_sector_count(inode); inode->i_mapping->a_ops = &ocfs2_aops; } inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime); inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec); inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime); inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec); inode->i_ctime.tv_sec = le64_to_cpu(fe->i_ctime); inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec); if (OCFS2_I(inode)->ip_blkno != le64_to_cpu(fe->i_blkno)) mlog(ML_ERROR, "ip_blkno %llu != i_blkno %llu!\n", (unsigned long long)OCFS2_I(inode)->ip_blkno, (unsigned long long)le64_to_cpu(fe->i_blkno)); set_nlink(inode, ocfs2_read_links_count(fe)); trace_ocfs2_populate_inode(OCFS2_I(inode)->ip_blkno, le32_to_cpu(fe->i_flags)); if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) { OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE; inode->i_flags |= S_NOQUOTA; } if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) { OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; } else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) { OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP; } else if (fe->i_flags & cpu_to_le32(OCFS2_QUOTA_FL)) { inode->i_flags |= S_NOQUOTA; } else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) { /* we can't actually hit this as read_inode can't * handle superblocks today ;-) */ BUG(); } switch (inode->i_mode & S_IFMT) { case S_IFREG: if (use_plocks) inode->i_fop = &ocfs2_fops; else inode->i_fop = &ocfs2_fops_no_plocks; inode->i_op = &ocfs2_file_iops; i_size_write(inode, le64_to_cpu(fe->i_size)); break; case S_IFDIR: inode->i_op = &ocfs2_dir_iops; if (use_plocks) inode->i_fop = &ocfs2_dops; else inode->i_fop = &ocfs2_dops_no_plocks; i_size_write(inode, le64_to_cpu(fe->i_size)); OCFS2_I(inode)->ip_dir_lock_gen = 1; break; case S_IFLNK: inode->i_op = &ocfs2_symlink_inode_operations; i_size_write(inode, le64_to_cpu(fe->i_size)); break; default: inode->i_op = &ocfs2_special_file_iops; init_special_inode(inode, inode->i_mode, inode->i_rdev); break; } if (create_ino) { inode->i_ino = ino_from_blkno(inode->i_sb, le64_to_cpu(fe->i_blkno)); /* * If we ever want to create system files from kernel, * the generation argument to * ocfs2_inode_lock_res_init() will have to change. */ BUG_ON(le32_to_cpu(fe->i_flags) & OCFS2_SYSTEM_FL); ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_inode_lockres, OCFS2_LOCK_TYPE_META, 0, inode); ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_open_lockres, OCFS2_LOCK_TYPE_OPEN, 0, inode); } ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_rw_lockres, OCFS2_LOCK_TYPE_RW, inode->i_generation, inode); ocfs2_set_inode_flags(inode); OCFS2_I(inode)->ip_last_used_slot = 0; OCFS2_I(inode)->ip_last_used_group = 0; if (S_ISDIR(inode->i_mode)) ocfs2_resv_set_type(&OCFS2_I(inode)->ip_la_data_resv, OCFS2_RESV_FLAG_DIR); }
static int ocfs2_remove_inode(struct inode *inode, struct buffer_head *di_bh, struct inode *orphan_dir_inode, struct buffer_head *orphan_dir_bh) { int status; struct inode *inode_alloc_inode = NULL; struct buffer_head *inode_alloc_bh = NULL; handle_t *handle; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; inode_alloc_inode = ocfs2_get_system_file_inode(osb, INODE_ALLOC_SYSTEM_INODE, le16_to_cpu(di->i_suballoc_slot)); if (!inode_alloc_inode) { status = -EEXIST; mlog_errno(status); goto bail; } mutex_lock(&inode_alloc_inode->i_mutex); status = ocfs2_inode_lock(inode_alloc_inode, &inode_alloc_bh, 1); if (status < 0) { mutex_unlock(&inode_alloc_inode->i_mutex); mlog_errno(status); goto bail; } handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS + ocfs2_quota_trans_credits(inode->i_sb)); if (IS_ERR(handle)) { status = PTR_ERR(handle); mlog_errno(status); goto bail_unlock; } if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, orphan_dir_bh, false); if (status < 0) { mlog_errno(status); goto bail_commit; } } /* set the inodes dtime */ status = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) { mlog_errno(status); goto bail_commit; } di->i_dtime = cpu_to_le64(CURRENT_TIME.tv_sec); di->i_flags &= cpu_to_le32(~(OCFS2_VALID_FL | OCFS2_ORPHANED_FL)); ocfs2_journal_dirty(handle, di_bh); ocfs2_remove_from_cache(INODE_CACHE(inode), di_bh); dquot_free_inode(inode); status = ocfs2_free_dinode(handle, inode_alloc_inode, inode_alloc_bh, di); if (status < 0) mlog_errno(status); bail_commit: ocfs2_commit_trans(osb, handle); bail_unlock: ocfs2_inode_unlock(inode_alloc_inode, 1); mutex_unlock(&inode_alloc_inode->i_mutex); brelse(inode_alloc_bh); bail: iput(inode_alloc_inode); return status; }
/** * i40e_alloc_arq_bufs - Allocate pre-posted buffers for the receive queue * @hw: pointer to the hardware structure **/ static i40e_status i40e_alloc_arq_bufs(struct i40e_hw *hw) { i40e_status ret_code; struct i40e_aq_desc *desc; struct i40e_dma_mem *bi; int i; /* We'll be allocating the buffer info memory first, then we can * allocate the mapped buffers for the event processing */ /* buffer_info structures do not need alignment */ ret_code = i40e_allocate_virt_mem(hw, &hw->aq.arq.dma_head, (hw->aq.num_arq_entries * sizeof(struct i40e_dma_mem))); if (ret_code) goto alloc_arq_bufs; hw->aq.arq.r.arq_bi = (struct i40e_dma_mem *)hw->aq.arq.dma_head.va; /* allocate the mapped buffers */ for (i = 0; i < hw->aq.num_arq_entries; i++) { bi = &hw->aq.arq.r.arq_bi[i]; ret_code = i40e_allocate_dma_mem(hw, bi, i40e_mem_arq_buf, hw->aq.arq_buf_size, I40E_ADMINQ_DESC_ALIGNMENT); if (ret_code) goto unwind_alloc_arq_bufs; /* now configure the descriptors for use */ desc = I40E_ADMINQ_DESC(hw->aq.arq, i); desc->flags = cpu_to_le16(I40E_AQ_FLAG_BUF); if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF) desc->flags |= cpu_to_le16(I40E_AQ_FLAG_LB); desc->opcode = 0; /* This is in accordance with Admin queue design, there is no * register for buffer size configuration */ desc->datalen = cpu_to_le16((u16)bi->size); desc->retval = 0; desc->cookie_high = 0; desc->cookie_low = 0; desc->params.external.addr_high = cpu_to_le32(upper_32_bits(bi->pa)); desc->params.external.addr_low = cpu_to_le32(lower_32_bits(bi->pa)); desc->params.external.param0 = 0; desc->params.external.param1 = 0; } alloc_arq_bufs: return ret_code; unwind_alloc_arq_bufs: /* don't try to free the one that failed... */ i--; for (; i >= 0; i--) i40e_free_dma_mem(hw, &hw->aq.arq.r.arq_bi[i]); i40e_free_virt_mem(hw, &hw->aq.arq.dma_head); return ret_code; }
/** * i40e_clean_arq_element * @hw: pointer to the hw struct * @e: event info from the receive descriptor, includes any buffers * @pending: number of events that could be left to process * * This function cleans one Admin Receive Queue element and returns * the contents through e. It can also return how many events are * left to process through 'pending' **/ i40e_status i40e_clean_arq_element(struct i40e_hw *hw, struct i40e_arq_event_info *e, u16 *pending) { i40e_status ret_code = 0; u16 ntc = hw->aq.arq.next_to_clean; struct i40e_aq_desc *desc; struct i40e_dma_mem *bi; u16 desc_idx; u16 datalen; u16 flags; u16 ntu; /* pre-clean the event info */ memset(&e->desc, 0, sizeof(e->desc)); /* take the lock before we start messing with the ring */ mutex_lock(&hw->aq.arq_mutex); if (hw->aq.arq.count == 0) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: Admin queue not initialized.\n"); ret_code = I40E_ERR_QUEUE_EMPTY; goto clean_arq_element_err; } /* set next_to_use to head */ ntu = rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK; if (ntu == ntc) { /* nothing to do - shouldn't need to update ring's values */ ret_code = I40E_ERR_ADMIN_QUEUE_NO_WORK; goto clean_arq_element_out; } /* now clean the next descriptor */ desc = I40E_ADMINQ_DESC(hw->aq.arq, ntc); desc_idx = ntc; hw->aq.arq_last_status = (enum i40e_admin_queue_err)le16_to_cpu(desc->retval); flags = le16_to_cpu(desc->flags); if (flags & I40E_AQ_FLAG_ERR) { ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: Event received with error 0x%X.\n", hw->aq.arq_last_status); } e->desc = *desc; datalen = le16_to_cpu(desc->datalen); e->msg_len = min(datalen, e->buf_len); if (e->msg_buf != NULL && (e->msg_len != 0)) memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va, e->msg_len); i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf, hw->aq.arq_buf_size); /* Restore the original datalen and buffer address in the desc, * FW updates datalen to indicate the event message * size */ bi = &hw->aq.arq.r.arq_bi[ntc]; memset((void *)desc, 0, sizeof(struct i40e_aq_desc)); desc->flags = cpu_to_le16(I40E_AQ_FLAG_BUF); if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF) desc->flags |= cpu_to_le16(I40E_AQ_FLAG_LB); desc->datalen = cpu_to_le16((u16)bi->size); desc->params.external.addr_high = cpu_to_le32(upper_32_bits(bi->pa)); desc->params.external.addr_low = cpu_to_le32(lower_32_bits(bi->pa)); /* set tail = the last cleaned desc index. */ wr32(hw, hw->aq.arq.tail, ntc); /* ntc is updated to tail + 1 */ ntc++; if (ntc == hw->aq.num_arq_entries) ntc = 0; hw->aq.arq.next_to_clean = ntc; hw->aq.arq.next_to_use = ntu; i40e_nvmupd_check_wait_event(hw, le16_to_cpu(e->desc.opcode), &e->desc); clean_arq_element_out: /* Set pending if needed, unlock and return */ if (pending) *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc); clean_arq_element_err: mutex_unlock(&hw->aq.arq_mutex); return ret_code; }
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <linux/etherdevice.h> #include "rsi_mgmt.h" #include "rsi_common.h" static struct bootup_params boot_params_20 = { .magic_number = cpu_to_le16(0x5aa5), .crystal_good_time = 0x0, .valid = cpu_to_le32(VALID_20), .reserved_for_valids = 0x0, .bootup_mode_info = 0x0, .digital_loop_back_params = 0x0, .rtls_timestamp_en = 0x0, .host_spi_intr_cfg = 0x0, .device_clk_info = {{ .pll_config_g = { .tapll_info_g = { .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)| (TA_PLL_M_VAL_20)), .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_20), }, .pll960_info_g = { .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_20 << 8)| (PLL960_N_VAL_20)),
void _rt2880_drvMutexLock() { *(volatile u32 *)(RT2880_REG_INTDIS) = cpu_to_le32(0x8); return; };
/* * kmmpd will update the MMP sequence every s_mmp_update_interval seconds */ static int kmmpd(void *data) { struct super_block *sb = ((struct mmpd_data *) data)->sb; struct buffer_head *bh = ((struct mmpd_data *) data)->bh; struct ext4_super_block *es = EXT4_SB(sb)->s_es; struct mmp_struct *mmp; ext4_fsblk_t mmp_block; u32 seq = 0; unsigned long failed_writes = 0; int mmp_update_interval = le16_to_cpu(es->s_mmp_update_interval); unsigned mmp_check_interval; unsigned long last_update_time; unsigned long diff; int retval; mmp_block = le64_to_cpu(es->s_mmp_block); mmp = (struct mmp_struct *)(bh->b_data); mmp->mmp_time = cpu_to_le64(get_seconds()); /* * Start with the higher mmp_check_interval and reduce it if * the MMP block is being updated on time. */ mmp_check_interval = max(EXT4_MMP_CHECK_MULT * mmp_update_interval, EXT4_MMP_MIN_CHECK_INTERVAL); mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); bdevname(bh->b_bdev, mmp->mmp_bdevname); memcpy(mmp->mmp_nodename, init_utsname()->sysname, sizeof(mmp->mmp_nodename)); while (!kthread_should_stop()) { if (++seq > EXT4_MMP_SEQ_MAX) seq = 1; mmp->mmp_seq = cpu_to_le32(seq); mmp->mmp_time = cpu_to_le64(get_seconds()); last_update_time = jiffies; retval = write_mmp_block(bh); /* * Don't spew too many error messages. Print one every * (s_mmp_update_interval * 60) seconds. */ if (retval && (failed_writes % 60) == 0) { ext4_error(sb, "Error writing to MMP block"); failed_writes++; } if (!(le32_to_cpu(es->s_feature_incompat) & EXT4_FEATURE_INCOMPAT_MMP)) { ext4_warning(sb, "kmmpd being stopped since MMP feature" " has been disabled."); EXT4_SB(sb)->s_mmp_tsk = NULL; goto failed; } if (sb->s_flags & MS_RDONLY) { ext4_warning(sb, "kmmpd being stopped since filesystem " "has been remounted as readonly."); EXT4_SB(sb)->s_mmp_tsk = NULL; goto failed; } diff = jiffies - last_update_time; if (diff < mmp_update_interval * HZ) schedule_timeout_interruptible(mmp_update_interval * HZ - diff); /* * We need to make sure that more than mmp_check_interval * seconds have not passed since writing. If that has happened * we need to check if the MMP block is as we left it. */ diff = jiffies - last_update_time; if (diff > mmp_check_interval * HZ) { struct buffer_head *bh_check = NULL; struct mmp_struct *mmp_check; retval = read_mmp_block(sb, &bh_check, mmp_block); if (retval) { ext4_error(sb, "error reading MMP data: %d", retval); EXT4_SB(sb)->s_mmp_tsk = NULL; goto failed; } mmp_check = (struct mmp_struct *)(bh_check->b_data); if (mmp->mmp_seq != mmp_check->mmp_seq || memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename, sizeof(mmp->mmp_nodename))) { dump_mmp_msg(sb, mmp_check, "Error while updating MMP info. " "The filesystem seems to have been" " multiply mounted."); ext4_error(sb, "abort"); goto failed; } put_bh(bh_check); } /* * Adjust the mmp_check_interval depending on how much time * it took for the MMP block to be written. */ mmp_check_interval = max(min(EXT4_MMP_CHECK_MULT * diff / HZ, EXT4_MMP_MAX_CHECK_INTERVAL), EXT4_MMP_MIN_CHECK_INTERVAL); mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); } /* * Unmount seems to be clean. */ mmp->mmp_seq = cpu_to_le32(EXT4_MMP_SEQ_CLEAN); mmp->mmp_time = cpu_to_le64(get_seconds()); retval = write_mmp_block(bh); failed: kfree(data); brelse(bh); return retval; }
unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba, struct bsg_job *job, struct be_dma_mem *nonemb_cmd) { struct be_cmd_resp_hdr *resp; struct be_mcc_wrb *wrb = wrb_from_mccq(phba); struct be_sge *mcc_sge = nonembedded_sgl(wrb); unsigned int tag = 0; struct iscsi_bsg_request *bsg_req = job->request; struct be_bsg_vendor_cmd *req = nonemb_cmd->va; unsigned short region, sector_size, sector, offset; nonemb_cmd->size = job->request_payload.payload_len; memset(nonemb_cmd->va, 0, nonemb_cmd->size); resp = nonemb_cmd->va; region = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3]; offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4]; req->region = region; req->sector = sector; req->offset = offset; spin_lock(&ctrl->mbox_lock); memset(wrb, 0, sizeof(*wrb)); switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) { case BEISCSI_WRITE_FLASH: offset = sector * sector_size + offset; be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, OPCODE_COMMON_WRITE_FLASH, sizeof(*req)); sg_copy_to_buffer(job->request_payload.sg_list, job->request_payload.sg_cnt, nonemb_cmd->va + offset, job->request_len); break; case BEISCSI_READ_FLASH: be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, OPCODE_COMMON_READ_FLASH, sizeof(*req)); break; default: shost_printk(KERN_WARNING, phba->shost, "Unsupported cmd = 0x%x\n\n", bsg_req->rqst_data. h_vendor.vendor_cmd[0]); spin_unlock(&ctrl->mbox_lock); return -ENOSYS; } tag = alloc_mcc_tag(phba); if (!tag) { spin_unlock(&ctrl->mbox_lock); return tag; } be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, job->request_payload.sg_cnt); mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); mcc_sge->len = cpu_to_le32(nonemb_cmd->size); wrb->tag0 |= tag; be_mcc_notify(phba); spin_unlock(&ctrl->mbox_lock); return tag; }
/** * gserial_setup - initialize TTY driver for one or more ports * @g: gadget to associate with these ports * @count: how many ports to support * Context: may sleep * * The TTY stack needs to know in advance how many devices it should * plan to manage. Use this call to set up the ports you will be * exporting through USB. Later, connect them to functions based * on what configuration is activated by the USB host; and disconnect * them as appropriate. * * An example would be a two-configuration device in which both * configurations expose port 0, but through different functions. * One configuration could even expose port 1 while the other * one doesn't. * * Returns negative errno or zero. */ int gserial_setup(struct usb_gadget *g, unsigned count) { unsigned i; struct usb_cdc_line_coding coding; int status; if (count == 0 || count > N_PORTS) return -EINVAL; gs_tty_driver = alloc_tty_driver(count); if (!gs_tty_driver) return -ENOMEM; gs_tty_driver->owner = THIS_MODULE; gs_tty_driver->driver_name = "g_serial"; gs_tty_driver->name = PREFIX; /* uses dynamically assigned dev_t values */ gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; gs_tty_driver->init_termios = tty_std_termios; /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on * MS-Windows. Otherwise, most of these flags shouldn't affect * anything unless we were to actually hook up to a serial line. */ gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; gs_tty_driver->init_termios.c_ispeed = 9600; gs_tty_driver->init_termios.c_ospeed = 9600; coding.dwDTERate = cpu_to_le32(9600); coding.bCharFormat = 8; coding.bParityType = USB_CDC_NO_PARITY; coding.bDataBits = USB_CDC_1_STOP_BITS; tty_set_operations(gs_tty_driver, &gs_tty_ops); gserial_wq = create_singlethread_workqueue("k_gserial"); if (!gserial_wq) { status = -ENOMEM; goto fail; } /* make devices be openable */ for (i = 0; i < count; i++) { mutex_init(&ports[i].lock); status = gs_port_alloc(i, &coding); if (status) { count = i; goto fail; } } n_ports = count; /* export the driver ... */ status = tty_register_driver(gs_tty_driver); if (status) { put_tty_driver(gs_tty_driver); pr_err("%s: cannot register, err %d\n", __func__, status); goto fail; } /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */ for (i = 0; i < count; i++) { struct device *tty_dev; tty_dev = tty_register_device(gs_tty_driver, i, &g->dev); if (IS_ERR(tty_dev)) pr_warning("%s: no classdev for port %d, err %ld\n", __func__, i, PTR_ERR(tty_dev)); } for (i = 0; i < count; i++) usb_debugfs_init(ports[i].port, i); pr_debug("%s: registered %d ttyGS* device%s\n", __func__, count, (count == 1) ? "" : "s"); return status; fail: while (count--) kfree(ports[count].port); if (gserial_wq) destroy_workqueue(gserial_wq); put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; return status; }
/* * Protect the filesystem from being mounted more than once. */ int ext4_multi_mount_protect(struct super_block *sb, ext4_fsblk_t mmp_block) { struct ext4_super_block *es = EXT4_SB(sb)->s_es; struct buffer_head *bh = NULL; struct mmp_struct *mmp = NULL; struct mmpd_data *mmpd_data; u32 seq; unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval); unsigned int wait_time = 0; int retval; if (mmp_block < le32_to_cpu(es->s_first_data_block) || mmp_block >= ext4_blocks_count(es)) { ext4_warning(sb, "Invalid MMP block in superblock"); goto failed; } retval = read_mmp_block(sb, &bh, mmp_block); if (retval) goto failed; mmp = (struct mmp_struct *)(bh->b_data); if (mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL) mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL; /* * If check_interval in MMP block is larger, use that instead of * update_interval from the superblock. */ if (le16_to_cpu(mmp->mmp_check_interval) > mmp_check_interval) mmp_check_interval = le16_to_cpu(mmp->mmp_check_interval); seq = le32_to_cpu(mmp->mmp_seq); if (seq == EXT4_MMP_SEQ_CLEAN) goto skip; if (seq == EXT4_MMP_SEQ_FSCK) { dump_mmp_msg(sb, mmp, "fsck is running on the filesystem"); goto failed; } wait_time = min(mmp_check_interval * 2 + 1, mmp_check_interval + 60); /* Print MMP interval if more than 20 secs. */ if (wait_time > EXT4_MMP_MIN_CHECK_INTERVAL * 4) ext4_warning(sb, "MMP interval %u higher than expected, please" " wait.\n", wait_time * 2); if (schedule_timeout_interruptible(HZ * wait_time) != 0) { ext4_warning(sb, "MMP startup interrupted, failing mount\n"); goto failed; } retval = read_mmp_block(sb, &bh, mmp_block); if (retval) goto failed; mmp = (struct mmp_struct *)(bh->b_data); if (seq != le32_to_cpu(mmp->mmp_seq)) { dump_mmp_msg(sb, mmp, "Device is already active on another node."); goto failed; } skip: /* * write a new random sequence number. */ mmp->mmp_seq = seq = cpu_to_le32(mmp_new_seq()); retval = write_mmp_block(bh); if (retval) goto failed; /* * wait for MMP interval and check mmp_seq. */ if (schedule_timeout_interruptible(HZ * wait_time) != 0) { ext4_warning(sb, "MMP startup interrupted, failing mount\n"); goto failed; } retval = read_mmp_block(sb, &bh, mmp_block); if (retval) goto failed; mmp = (struct mmp_struct *)(bh->b_data); if (seq != le32_to_cpu(mmp->mmp_seq)) { dump_mmp_msg(sb, mmp, "Device is already active on another node."); goto failed; } mmpd_data = kmalloc(sizeof(struct mmpd_data), GFP_KERNEL); if (!mmpd_data) { ext4_warning(sb, "not enough memory for mmpd_data"); goto failed; } mmpd_data->sb = sb; mmpd_data->bh = bh; /* * Start a kernel thread to update the MMP block periodically. */ EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%s", bdevname(bh->b_bdev, mmp->mmp_bdevname)); if (IS_ERR(EXT4_SB(sb)->s_mmp_tsk)) { EXT4_SB(sb)->s_mmp_tsk = NULL; kfree(mmpd_data); ext4_warning(sb, "Unable to create kmmpd thread for %s.", sb->s_id); goto failed; } return 0; failed: brelse(bh); return 1; }
static int lab4fs_fill_super(struct super_block * sb, void * data, int silent) { struct buffer_head * bh; int blocksize = BLOCK_SIZE; unsigned long logic_sb_block; unsigned offset = 0; unsigned long sb_block = 1; struct lab4fs_super_block *es; struct lab4fs_sb_info *sbi; struct inode *root; int hblock; int err = 0; sbi = kmalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) return -ENOMEM; sb->s_fs_info = sbi; memset(sbi, 0, sizeof(*sbi)); blocksize = sb_min_blocksize(sb, BLOCK_SIZE); if (!blocksize) { LAB4ERROR("unable to set blocksize\n"); err = -EIO; goto out_fail; } /* * If the superblock doesn't start on a hardware sector boundary, * calculate the offset. */ if (blocksize != BLOCK_SIZE) { logic_sb_block = (sb_block * BLOCK_SIZE) / blocksize; offset = (sb_block * BLOCK_SIZE) % blocksize; } else { logic_sb_block = sb_block; } if (!(bh = sb_bread(sb, logic_sb_block))) { LAB4ERROR("unable to read super block\n"); goto out_fail; } es = (struct lab4fs_super_block *) (((char *)bh->b_data) + offset); sb->s_magic = le32_to_cpu(es->s_magic); if (sb->s_magic != LAB4FS_SUPER_MAGIC) { if (!silent) LAB4ERROR("VFS: Can't find lab4fs filesystem on dev %s.\n", sb->s_id); goto failed_mount; } sbi->s_sb = es; blocksize = le32_to_cpu(es->s_block_size); hblock = bdev_hardsect_size(sb->s_bdev); if (sb->s_blocksize != blocksize) { /* * Make sure the blocksize for the filesystem is larger * than the hardware sectorsize for the machine. */ if (blocksize < hblock) { LAB4ERROR("blocksize %d too small for " "device blocksize %d.\n", blocksize, hblock); goto failed_mount; } brelse (bh); sb_set_blocksize(sb, blocksize); logic_sb_block = (sb_block * BLOCK_SIZE) / blocksize; offset = (sb_block * BLOCK_SIZE) % blocksize; bh = sb_bread(sb, logic_sb_block); if (!bh) { LAB4ERROR("Can't read superblock on 2nd try.\n"); goto failed_mount; } es = (struct lab4fs_super_block *)(((char *)bh->b_data) + offset); sbi->s_sb = es; if (es->s_magic != cpu_to_le32(LAB4FS_SUPER_MAGIC)) { LAB4ERROR("Magic mismatch, very weird !\n"); goto failed_mount; } } sb->s_maxbytes = lab4fs_max_size(es); sbi->s_sbh = bh; sbi->s_log_block_size = log2(sb->s_blocksize); sbi->s_first_ino = le32_to_cpu(es->s_first_inode); sbi->s_inode_size = le32_to_cpu(es->s_inode_size); sbi->s_log_inode_size = log2(sbi->s_inode_size); sbi->s_inode_table = le32_to_cpu(es->s_inode_table); sbi->s_data_blocks = le32_to_cpu(es->s_data_blocks); sbi->s_next_generation = 0; sbi->s_free_inodes_count = le32_to_cpu(es->s_free_inodes_count); sbi->s_free_data_blocks_count = le32_to_cpu(es->s_free_data_blocks_count); sbi->s_inodes_count = le32_to_cpu(es->s_inodes_count); sbi->s_blocks_count = le32_to_cpu(es->s_blocks_count); sbi->s_inode_bitmap.nr_valid_bits = le32_to_cpu(es->s_inodes_count); sbi->s_data_bitmap.nr_valid_bits = le32_to_cpu(es->s_blocks_count) - le32_to_cpu(es->s_data_blocks); rwlock_init(&sbi->rwlock); sb->s_op = &lab4fs_super_ops; err = bitmap_setup(&sbi->s_inode_bitmap, sb, le32_to_cpu(es->s_inode_bitmap)); if (err) goto out_fail; err = bitmap_setup(&sbi->s_data_bitmap, sb, le32_to_cpu(es->s_data_bitmap)); if (err) goto out_fail; sbi->s_root_inode = le32_to_cpu(es->s_root_inode); root = iget(sb, sbi->s_root_inode); LAB4DEBUG("I can get the root inode\n"); print_inode(root); LAB4DEBUG("END\n"); sb->s_root = d_alloc_root(root); if (!sb->s_root) { iput(root); kfree(sbi); return -ENOMEM; } return 0; failed_mount: out_fail: kfree(sbi); return err; }
static void make_config(struct dlm_ls *ls, struct rcom_config *rf) { rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen); rf->rf_lsflags = cpu_to_le32(ls->ls_exflags); }
static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; PSTxDesc head_td; u32 dma_idx; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); if (ieee80211_is_data(hdr->frame_control)) dma_idx = TYPE_AC0DMA; else dma_idx = TYPE_TXDMA0; if (AVAIL_TD(priv, dma_idx) < 1) { spin_unlock_irqrestore(&priv->lock, flags); return -ENOMEM; } head_td = priv->apCurrTD[dma_idx]; head_td->m_td1TD1.byTCR = 0; head_td->pTDInfo->skb = skb; if (dma_idx == TYPE_AC0DMA) head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; priv->apCurrTD[dma_idx] = head_td->next; spin_unlock_irqrestore(&priv->lock, flags); vnt_generate_fifo_header(priv, dma_idx, head_td, skb); if (MACbIsRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) MACbPSWakeup(priv->PortOffset); spin_lock_irqsave(&priv->lock, flags); priv->bPWBitOn = false; /* Set TSR1 & ReqCount in TxDescHead */ head_td->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); head_td->m_td1TD1.wReqCount = cpu_to_le16((u16)head_td->pTDInfo->dwReqCount); head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma); /* Poll Transmit the adapter */ wmb(); head_td->m_td0TD0.f1Owner = OWNED_BY_NIC; wmb(); /* second memory barrier */ if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) MACvTransmitAC0(priv->PortOffset); else MACvTransmit0(priv->PortOffset); priv->iTDUsed[dma_idx]++; spin_unlock_irqrestore(&priv->lock, flags); return 0; }
int init_initiator_midpath_unsolicited_fcoe_task( struct fcoe_task_params *task_params, struct fcoe_tx_mid_path_params *mid_path_fc_header, struct scsi_sgl_task_params *tx_sgl_task_params, struct scsi_sgl_task_params *rx_sgl_task_params, u8 fw_to_place_fc_header) { struct e4_fcoe_task_context *ctx = task_params->context; const u8 val_byte = ctx->ystorm_ag_context.byte0; struct e4_ustorm_fcoe_task_ag_ctx *u_ag_ctx; struct ystorm_fcoe_task_st_ctx *y_st_ctx; struct tstorm_fcoe_task_st_ctx *t_st_ctx; struct mstorm_fcoe_task_st_ctx *m_st_ctx; u32 val; memset(ctx, 0, sizeof(*(ctx))); ctx->ystorm_ag_context.byte0 = val_byte; /* Init Ystorm */ y_st_ctx = &ctx->ystorm_st_context; init_scsi_sgl_context(&y_st_ctx->sgl_params, &y_st_ctx->data_desc, tx_sgl_task_params); SET_FIELD(y_st_ctx->sgl_mode, YSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE, SCSI_FAST_SGL); y_st_ctx->data_2_trns_rem = cpu_to_le32(task_params->tx_io_size); y_st_ctx->task_type = (u8)task_params->task_type; memcpy(&y_st_ctx->tx_info_union.tx_params.mid_path, mid_path_fc_header, sizeof(struct fcoe_tx_mid_path_params)); /* Init Mstorm */ m_st_ctx = &ctx->mstorm_st_context; init_scsi_sgl_context(&m_st_ctx->sgl_params, &m_st_ctx->data_desc, rx_sgl_task_params); SET_FIELD(m_st_ctx->flags, MSTORM_FCOE_TASK_ST_CTX_MP_INCLUDE_FC_HEADER, fw_to_place_fc_header); m_st_ctx->data_2_trns_rem = cpu_to_le32(task_params->rx_io_size); /* Init Tstorm */ t_st_ctx = &ctx->tstorm_st_context; t_st_ctx->read_only.cid = cpu_to_le32(task_params->conn_cid); val = cpu_to_le32(task_params->cq_rss_number); t_st_ctx->read_only.glbl_q_num = val; t_st_ctx->read_only.task_type = (u8)task_params->task_type; SET_FIELD(t_st_ctx->read_write.flags, FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_EXP_FIRST_FRAME, 1); t_st_ctx->read_write.rx_id = cpu_to_le16(FCOE_RX_ID); /* Init Ustorm */ u_ag_ctx = &ctx->ustorm_ag_context; u_ag_ctx->global_cq_num = cpu_to_le32(task_params->cq_rss_number); /* Init SQE */ init_common_sqe(task_params, SEND_FCOE_MIDPATH); task_params->sqe->additional_info_union.burst_length = tx_sgl_task_params->total_buffer_size; SET_FIELD(task_params->sqe->flags, FCOE_WQE_NUM_SGES, tx_sgl_task_params->num_sges); SET_FIELD(task_params->sqe->flags, FCOE_WQE_SGL_MODE, SCSI_FAST_SGL); return 0; }
static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) { struct iwl_bt_iterator_data data = { .mvm = mvm, .notif = &mvm->last_bt_notif, }; struct iwl_bt_coex_ci_cmd cmd = {}; u8 ci_bw_idx; /* Ignore updates if we are in force mode */ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) return; rcu_read_lock(); ieee80211_iterate_active_interfaces_atomic( mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_bt_notif_iterator, &data); iwl_mvm_bt_coex_tcm_based_ci(mvm, &data); if (data.primary) { struct ieee80211_chanctx_conf *chan = data.primary; if (WARN_ON(!chan->def.chan)) { rcu_read_unlock(); return; } if (chan->def.width < NL80211_CHAN_WIDTH_40) { ci_bw_idx = 0; } else { if (chan->def.center_freq1 > chan->def.chan->center_freq) ci_bw_idx = 2; else ci_bw_idx = 1; } cmd.bt_primary_ci = iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; cmd.primary_ch_phy_id = cpu_to_le32(*((u16 *)data.primary->drv_priv)); } if (data.secondary) { struct ieee80211_chanctx_conf *chan = data.secondary; if (WARN_ON(!data.secondary->def.chan)) { rcu_read_unlock(); return; } if (chan->def.width < NL80211_CHAN_WIDTH_40) { ci_bw_idx = 0; } else { if (chan->def.center_freq1 > chan->def.chan->center_freq) ci_bw_idx = 2; else ci_bw_idx = 1; } cmd.bt_secondary_ci = iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; cmd.secondary_ch_phy_id = cpu_to_le32(*((u16 *)data.secondary->drv_priv)); } rcu_read_unlock(); /* Don't spam the fw with the same command over and over */ if (memcmp(&cmd, &mvm->last_bt_ci_cmd, sizeof(cmd))) { if (iwl_mvm_send_cmd_pdu(mvm, BT_COEX_CI, 0, sizeof(cmd), &cmd)) IWL_ERR(mvm, "Failed to send BT_CI cmd\n"); memcpy(&mvm->last_bt_ci_cmd, &cmd, sizeof(cmd)); } } void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n", le32_to_cpu(notif->primary_ch_lut)); IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n", le32_to_cpu(notif->secondary_ch_lut)); IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n", le32_to_cpu(notif->bt_activity_grading)); /* remember this notification for future use: rssi fluctuations */ memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); iwl_mvm_bt_coex_notif_handle(mvm); } void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, enum ieee80211_rssi_event_data rssi_event) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); int ret; lockdep_assert_held(&mvm->mutex); /* Ignore updates if we are in force mode */ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) return; /* * Rssi update while not associated - can happen since the statistics * are handled asynchronously */ if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA) return; /* No BT - reports should be disabled */ if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF) return; IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW"); /* * Check if rssi is good enough for reduced Tx power, but not in loose * scheme. */ if (rssi_event == RSSI_EVENT_LOW || mvm->cfg->bt_shared_single_ant || iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT) ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false); else ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true); if (ret) IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n"); } #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) #define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm, struct ieee80211_sta *sta) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt; enum iwl_bt_coex_lut_type lut_type; if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) return LINK_QUAL_AGG_TIME_LIMIT_DEF; if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < BT_HIGH_TRAFFIC) return LINK_QUAL_AGG_TIME_LIMIT_DEF; lut_type = iwl_get_coex_type(mvm, mvmsta->vif); if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT) return LINK_QUAL_AGG_TIME_LIMIT_DEF; /* tight coex, high bt traffic, reduce AGG time limit */ return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT; } bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, struct ieee80211_sta *sta) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt; enum iwl_bt_coex_lut_type lut_type; if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id)) return true; if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < BT_HIGH_TRAFFIC) return true; /* * In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas * since BT is already killed. * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while * we Tx. * When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO. */ lut_type = iwl_get_coex_type(mvm, mvmsta->vif); return lut_type != BT_COEX_LOOSE_LUT; } bool iwl_mvm_bt_coex_is_ant_avail(struct iwl_mvm *mvm, u8 ant) { /* there is no other antenna, shared antenna is always available */ if (mvm->cfg->bt_shared_single_ant) return true; if (ant & mvm->cfg->non_shared_ant) return true; return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < BT_HIGH_TRAFFIC; } bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm) { /* there is no other antenna, shared antenna is always available */ if (mvm->cfg->bt_shared_single_ant) return true; return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < BT_HIGH_TRAFFIC; } bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm, enum nl80211_band band) { u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); if (band != NL80211_BAND_2GHZ) return false; return bt_activity >= BT_LOW_TRAFFIC; }
int init_initiator_rw_fcoe_task(struct fcoe_task_params *task_params, struct scsi_sgl_task_params *sgl_task_params, struct regpair sense_data_buffer_phys_addr, u32 task_retry_id, u8 fcp_cmd_payload[32]) { struct e4_fcoe_task_context *ctx = task_params->context; const u8 val_byte = ctx->ystorm_ag_context.byte0; struct e4_ustorm_fcoe_task_ag_ctx *u_ag_ctx; struct ystorm_fcoe_task_st_ctx *y_st_ctx; struct tstorm_fcoe_task_st_ctx *t_st_ctx; struct mstorm_fcoe_task_st_ctx *m_st_ctx; u32 io_size, val; bool slow_sgl; memset(ctx, 0, sizeof(*(ctx))); ctx->ystorm_ag_context.byte0 = val_byte; slow_sgl = scsi_is_slow_sgl(sgl_task_params->num_sges, sgl_task_params->small_mid_sge); io_size = (task_params->task_type == FCOE_TASK_TYPE_WRITE_INITIATOR ? task_params->tx_io_size : task_params->rx_io_size); /* Ystorm ctx */ y_st_ctx = &ctx->ystorm_st_context; y_st_ctx->data_2_trns_rem = cpu_to_le32(io_size); y_st_ctx->task_rety_identifier = cpu_to_le32(task_retry_id); y_st_ctx->task_type = (u8)task_params->task_type; memcpy(&y_st_ctx->tx_info_union.fcp_cmd_payload, fcp_cmd_payload, sizeof(struct fcoe_fcp_cmd_payload)); /* Tstorm ctx */ t_st_ctx = &ctx->tstorm_st_context; t_st_ctx->read_only.dev_type = (u8)(task_params->is_tape_device == 1 ? FCOE_TASK_DEV_TYPE_TAPE : FCOE_TASK_DEV_TYPE_DISK); t_st_ctx->read_only.cid = cpu_to_le32(task_params->conn_cid); val = cpu_to_le32(task_params->cq_rss_number); t_st_ctx->read_only.glbl_q_num = val; t_st_ctx->read_only.fcp_cmd_trns_size = cpu_to_le32(io_size); t_st_ctx->read_only.task_type = (u8)task_params->task_type; SET_FIELD(t_st_ctx->read_write.flags, FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_EXP_FIRST_FRAME, 1); t_st_ctx->read_write.rx_id = cpu_to_le16(FCOE_RX_ID); /* Ustorm ctx */ u_ag_ctx = &ctx->ustorm_ag_context; u_ag_ctx->global_cq_num = cpu_to_le32(task_params->cq_rss_number); /* Mstorm buffer for sense/rsp data placement */ m_st_ctx = &ctx->mstorm_st_context; val = cpu_to_le32(sense_data_buffer_phys_addr.hi); m_st_ctx->rsp_buf_addr.hi = val; val = cpu_to_le32(sense_data_buffer_phys_addr.lo); m_st_ctx->rsp_buf_addr.lo = val; if (task_params->task_type == FCOE_TASK_TYPE_WRITE_INITIATOR) { /* Ystorm ctx */ y_st_ctx->expect_first_xfer = 1; /* Set the amount of super SGEs. Can be up to 4. */ SET_FIELD(y_st_ctx->sgl_mode, YSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE, (slow_sgl ? SCSI_TX_SLOW_SGL : SCSI_FAST_SGL)); init_scsi_sgl_context(&y_st_ctx->sgl_params, &y_st_ctx->data_desc, sgl_task_params); /* Mstorm ctx */ SET_FIELD(m_st_ctx->flags, MSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE, (slow_sgl ? SCSI_TX_SLOW_SGL : SCSI_FAST_SGL)); m_st_ctx->sgl_params.sgl_num_sges = cpu_to_le16(sgl_task_params->num_sges); } else { /* Tstorm ctx */ SET_FIELD(t_st_ctx->read_write.flags, FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_RX_SGL_MODE, (slow_sgl ? SCSI_TX_SLOW_SGL : SCSI_FAST_SGL)); /* Mstorm ctx */ m_st_ctx->data_2_trns_rem = cpu_to_le32(io_size); init_scsi_sgl_context(&m_st_ctx->sgl_params, &m_st_ctx->data_desc, sgl_task_params); } /* Init Sqe */ init_common_sqe(task_params, SEND_FCOE_CMD); return 0; }
static void _iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf, struct iwl_rxon_context *ctx) { struct iwl_rxon_cmd *rxon = &ctx->staging; if (!ctx->ht.enabled) { rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK | RXON_FLG_HT_PROT_MSK); return; } /* FIXME: if the definition of ht.protection changed, the "translation" * will be needed for rxon->flags */ rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); /* Set up channel bandwidth: * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ /* clear the HT channel mode before set the mode */ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) { /* pure ht40 */ if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; /* Note: control channel is opposite of extension channel */ switch (ctx->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; break; case IEEE80211_HT_PARAM_CHA_SEC_BELOW: rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; break; } } else { /* Note: control channel is opposite of extension channel */ switch (ctx->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; break; case IEEE80211_HT_PARAM_CHA_SEC_BELOW: rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; break; case IEEE80211_HT_PARAM_CHA_SEC_NONE: default: /* channel location only valid if in Mixed mode */ IWL_ERR(priv, "invalid extension channel offset\n"); break; } } } else { rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; } iwlagn_set_rxon_chain(priv, ctx); IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags), ctx->ht.protection, ctx->ht.extension_chan_offset); }
int musb_hub_control( struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct musb *musb = hcd_to_musb(hcd); u32 temp; int retval = 0; unsigned long flags; spin_lock_irqsave(&musb->lock, flags); if (unlikely(!HCD_HW_ACCESSIBLE(hcd))) { spin_unlock_irqrestore(&musb->lock, flags); return -ESHUTDOWN; } /* hub features: always zero, setting is a NOP * port features: reported, sometimes updated when host is active * no indicators */ switch (typeReq) { case ClearHubFeature: case SetHubFeature: switch (wValue) { case C_HUB_OVER_CURRENT: case C_HUB_LOCAL_POWER: break; default: goto error; } break; case ClearPortFeature: if ((wIndex & 0xff) != 1) goto error; switch (wValue) { case USB_PORT_FEAT_ENABLE: break; case USB_PORT_FEAT_SUSPEND: musb_port_suspend(musb, false); break; case USB_PORT_FEAT_POWER: if (!hcd->self.is_b_host) musb_platform_set_vbus(musb, 0); break; case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_ENABLE: case USB_PORT_FEAT_C_OVER_CURRENT: case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_SUSPEND: break; default: goto error; } dev_dbg(musb->controller, "clear feature %d\n", wValue); musb->port1_status &= ~(1 << wValue); break; case GetHubDescriptor: { struct usb_hub_descriptor *desc = (void *)buf; desc->bDescLength = 9; desc->bDescriptorType = 0x29; desc->bNbrPorts = 1; desc->wHubCharacteristics = cpu_to_le16( 0x0001 /* per-port power switching */ | 0x0010 /* no overcurrent reporting */ ); desc->bPwrOn2PwrGood = 5; /* msec/2 */ desc->bHubContrCurrent = 0; /* workaround bogus struct definition */ desc->u.hs.DeviceRemovable[0] = 0x02; /* port 1 */ desc->u.hs.DeviceRemovable[1] = 0xff; } break; case GetHubStatus: temp = 0; *(__le32 *) buf = cpu_to_le32(temp); break; case GetPortStatus: if (wIndex != 1) goto error; /* finish RESET signaling? */ if ((musb->port1_status & USB_PORT_STAT_RESET) && time_after_eq(jiffies, musb->rh_timer)) musb_port_reset(musb, false); /* finish RESUME signaling? */ if ((musb->port1_status & MUSB_PORT_STAT_RESUME) && time_after_eq(jiffies, musb->rh_timer)) { u8 power; power = musb_readb(musb->mregs, MUSB_POWER); power &= ~MUSB_POWER_RESUME; dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power); musb_writeb(musb->mregs, MUSB_POWER, power); /* ISSUE: DaVinci (RTL 1.300) disconnects after * resume of high speed peripherals (but not full * speed ones). */ musb->is_active = 1; musb->port1_status &= ~(USB_PORT_STAT_SUSPEND | MUSB_PORT_STAT_RESUME); musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; usb_hcd_poll_rh_status(musb_to_hcd(musb)); /* NOTE: it might really be A_WAIT_BCON ... */ musb->xceiv->state = OTG_STATE_A_HOST; } put_unaligned(cpu_to_le32(musb->port1_status & ~MUSB_PORT_STAT_RESUME), (__le32 *) buf); /* port change status is more interesting */ dev_dbg(musb->controller, "port status %08x\n", musb->port1_status); break; case SetPortFeature: if ((wIndex & 0xff) != 1) goto error; switch (wValue) { case USB_PORT_FEAT_POWER: /* NOTE: this controller has a strange state machine * that involves "requesting sessions" according to * magic side effects from incompletely-described * rules about startup... * * This call is what really starts the host mode; be * very careful about side effects if you reorder any * initialization logic, e.g. for OTG, or change any * logic relating to VBUS power-up. */ if (!hcd->self.is_b_host) musb_start(musb); break; case USB_PORT_FEAT_RESET: musb_port_reset(musb, true); break; case USB_PORT_FEAT_SUSPEND: musb_port_suspend(musb, true); break; case USB_PORT_FEAT_TEST: if (unlikely(is_host_active(musb))) goto error; wIndex >>= 8; switch (wIndex) { case 1: pr_debug("TEST_J\n"); temp = MUSB_TEST_J; break; case 2: pr_debug("TEST_K\n"); temp = MUSB_TEST_K; break; case 3: pr_debug("TEST_SE0_NAK\n"); temp = MUSB_TEST_SE0_NAK; break; case 4: pr_debug("TEST_PACKET\n"); temp = MUSB_TEST_PACKET; musb_load_testpacket(musb); break; case 5: pr_debug("TEST_FORCE_ENABLE\n"); temp = MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_HS; musb_writeb(musb->mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); break; case 6: pr_debug("TEST_FIFO_ACCESS\n"); temp = MUSB_TEST_FIFO_ACCESS; break; default: goto error; } musb_writeb(musb->mregs, MUSB_TESTMODE, temp); break; default: goto error; } dev_dbg(musb->controller, "set feature %d\n", wValue); musb->port1_status |= 1 << wValue; break; default: error: /* "protocol stall" on error */ retval = -EPIPE; } spin_unlock_irqrestore(&musb->lock, flags); return retval; }
s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) { PADAPTER padapter; struct dvobj_priv *psdiodev; PSDIO_DATA psdio; u8 bMacPwrCtrlOn; u8 deviceId; u16 offset; u32 ftaddr; u8 shift; s32 err; _func_enter_; padapter = pintfhdl->padapter; psdiodev = pintfhdl->pintf_dev; psdio = &psdiodev->intf_data; err = 0; ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || (_FALSE == bMacPwrCtrlOn) #ifdef CONFIG_LPS_LCLK || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode) #endif ) { val = cpu_to_le32(val); err = sd_cmd52_write(psdio, ftaddr, 4, (u8*)&val); return err; } // 4 bytes alignment shift = ftaddr & 0x3; #if 1 if (shift == 0) { sd_write32(psdio, ftaddr, val, &err); } else { val = cpu_to_le32(val); err = sd_cmd52_write(psdio, ftaddr, 4, (u8*)&val); } #else if (shift == 0) { sd_write32(psdio, ftaddr, val, &err); } else { u8 *ptmpbuf; ptmpbuf = (u8*)rtw_malloc(8); if (NULL == ptmpbuf) return (-1); ftaddr &= ~(u16)0x3; err = sd_read(psdio, ftaddr, 8, ptmpbuf); if (err) { _rtw_mfree(ptmpbuf, 8); return err; } val = cpu_to_le32(val); _rtw_memcpy(ptmpbuf+shift, &val, 4); err = sd_write(psdio, ftaddr, 8, ptmpbuf); rtw_mfree(ptmpbuf, 8); } #endif _func_exit_; return err; }
void _rt2880_drvMutexUnlock() { *(volatile u32 *)(RT2880_REG_INTENA) = cpu_to_le32(0x8); return; }
/* * The argv is expected to include one optional parameter and two filenames: * [--vs] IN OUT * * --vs - turns on the variable size SPL mode * IN - the u-boot SPL binary, usually u-boot-spl.bin * OUT - the prepared SPL blob, usually ${BOARD}-spl.bin * * This utility first reads the "u-boot-spl.bin" into a buffer. In case of * fixed size SPL the buffer size is exactly CHECKSUM_OFFSET (such that * smaller u-boot-spl.bin gets padded with 0xff bytes, the larger than limit * u-boot-spl.bin causes an error). For variable size SPL the buffer size is * eqaul to size of the IN file. * * Then it calculates checksum of the buffer by just summing up all bytes. * Then * * - for fixed size SPL the buffer is written into the output file and the * checksum is appended to the file in little endian format, which results * in checksum added exactly at CHECKSUM_OFFSET. * * - for variable size SPL the checksum and file size are stored in the * var_size_header structure (again, in little endian format) and the * structure is written into the output file. Then the buffer is written * into the output file. */ int main(int argc, char **argv) { unsigned char *buffer; int i, ifd, ofd; uint32_t checksum = 0; off_t len; int var_size_flag, read_size, count; struct stat stat; const int if_index = argc - 2; /* Input file name index in argv. */ const int of_index = argc - 1; /* Output file name index in argv. */ /* Strip path off the program name. */ prog_name = strrchr(argv[0], '/'); if (prog_name) prog_name++; else prog_name = argv[0]; if ((argc < 3) || (argc > 4) || ((argc == 4) && strcmp(argv[1], "--vs"))) { fprintf(stderr, "Usage: %s [--vs] <infile> <outfile>\n", prog_name); exit(EXIT_FAILURE); } /* four args mean variable size SPL wrapper is required */ var_size_flag = (argc == 4); ifd = open(argv[if_index], O_RDONLY); if (ifd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", prog_name, argv[if_index], strerror(errno)); exit(EXIT_FAILURE); } ofd = open(argv[of_index], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM); if (ofd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", prog_name, argv[of_index], strerror(errno)); exit(EXIT_FAILURE); } if (fstat(ifd, &stat)) { fprintf(stderr, "%s: Unable to get size of %s: %s\n", prog_name, argv[if_index], strerror(errno)); exit(EXIT_FAILURE); } len = stat.st_size; if (var_size_flag) { read_size = len; count = len; } else { if (len > CHECKSUM_OFFSET) { fprintf(stderr, "%s: %s is too big (exceeds %d bytes)\n", prog_name, argv[if_index], CHECKSUM_OFFSET); exit(EXIT_FAILURE); } count = CHECKSUM_OFFSET; read_size = len; } buffer = malloc(count); if (!buffer) { fprintf(stderr, "%s: Failed to allocate %d bytes to store %s\n", prog_name, count, argv[if_index]); exit(EXIT_FAILURE); } if (read(ifd, buffer, read_size) != read_size) { fprintf(stderr, "%s: Can't read %s: %s\n", prog_name, argv[if_index], strerror(errno)); exit(EXIT_FAILURE); } /* Pad if needed with 0xff to make flashing faster. */ if (read_size < count) memset((char *)buffer + read_size, 0xff, count - read_size); for (i = 0, checksum = 0; i < count; i++) checksum += buffer[i]; checksum = cpu_to_le32(checksum); if (var_size_flag) { /* Prepare and write out the variable size SPL header. */ struct var_size_header vsh; uint32_t spl_size; memset(&vsh, 0, sizeof(vsh)); memcpy(&vsh.spl_checksum, &checksum, sizeof(checksum)); spl_size = cpu_to_le32(count + sizeof(struct var_size_header)); memcpy(&vsh.spl_size, &spl_size, sizeof(spl_size)); write_to_file(ofd, &vsh, sizeof(vsh)); } write_to_file(ofd, buffer, count); /* For fixed size SPL checksum is appended in the end. */ if (!var_size_flag) write_to_file(ofd, &checksum, sizeof(checksum)); close(ifd); close(ofd); free(buffer); return EXIT_SUCCESS; }
/** * i40e_asq_send_command - send command to Admin Queue * @hw: pointer to the hw struct * @desc: prefilled descriptor describing the command (non DMA mem) * @buff: buffer to use for indirect commands * @buff_size: size of buffer for indirect commands * @cmd_details: pointer to command details structure * * This is the main send command driver routine for the Admin Queue send * queue. It runs the queue, cleans the queue, etc **/ i40e_status i40e_asq_send_command(struct i40e_hw *hw, struct i40e_aq_desc *desc, void *buff, /* can be NULL */ u16 buff_size, struct i40e_asq_cmd_details *cmd_details) { i40e_status status = 0; struct i40e_dma_mem *dma_buff = NULL; struct i40e_asq_cmd_details *details; struct i40e_aq_desc *desc_on_ring; bool cmd_completed = false; u16 retval = 0; u32 val = 0; mutex_lock(&hw->aq.asq_mutex); if (hw->aq.asq.count == 0) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: Admin queue not initialized.\n"); status = I40E_ERR_QUEUE_EMPTY; goto asq_send_command_error; } hw->aq.asq_last_status = I40E_AQ_RC_OK; val = rd32(hw, hw->aq.asq.head); if (val >= hw->aq.num_asq_entries) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: head overrun at %d\n", val); status = I40E_ERR_ADMIN_QUEUE_FULL; goto asq_send_command_error; } details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use); if (cmd_details) { *details = *cmd_details; /* If the cmd_details are defined copy the cookie. The * cpu_to_le32 is not needed here because the data is ignored * by the FW, only used by the driver */ if (details->cookie) { desc->cookie_high = cpu_to_le32(upper_32_bits(details->cookie)); desc->cookie_low = cpu_to_le32(lower_32_bits(details->cookie)); } } else { memset(details, 0, sizeof(struct i40e_asq_cmd_details)); } /* clear requested flags and then set additional flags if defined */ desc->flags &= ~cpu_to_le16(details->flags_dis); desc->flags |= cpu_to_le16(details->flags_ena); if (buff_size > hw->aq.asq_buf_size) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: Invalid buffer size: %d.\n", buff_size); status = I40E_ERR_INVALID_SIZE; goto asq_send_command_error; } if (details->postpone && !details->async) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: Async flag not set along with postpone flag"); status = I40E_ERR_PARAM; goto asq_send_command_error; } /* call clean and check queue available function to reclaim the * descriptors that were processed by FW, the function returns the * number of desc available */ /* the clean function called here could be called in a separate thread * in case of asynchronous completions */ if (i40e_clean_asq(hw) == 0) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: Error queue is full.\n"); status = I40E_ERR_ADMIN_QUEUE_FULL; goto asq_send_command_error; } /* initialize the temp desc pointer with the right desc */ desc_on_ring = I40E_ADMINQ_DESC(hw->aq.asq, hw->aq.asq.next_to_use); /* if the desc is available copy the temp desc to the right place */ *desc_on_ring = *desc; /* if buff is not NULL assume indirect command */ if (buff != NULL) { dma_buff = &(hw->aq.asq.r.asq_bi[hw->aq.asq.next_to_use]); /* copy the user buff into the respective DMA buff */ memcpy(dma_buff->va, buff, buff_size); desc_on_ring->datalen = cpu_to_le16(buff_size); /* Update the address values in the desc with the pa value * for respective buffer */ desc_on_ring->params.external.addr_high = cpu_to_le32(upper_32_bits(dma_buff->pa)); desc_on_ring->params.external.addr_low = cpu_to_le32(lower_32_bits(dma_buff->pa)); } /* bump the tail */ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff, buff_size); (hw->aq.asq.next_to_use)++; if (hw->aq.asq.next_to_use == hw->aq.asq.count) hw->aq.asq.next_to_use = 0; if (!details->postpone) wr32(hw, hw->aq.asq.tail, hw->aq.asq.next_to_use); /* if cmd_details are not defined or async flag is not set, * we need to wait for desc write back */ if (!details->async && !details->postpone) { u32 total_delay = 0; do { /* AQ designers suggest use of head for better * timing reliability than DD bit */ if (i40e_asq_done(hw)) break; udelay(50); total_delay += 50; } while (total_delay < hw->aq.asq_cmd_timeout); } /* if ready, copy the desc back to temp */ if (i40e_asq_done(hw)) { *desc = *desc_on_ring; if (buff != NULL) memcpy(buff, dma_buff->va, buff_size); retval = le16_to_cpu(desc->retval); if (retval != 0) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: Command completed with error 0x%X.\n", retval); /* strip off FW internal code */ retval &= 0xff; } cmd_completed = true; if ((enum i40e_admin_queue_err)retval == I40E_AQ_RC_OK) status = 0; else if ((enum i40e_admin_queue_err)retval == I40E_AQ_RC_EBUSY) status = I40E_ERR_NOT_READY; else status = I40E_ERR_ADMIN_QUEUE_ERROR; hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval; } i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer writeback:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size); /* save writeback aq if requested */ if (details->wb_desc) *details->wb_desc = *desc_on_ring; /* update the error if time out occurred */ if ((!cmd_completed) && (!details->async && !details->postpone)) { if (rd32(hw, hw->aq.asq.len) & I40E_GL_ATQLEN_ATQCRIT_MASK) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: AQ Critical error.\n"); status = I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR; } else { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: Writeback timeout.\n"); status = I40E_ERR_ADMIN_QUEUE_TIMEOUT; } } asq_send_command_error: mutex_unlock(&hw->aq.asq_mutex); return status; }
static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rxq *rxq = &trans_pcie->rxq; struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; unsigned long flags; bool page_stolen = false; int max_len = PAGE_SIZE << trans_pcie->rx_page_order; u32 offset = 0; if (WARN_ON(!rxb)) return; dma_unmap_page(trans->dev, rxb->page_dma, max_len, DMA_FROM_DEVICE); while (offset + sizeof(u32) + sizeof(struct iwl_cmd_header) < max_len) { struct iwl_rx_packet *pkt; struct iwl_device_cmd *cmd; u16 sequence; bool reclaim; int index, cmd_index, err, len; struct iwl_rx_cmd_buffer rxcb = { ._offset = offset, ._rx_page_order = trans_pcie->rx_page_order, ._page = rxb->page, ._page_stolen = false, .truesize = max_len, }; pkt = rxb_addr(&rxcb); if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) break; IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd), pkt->hdr.cmd); len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; len += sizeof(u32); /* account for status word */ trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len); trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len); /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. * If the packet (e.g. Rx frame) originated from uCode, * there is no command buffer to reclaim. * Ucode should set SEQ_RX_FRAME bit if ucode-originated, * but apparently a few don't get set; catch them here. */ reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME); if (reclaim) { int i; for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) { if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) { reclaim = false; break; } } } sequence = le16_to_cpu(pkt->hdr.sequence); index = SEQ_TO_INDEX(sequence); cmd_index = get_cmd_index(&txq->q, index); if (reclaim) cmd = txq->entries[cmd_index].cmd; else cmd = NULL; err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); if (reclaim) { kfree(txq->entries[cmd_index].free_buf); txq->entries[cmd_index].free_buf = NULL; } /* * After here, we should always check rxcb._page_stolen, * if it is true then one of the handlers took the page. */ if (reclaim) { /* Invoke any callbacks, transfer the buffer to caller, * and fire off the (possibly) blocking * iwl_trans_send_cmd() * as we reclaim the driver command queue */ if (!rxcb._page_stolen) iwl_pcie_hcmd_complete(trans, &rxcb, err); else IWL_WARN(trans, "Claim null rxb?\n"); } page_stolen |= rxcb._page_stolen; offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN); } /* page was stolen from us -- free our reference */ if (page_stolen) { __free_pages(rxb->page, trans_pcie->rx_page_order); rxb->page = NULL; } /* Reuse the page if possible. For notification packets and * SKBs that fail to Rx correctly, add them back into the * rx_free list for reuse later. */ spin_lock_irqsave(&rxq->lock, flags); if (rxb->page != NULL) { rxb->page_dma = dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, rxb->page_dma)) { /* * free the page(s) as well to not break * the invariant that the items on the used * list have no page(s) */ __free_pages(rxb->page, trans_pcie->rx_page_order); rxb->page = NULL; list_add_tail(&rxb->list, &rxq->rx_used); } else { list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; } } else list_add_tail(&rxb->list, &rxq->rx_used); spin_unlock_irqrestore(&rxq->lock, flags); } /* * iwl_pcie_rx_handle - Main entry function for receiving responses from fw */ static void iwl_pcie_rx_handle(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rxq *rxq = &trans_pcie->rxq; u32 r, i; u8 fill_rx = 0; u32 count = 8; int total_empty; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ r = le16_to_cpu(ACCESS_ONCE(rxq->rb_stts->closed_rb_num)) & 0x0FFF; i = rxq->read; /* Rx interrupt, but nothing sent from uCode */ if (i == r) IWL_DEBUG_RX(trans, "HW = SW = %d\n", r); /* calculate total frames need to be restock after handling RX */ total_empty = r - rxq->write_actual; if (total_empty < 0) total_empty += RX_QUEUE_SIZE; if (total_empty > (RX_QUEUE_SIZE / 2)) fill_rx = 1; while (i != r) { struct iwl_rx_mem_buffer *rxb; rxb = rxq->queue[i]; rxq->queue[i] = NULL; IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", r, i, rxb); iwl_pcie_rx_handle_rb(trans, rxb); i = (i + 1) & RX_QUEUE_MASK; /* If there are a lot of unused frames, * restock the Rx queue so ucode wont assert. */ if (fill_rx) { count++; if (count >= 8) { rxq->read = i; iwl_pcie_rx_replenish_now(trans); count = 0; } } } /* Backtrack one entry */ rxq->read = i; if (fill_rx) iwl_pcie_rx_replenish_now(trans); else iwl_pcie_rxq_restock(trans); } /* * iwl_pcie_irq_handle_error - called for HW or SW error interrupt from card */ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ if (trans->cfg->internal_wimax_coex && (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & APMS_CLK_VAL_MRB_FUNC_MODE) || (iwl_read_prph(trans, APMG_PS_CTRL_REG) & APMG_PS_CTRL_VAL_RESET_REQ))) { clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); iwl_op_mode_wimax_active(trans->op_mode); wake_up(&trans_pcie->wait_command_queue); return; } iwl_pcie_dump_csr(trans); iwl_pcie_dump_fh(trans, NULL); set_bit(STATUS_FW_ERROR, &trans_pcie->status); clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); wake_up(&trans_pcie->wait_command_queue); local_bh_disable(); iwl_op_mode_nic_error(trans->op_mode); local_bh_enable(); } irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) { struct iwl_trans *trans = dev_id; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct isr_statistics *isr_stats = &trans_pcie->isr_stats; u32 inta = 0; u32 handled = 0; unsigned long flags; u32 i; #ifdef CONFIG_IWLWIFI_DEBUG u32 inta_mask; #endif lock_map_acquire(&trans->sync_cmd_lockdep_map); spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Ack/clear/reset pending uCode interrupts. * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, */ /* There is a hardware bug in the interrupt mask function that some * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if * they are disabled in the CSR_INT_MASK register. Furthermore the * ICT interrupt handling mechanism has another bug that might cause * these unmasked interrupts fail to be detected. We workaround the * hardware bugs here by ACKing all the possible interrupts so that * interrupt coalescing can still be achieved. */ iwl_write32(trans, CSR_INT, trans_pcie->inta | ~trans_pcie->inta_mask); inta = trans_pcie->inta; #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_have_debug_level(IWL_DL_ISR)) { /* just for debug */ inta_mask = iwl_read32(trans, CSR_INT_MASK); IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n", inta, inta_mask); } #endif /* saved interrupt in inta variable now we can reset trans_pcie->inta */ trans_pcie->inta = 0; spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* Now service all interrupt bits discovered above. */ if (inta & CSR_INT_BIT_HW_ERR) { IWL_ERR(trans, "Hardware error detected. Restarting.\n"); /* Tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); isr_stats->hw++; iwl_pcie_irq_handle_error(trans); handled |= CSR_INT_BIT_HW_ERR; goto out; } #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_have_debug_level(IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ if (inta & CSR_INT_BIT_SCD) { IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " "the frame/frames.\n"); isr_stats->sch++; } /* Alive notification via Rx interrupt will do the real work */ if (inta & CSR_INT_BIT_ALIVE) { IWL_DEBUG_ISR(trans, "Alive interrupt\n"); isr_stats->alive++; } } #endif /* Safely ignore these bits for debug checks below */ inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { bool hw_rfkill; hw_rfkill = iwl_is_rfkill_set(trans); IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", hw_rfkill ? "disable radio" : "enable radio"); isr_stats->rfkill++; iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); if (hw_rfkill) { set_bit(STATUS_RFKILL, &trans_pcie->status); if (test_and_clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) IWL_DEBUG_RF_KILL(trans, "Rfkill while SYNC HCMD in flight\n"); wake_up(&trans_pcie->wait_command_queue); } else { clear_bit(STATUS_RFKILL, &trans_pcie->status); } handled |= CSR_INT_BIT_RF_KILL; } /* Chip got too hot and stopped itself */ if (inta & CSR_INT_BIT_CT_KILL) { IWL_ERR(trans, "Microcode CT kill error detected.\n"); isr_stats->ctkill++; handled |= CSR_INT_BIT_CT_KILL; } /* Error detected by uCode */ if (inta & CSR_INT_BIT_SW_ERR) { IWL_ERR(trans, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); isr_stats->sw++; iwl_pcie_irq_handle_error(trans); handled |= CSR_INT_BIT_SW_ERR; } /* uCode wakes up after power-down sleep */ if (inta & CSR_INT_BIT_WAKEUP) { IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); iwl_pcie_rxq_inc_wr_ptr(trans, &trans_pcie->rxq); for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) iwl_pcie_txq_inc_wr_ptr(trans, &trans_pcie->txq[i]); isr_stats->wakeup++;
int ocfs2_validate_inode_block(struct super_block *sb, struct buffer_head *bh) { int rc; struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; trace_ocfs2_validate_inode_block((unsigned long long)bh->b_blocknr); BUG_ON(!buffer_uptodate(bh)); /* * If the ecc fails, we return the error but otherwise * leave the filesystem running. We know any error is * local to this block. */ rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &di->i_check); if (rc) { mlog(ML_ERROR, "Checksum failed for dinode %llu\n", (unsigned long long)bh->b_blocknr); goto bail; } /* * Errors after here are fatal. */ rc = -EINVAL; if (!OCFS2_IS_VALID_DINODE(di)) { ocfs2_error(sb, "Invalid dinode #%llu: signature = %.*s\n", (unsigned long long)bh->b_blocknr, 7, di->i_signature); goto bail; } if (le64_to_cpu(di->i_blkno) != bh->b_blocknr) { ocfs2_error(sb, "Invalid dinode #%llu: i_blkno is %llu\n", (unsigned long long)bh->b_blocknr, (unsigned long long)le64_to_cpu(di->i_blkno)); goto bail; } if (!(di->i_flags & cpu_to_le32(OCFS2_VALID_FL))) { ocfs2_error(sb, "Invalid dinode #%llu: OCFS2_VALID_FL not set\n", (unsigned long long)bh->b_blocknr); goto bail; } if (le32_to_cpu(di->i_fs_generation) != OCFS2_SB(sb)->fs_generation) { ocfs2_error(sb, "Invalid dinode #%llu: fs_generation is %u\n", (unsigned long long)bh->b_blocknr, le32_to_cpu(di->i_fs_generation)); goto bail; } rc = 0; bail: return rc; }
static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign) { unsigned char *base; unsigned long size, align; unsigned long fibsize = 4096; unsigned long printfbufsiz = 256; struct aac_init *init; dma_addr_t phys; size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz; base = pci_alloc_consistent(dev->pdev, size, &phys); if(base == NULL) { printk(KERN_ERR "aacraid: unable to create mapping.\n"); return 0; } dev->comm_addr = (void *)base; dev->comm_phys = phys; dev->comm_size = size; dev->init = (struct aac_init *)(base + fibsize); dev->init_pa = (struct aac_init *)(phys + fibsize); init = dev->init; init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION); init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION); init->fsrev = cpu_to_le32(dev->fsrev); /* * Adapter Fibs are the first thing allocated so that they * start page aligned */ init->AdapterFibsVirtualAddress = cpu_to_le32(base); init->AdapterFibsPhysicalAddress = cpu_to_le32(phys); init->AdapterFibsSize = cpu_to_le32(fibsize); init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); /* * Increment the base address by the amount already used */ base = base + fibsize + sizeof(struct aac_init); phys = phys + fibsize + sizeof(struct aac_init); /* * Align the beginning of Headers to commalign */ align = (commalign - ((unsigned long)(base) & (commalign - 1))); base = base + align; phys = phys + align; /* * Fill in addresses of the Comm Area Headers and Queues */ *commaddr = (unsigned long *)base; init->CommHeaderAddress = cpu_to_le32(phys); /* * Increment the base address by the size of the CommArea */ base = base + commsize; phys = phys + commsize; /* * Place the Printf buffer area after the Fast I/O comm area. */ dev->printfbuf = (void *)base; init->printfbuf = cpu_to_le32(phys); init->printfbufsiz = cpu_to_le32(printfbufsiz); memset(base, 0, printfbufsiz); return 1; }
static int ocfs2_read_locked_inode(struct inode *inode, struct ocfs2_find_inode_args *args) { struct super_block *sb; struct ocfs2_super *osb; struct ocfs2_dinode *fe; struct buffer_head *bh = NULL; int status, can_lock; u32 generation = 0; status = -EINVAL; sb = inode->i_sb; osb = OCFS2_SB(sb); /* * To improve performance of cold-cache inode stats, we take * the cluster lock here if possible. * * Generally, OCFS2 never trusts the contents of an inode * unless it's holding a cluster lock, so taking it here isn't * a correctness issue as much as it is a performance * improvement. * * There are three times when taking the lock is not a good idea: * * 1) During startup, before we have initialized the DLM. * * 2) If we are reading certain system files which never get * cluster locks (local alloc, truncate log). * * 3) If the process doing the iget() is responsible for * orphan dir recovery. We're holding the orphan dir lock and * can get into a deadlock with another process on another * node in ->delete_inode(). * * #1 and #2 can be simply solved by never taking the lock * here for system files (which are the only type we read * during mount). It's a heavier approach, but our main * concern is user-accessible files anyway. * * #3 works itself out because we'll eventually take the * cluster lock before trusting anything anyway. */ can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE) && !(args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY) && !ocfs2_mount_local(osb); trace_ocfs2_read_locked_inode( (unsigned long long)OCFS2_I(inode)->ip_blkno, can_lock); /* * To maintain backwards compatibility with older versions of * ocfs2-tools, we still store the generation value for system * files. The only ones that actually matter to userspace are * the journals, but it's easier and inexpensive to just flag * all system files similarly. */ if (args->fi_flags & OCFS2_FI_FLAG_SYSFILE) generation = osb->fs_generation; ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_inode_lockres, OCFS2_LOCK_TYPE_META, generation, inode); ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_open_lockres, OCFS2_LOCK_TYPE_OPEN, 0, inode); if (can_lock) { status = ocfs2_open_lock(inode); if (status) { make_bad_inode(inode); mlog_errno(status); return status; } status = ocfs2_inode_lock(inode, NULL, 0); if (status) { make_bad_inode(inode); mlog_errno(status); return status; } } if (args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY) { status = ocfs2_try_open_lock(inode, 0); if (status) { make_bad_inode(inode); return status; } } if (can_lock) { status = ocfs2_read_inode_block_full(inode, &bh, OCFS2_BH_IGNORE_CACHE); } else { status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); /* * If buffer is in jbd, then its checksum may not have been * computed as yet. */ if (!status && !buffer_jbd(bh)) status = ocfs2_validate_inode_block(osb->sb, bh); } if (status < 0) { mlog_errno(status); goto bail; } status = -EINVAL; fe = (struct ocfs2_dinode *) bh->b_data; /* * This is a code bug. Right now the caller needs to * understand whether it is asking for a system file inode or * not so the proper lock names can be built. */ mlog_bug_on_msg(!!(fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) != !!(args->fi_flags & OCFS2_FI_FLAG_SYSFILE), "Inode %llu: system file state is ambigous\n", (unsigned long long)args->fi_blkno); if (S_ISCHR(le16_to_cpu(fe->i_mode)) || S_ISBLK(le16_to_cpu(fe->i_mode))) inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); ocfs2_populate_inode(inode, fe, 0); BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno)); status = 0; bail: if (can_lock) ocfs2_inode_unlock(inode, 0); if (status < 0) make_bad_inode(inode); brelse(bh); return status; }
int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; unsigned int transfer_length = srb->request_bufflen; unsigned int residue; int result; int fake_sense = 0; unsigned int cswlen; unsigned int cbwlen = US_BULK_CB_WRAP_LEN; /* Take care of BULK32 devices; set extra byte to 0 */ if ( unlikely(us->flags & US_FL_BULK32)) { cbwlen = 32; us->iobuf[31] = 0; } /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(transfer_length); bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0; bcb->Tag = ++us->tag; bcb->Lun = srb->device->lun; if (us->flags & US_FL_SCM_MULT_TARG) bcb->Lun |= srb->device->id << 4; bcb->Length = srb->cmd_len; /* copy the command payload */ memset(bcb->CDB, 0, sizeof(bcb->CDB)); memcpy(bcb->CDB, srb->cmnd, bcb->Length); /* send it to out endpoint */ US_DEBUGP("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n", le32_to_cpu(bcb->Signature), bcb->Tag, le32_to_cpu(bcb->DataTransferLength), bcb->Flags, (bcb->Lun >> 4), (bcb->Lun & 0x0F), bcb->Length); result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, cbwlen, NULL); US_DEBUGP("Bulk command transfer result=%d\n", result); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; /* DATA STAGE */ /* send/receive data payload, if there is any */ /* Some USB-IDE converter chips need a 100us delay between the * command phase and the data phase. Some devices need a little * more than that, probably because of clock rate inaccuracies. */ if (unlikely(us->flags & US_FL_GO_SLOW)) udelay(125); if (transfer_length) { unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? us->recv_bulk_pipe : us->send_bulk_pipe; result = usb_stor_bulk_transfer_sg(us, pipe, srb->request_buffer, transfer_length, srb->use_sg, &srb->resid); US_DEBUGP("Bulk data transfer result 0x%x\n", result); if (result == USB_STOR_XFER_ERROR) return USB_STOR_TRANSPORT_ERROR; /* If the device tried to send back more data than the * amount requested, the spec requires us to transfer * the CSW anyway. Since there's no point retrying the * the command, we'll return fake sense data indicating * Illegal Request, Invalid Field in CDB. */ if (result == USB_STOR_XFER_LONG) fake_sense = 1; } /* See flow chart on pg 15 of the Bulk Only Transport spec for * an explanation of how this code works. */ /* get CSW for device status */ US_DEBUGP("Attempting to get CSW...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen); /* Some broken devices add unnecessary zero-length packets to the * end of their data transfers. Such packets show up as 0-length * CSWs. If we encounter such a thing, try to read the CSW again. */ if (result == USB_STOR_XFER_SHORT && cswlen == 0) { US_DEBUGP("Received 0-length CSW; retrying...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen); } /* did the attempt to read the CSW fail? */ if (result == USB_STOR_XFER_STALLED) { /* get the status again */ US_DEBUGP("Attempting to get CSW (2nd try)...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL); } /* if we still have a failure at this point, we're in trouble */ US_DEBUGP("Bulk status result = %d\n", result); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; /* check bulk status */ residue = le32_to_cpu(bcs->Residue); US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n", le32_to_cpu(bcs->Signature), bcs->Tag, residue, bcs->Status); if (bcs->Tag != us->tag || bcs->Status > US_BULK_STAT_PHASE) { US_DEBUGP("Bulk logical error\n"); return USB_STOR_TRANSPORT_ERROR; } /* Some broken devices report odd signatures, so we do not check them * for validity against the spec. We store the first one we see, * and check subsequent transfers for validity against this signature. */ if (!us->bcs_signature) { us->bcs_signature = bcs->Signature; if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN)) US_DEBUGP("Learnt BCS signature 0x%08X\n", le32_to_cpu(us->bcs_signature)); } else if (bcs->Signature != us->bcs_signature) { US_DEBUGP("Signature mismatch: got %08X, expecting %08X\n", le32_to_cpu(bcs->Signature), le32_to_cpu(us->bcs_signature)); return USB_STOR_TRANSPORT_ERROR; } /* try to compute the actual residue, based on how much data * was really transferred and what the device tells us */ if (residue) { if (!(us->flags & US_FL_IGNORE_RESIDUE)) { residue = min(residue, transfer_length); srb->resid = max(srb->resid, (int) residue); } } /* based on the status code, we report good or bad */ switch (bcs->Status) { case US_BULK_STAT_OK: /* device babbled -- return fake sense data */ if (fake_sense) { memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB, sizeof(usb_stor_sense_invalidCDB)); return USB_STOR_TRANSPORT_NO_SENSE; } /* command good -- note that data could be short */ return USB_STOR_TRANSPORT_GOOD; case US_BULK_STAT_FAIL: /* command failed */ return USB_STOR_TRANSPORT_FAILED; case US_BULK_STAT_PHASE: /* phase error -- note that a transport reset will be * invoked by the invoke_transport() function */ return USB_STOR_TRANSPORT_ERROR; } /* we should never get here, but if we do, we're in trouble */ return USB_STOR_TRANSPORT_ERROR; }
/* Query the cluster to determine whether we should wipe an inode from * disk or not. * * Requires the inode to have the cluster lock. */ static int ocfs2_query_inode_wipe(struct inode *inode, struct buffer_head *di_bh, int *wipe) { int status = 0, reason = 0; struct ocfs2_inode_info *oi = OCFS2_I(inode); struct ocfs2_dinode *di; *wipe = 0; trace_ocfs2_query_inode_wipe_begin((unsigned long long)oi->ip_blkno, inode->i_nlink); /* While we were waiting for the cluster lock in * ocfs2_delete_inode, another node might have asked to delete * the inode. Recheck our flags to catch this. */ if (!ocfs2_inode_is_valid_to_delete(inode)) { reason = 1; goto bail; } /* Now that we have an up to date inode, we can double check * the link count. */ if (inode->i_nlink) goto bail; /* Do some basic inode verification... */ di = (struct ocfs2_dinode *) di_bh->b_data; if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) && !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { /* * Inodes in the orphan dir must have ORPHANED_FL. The only * inodes that come back out of the orphan dir are reflink * targets. A reflink target may be moved out of the orphan * dir between the time we scan the directory and the time we * process it. This would lead to HAS_REFCOUNT_FL being set but * ORPHANED_FL not. */ if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) { reason = 2; goto bail; } /* for lack of a better error? */ status = -EEXIST; mlog(ML_ERROR, "Inode %llu (on-disk %llu) not orphaned! " "Disk flags 0x%x, inode flags 0x%x\n", (unsigned long long)oi->ip_blkno, (unsigned long long)le64_to_cpu(di->i_blkno), le32_to_cpu(di->i_flags), oi->ip_flags); goto bail; } /* has someone already deleted us?! baaad... */ if (di->i_dtime) { status = -EEXIST; mlog_errno(status); goto bail; } /* * This is how ocfs2 determines whether an inode is still live * within the cluster. Every node takes a shared read lock on * the inode open lock in ocfs2_read_locked_inode(). When we * get to ->delete_inode(), each node tries to convert it's * lock to an exclusive. Trylocks are serialized by the inode * meta data lock. If the upconvert succeeds, we know the inode * is no longer live and can be deleted. * * Though we call this with the meta data lock held, the * trylock keeps us from ABBA deadlock. */ status = ocfs2_try_open_lock(inode, 1); if (status == -EAGAIN) { status = 0; reason = 3; goto bail; } if (status < 0) { mlog_errno(status); goto bail; } *wipe = 1; trace_ocfs2_query_inode_wipe_succ(le16_to_cpu(di->i_orphaned_slot)); bail: trace_ocfs2_query_inode_wipe_end(status, reason); return status; }
static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, u8 *prep_elem, u32 metric) { struct mesh_path *mpath; u8 *target_addr, *orig_addr; u8 ttl, hopcount, flags; u8 next_hop[ETH_ALEN]; u32 target_sn, orig_sn, lifetime; mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); /* Note that we divert from the draft nomenclature and denominate * destination to what the draft refers to as origininator. So in this * function destnation refers to the final destination of the PREP, * which corresponds with the originator of the PREQ which this PREP * replies */ target_addr = PREP_IE_TARGET_ADDR(prep_elem); if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) /* destination, no forwarding required */ return; ttl = PREP_IE_TTL(prep_elem); if (ttl <= 1) { sdata->u.mesh.mshstats.dropped_frames_ttl++; return; } rcu_read_lock(); mpath = mesh_path_lookup(target_addr, sdata); if (mpath) spin_lock_bh(&mpath->state_lock); else goto fail; if (!(mpath->flags & MESH_PATH_ACTIVE)) { spin_unlock_bh(&mpath->state_lock); goto fail; } memcpy(next_hop, next_hop_deref_protected(mpath)->sta.addr, ETH_ALEN); spin_unlock_bh(&mpath->state_lock); --ttl; flags = PREP_IE_FLAGS(prep_elem); lifetime = PREP_IE_LIFETIME(prep_elem); hopcount = PREP_IE_HOPCOUNT(prep_elem) + 1; orig_addr = PREP_IE_ORIG_ADDR(prep_elem); target_sn = PREP_IE_TARGET_SN(prep_elem); orig_sn = PREP_IE_ORIG_SN(prep_elem); mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, cpu_to_le32(orig_sn), 0, target_addr, cpu_to_le32(target_sn), next_hop, hopcount, ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), 0, sdata); rcu_read_unlock(); sdata->u.mesh.mshstats.fwded_unicast++; sdata->u.mesh.mshstats.fwded_frames++; return; fail: rcu_read_unlock(); sdata->u.mesh.mshstats.dropped_frames_no_route++; }