static void __exit exit_qlogic_cs(void) { pcmcia_unregister_driver(&qlogic_cs_driver); BUG_ON(dev_list != NULL); }
static int eth_close(struct net_device *dev) { struct port *port = netdev_priv(dev); struct msg msg; int buffs = RX_DESCS; /* allocated RX buffers */ int i; ports_open--; qmgr_disable_irq(port->plat->rxq); napi_disable(&port->napi); netif_stop_queue(dev); while (queue_get_desc(RXFREE_QUEUE(port->id), port, 0) >= 0) buffs--; memset(&msg, 0, sizeof(msg)); msg.cmd = NPE_SETLOOPBACK_MODE; msg.eth_id = port->id; msg.byte3 = 1; if (npe_send_recv_message(port->npe, &msg, "ETH_ENABLE_LOOPBACK")) printk(KERN_CRIT "%s: unable to enable loopback\n", dev->name); i = 0; do { /* drain RX buffers */ while (queue_get_desc(port->plat->rxq, port, 0) >= 0) buffs--; if (!buffs) break; if (qmgr_stat_empty(TX_QUEUE(port->id))) { /* we have to inject some packet */ struct desc *desc; u32 phys; int n = queue_get_desc(port->plat->txreadyq, port, 1); BUG_ON(n < 0); desc = tx_desc_ptr(port, n); phys = tx_desc_phys(port, n); desc->buf_len = desc->pkt_len = 1; wmb(); queue_put_desc(TX_QUEUE(port->id), phys, desc); } udelay(1); } while (++i < MAX_CLOSE_WAIT); if (buffs) printk(KERN_CRIT "%s: unable to drain RX queue, %i buffer(s)" " left in NPE\n", dev->name, buffs); #if DEBUG_CLOSE if (!buffs) printk(KERN_DEBUG "Draining RX queue took %i cycles\n", i); #endif buffs = TX_DESCS; while (queue_get_desc(TX_QUEUE(port->id), port, 1) >= 0) buffs--; /* cancel TX */ i = 0; do { while (queue_get_desc(port->plat->txreadyq, port, 1) >= 0) buffs--; if (!buffs) break; } while (++i < MAX_CLOSE_WAIT); if (buffs) printk(KERN_CRIT "%s: unable to drain TX queue, %i buffer(s) " "left in NPE\n", dev->name, buffs); #if DEBUG_CLOSE if (!buffs) printk(KERN_DEBUG "Draining TX queues took %i cycles\n", i); #endif msg.byte3 = 0; if (npe_send_recv_message(port->npe, &msg, "ETH_DISABLE_LOOPBACK")) printk(KERN_CRIT "%s: unable to disable loopback\n", dev->name); phy_stop(port->phydev); if (!ports_open) qmgr_disable_irq(TXDONE_QUEUE); destroy_queues(port); release_queues(port); return 0; }
static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev) { struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data; BUG_ON(scsi_dh_data == NULL); return ((struct alua_dh_data *) scsi_dh_data->buf); }
/* * This sets up the system timers, clock source and clock event. */ static void __init u300_timer_init(void) { struct clk *clk; unsigned long rate; /* Clock the interrupt controller */ clk = clk_get_sys("apptimer", NULL); BUG_ON(IS_ERR(clk)); clk_enable(clk); rate = clk_get_rate(clk); init_sched_clock(&cd, u300_update_sched_clock, 32, rate); /* * Disable the "OS" and "DD" timers - these are designed for Symbian! * Example usage in cnh1601578 cpu subsystem pd_timer_app.c */ writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE, U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC); writel(U300_TIMER_APP_ROST_TIMER_RESET, U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST); writel(U300_TIMER_APP_DOST_TIMER_DISABLE, U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST); writel(U300_TIMER_APP_RDDT_TIMER_RESET, U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT); writel(U300_TIMER_APP_DDDT_TIMER_DISABLE, U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT); /* Reset the General Purpose timer 1. */ writel(U300_TIMER_APP_RGPT1_TIMER_RESET, U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1); /* Set up the IRQ handler */ setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq); /* Reset the General Purpose timer 2 */ writel(U300_TIMER_APP_RGPT2_TIMER_RESET, U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2); /* Set this timer to run around forever */ writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC); /* Set continuous mode so it wraps around */ writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS, U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M); /* Disable timer interrupts */ writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE); /* Then enable the GP2 timer to use as a free running us counter */ writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); /* Use general purpose timer 2 as clock source */ if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC, "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) pr_err("timer: failed to initialize U300 clock source\n"); clockevents_calc_mult_shift(&clockevent_u300_1mhz, rate, APPTIMER_MIN_RANGE); /* 32bit counter, so 32bits delta is max */ clockevent_u300_1mhz.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_u300_1mhz); /* This timer is slow enough to set for 1 cycle == 1 MHz */ clockevent_u300_1mhz.min_delta_ns = clockevent_delta2ns(1, &clockevent_u300_1mhz); clockevent_u300_1mhz.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_u300_1mhz); /* * TODO: init and register the rest of the timers too, they can be * used by hrtimers! */ }
/** * suspend_enter - enter the desired system sleep state. * @state: state to enter * * This function should be called after devices have been suspended. */ static int suspend_enter(suspend_state_t state) { int error; if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) goto Platform_finish; } error = dpm_suspend_noirq(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; } if (suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = sysdev_suspend(PMSG_SUSPEND); if (!error) { error = syscore_suspend(); if (error) sysdev_resume(); } if (!error) { if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { error = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); sysdev_resume(); sleepEnter = 1; } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); dpm_resume_noirq(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }
/* * this first locks inode (neither reads nor sync are permitted), * reads tail through page cache, insert direct item. When direct item * inserted successfully inode is left locked. Return value is always * what we expect from it (number of cut bytes). But when tail remains * in the unformatted node, we set mode to SKIP_BALANCING and unlock * inode */ int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *inode, struct page *page, struct treepath *path, /* path to the indirect item. */ const struct cpu_key *item_key, /* Key to look for * unformatted node * pointer to be cut. */ loff_t n_new_file_size, /* New file size. */ char *mode) { struct super_block *sb = inode->i_sb; struct item_head s_ih; unsigned long block_size = sb->s_blocksize; char *tail; int tail_len, round_tail_len; loff_t pos, pos1; /* position of first byte of the tail */ struct cpu_key key; BUG_ON(!th->t_trans_id); REISERFS_SB(sb)->s_indirect2direct++; *mode = M_SKIP_BALANCING; /* store item head path points to. */ copy_item_head(&s_ih, tp_item_head(path)); tail_len = (n_new_file_size & (block_size - 1)); if (get_inode_sd_version(inode) == STAT_DATA_V2) round_tail_len = ROUND_UP(tail_len); else round_tail_len = tail_len; pos = le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE - 1) * sb->s_blocksize; pos1 = pos; /* * we are protected by i_mutex. The tail can not disapper, not * append can be done either * we are in truncate or packing tail in file_release */ tail = (char *)kmap(page); /* this can schedule */ if (path_changed(&s_ih, path)) { /* re-search indirect item */ if (search_for_position_by_key(sb, item_key, path) == POSITION_NOT_FOUND) reiserfs_panic(sb, "PAP-5520", "item to be converted %K does not exist", item_key); copy_item_head(&s_ih, tp_item_head(path)); #ifdef CONFIG_REISERFS_CHECK pos = le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE - 1) * sb->s_blocksize; if (pos != pos1) reiserfs_panic(sb, "vs-5530", "tail position " "changed while we were reading it"); #endif } /* Set direct item header to insert. */ make_le_item_head(&s_ih, NULL, get_inode_item_key_version(inode), pos1 + 1, TYPE_DIRECT, round_tail_len, 0xffff /*ih_free_space */ ); /* * we want a pointer to the first byte of the tail in the page. * the page was locked and this part of the page was up to date when * indirect2direct was called, so we know the bytes are still valid */ tail = tail + (pos & (PAGE_SIZE - 1)); PATH_LAST_POSITION(path)++; key = *item_key; set_cpu_key_k_type(&key, TYPE_DIRECT); key.key_length = 4; /* Insert tail as new direct item in the tree */ if (reiserfs_insert_item(th, path, &key, &s_ih, inode, tail ? tail : NULL) < 0) { /* * No disk memory. So we can not convert last unformatted node * to the direct item. In this case we used to adjust * indirect items's ih_free_space. Now ih_free_space is not * used, it would be ideal to write zeros to corresponding * unformatted node. For now i_size is considered as guard for * going out of file size */ kunmap(page); return block_size - round_tail_len; } kunmap(page); /* make sure to get the i_blocks changes from reiserfs_insert_item */ reiserfs_update_sd(th, inode); /* * note: we have now the same as in above direct2indirect * conversion: there are two keys which have matching first three * key components. They only differ by the fourth one. */ /* * We have inserted new direct item and must remove last * unformatted node. */ *mode = M_CUT; /* we store position of first direct item in the in-core inode */ /* mark_file_with_tail (inode, pos1 + 1); */ REISERFS_I(inode)->i_first_direct_byte = pos1 + 1; return block_size - round_tail_len; }
char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type) { unsigned char csum, ch; unsigned int acc; char *key; int loop, len, max, seg, mark, print; _enter(",%d", keylen); BUG_ON(keylen < 2 || keylen > 514); csum = raw[0] + raw[1]; print = 1; for (loop = 2; loop < keylen; loop++) { ch = raw[loop]; csum += ch; print &= cachefiles_filecharmap[ch]; } if (print) { max = keylen - 2; max += 2; max += 5; max += 3 * 2; max += 1; } else { keylen = (keylen + 2) / 3; max = keylen * 4; max += 5; max += 3 * 2; max += 1; } max += 1; _debug("max: %d", max); key = kmalloc(max, GFP_KERNEL); if (!key) return NULL; len = 0; sprintf(key, "@%02x%c+", (unsigned) csum, 0); len = 5; mark = len - 1; if (print) { acc = *(uint16_t *) raw; raw += 2; key[len + 1] = cachefiles_charmap[acc & 63]; acc >>= 6; key[len] = cachefiles_charmap[acc & 63]; len += 2; seg = 250; for (loop = keylen; loop > 0; loop--) { if (seg <= 0) { key[len++] = '\0'; mark = len; key[len++] = '+'; seg = 252; } key[len++] = *raw++; ASSERT(len < max); } switch (type) { case FSCACHE_COOKIE_TYPE_INDEX: type = 'I'; break; case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'D'; break; default: type = 'S'; break; } } else {
/* * this drops all the extents in the cache that intersect the range * [start, end]. Existing extents are split as required. */ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, int skip_pinned) { struct extent_map *em; struct extent_map *split = NULL; struct extent_map *split2 = NULL; struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; u64 len = end - start + 1; int ret; int testend = 1; unsigned long flags; int compressed = 0; WARN_ON(end < start); if (end == (u64)-1) { len = (u64)-1; testend = 0; } while (1) { if (!split) split = alloc_extent_map(GFP_NOFS); if (!split2) split2 = alloc_extent_map(GFP_NOFS); BUG_ON(!split || !split2); write_lock(&em_tree->lock); em = lookup_extent_mapping(em_tree, start, len); if (!em) { write_unlock(&em_tree->lock); break; } flags = em->flags; if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) { if (testend && em->start + em->len >= start + len) { free_extent_map(em); write_unlock(&em_tree->lock); break; } start = em->start + em->len; if (testend) len = start + len - (em->start + em->len); free_extent_map(em); write_unlock(&em_tree->lock); continue; } compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags); clear_bit(EXTENT_FLAG_PINNED, &em->flags); remove_extent_mapping(em_tree, em); if (em->block_start < EXTENT_MAP_LAST_BYTE && em->start < start) { split->start = em->start; split->len = start - em->start; split->orig_start = em->orig_start; split->block_start = em->block_start; if (compressed) split->block_len = em->block_len; else split->block_len = split->len; split->bdev = em->bdev; split->flags = flags; split->compress_type = em->compress_type; ret = add_extent_mapping(em_tree, split); BUG_ON(ret); free_extent_map(split); split = split2; split2 = NULL; } if (em->block_start < EXTENT_MAP_LAST_BYTE && testend && em->start + em->len > start + len) { u64 diff = start + len - em->start; split->start = start + len; split->len = em->start + em->len - (start + len); split->bdev = em->bdev; split->flags = flags; split->compress_type = em->compress_type; if (compressed) { split->block_len = em->block_len; split->block_start = em->block_start; split->orig_start = em->orig_start; } else { split->block_len = split->len; split->block_start = em->block_start + diff; split->orig_start = split->start; } ret = add_extent_mapping(em_tree, split); BUG_ON(ret); free_extent_map(split); split = NULL; } write_unlock(&em_tree->lock); /* once for us */ free_extent_map(em); /* once for the tree*/ free_extent_map(em); } if (split) free_extent_map(split); if (split2) free_extent_map(split2); return 0; }
/* * this is very complex, but the basic idea is to drop all extents * in the range start - end. hint_block is filled in with a block number * that would be a good hint to the block allocator for this file. * * If an extent intersects the range but is not entirely inside the range * it is either truncated or split. Anything entirely inside the range * is deleted from the tree. */ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, u64 start, u64 end, u64 *hint_byte, int drop_cache) { struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_buffer *leaf; struct btrfs_file_extent_item *fi; struct btrfs_path *path; struct btrfs_key key; struct btrfs_key new_key; u64 search_start = start; u64 disk_bytenr = 0; u64 num_bytes = 0; u64 extent_offset = 0; u64 extent_end = 0; int del_nr = 0; int del_slot = 0; int extent_type; int recow; int ret; if (drop_cache) btrfs_drop_extent_cache(inode, start, end - 1, 0); path = btrfs_alloc_path(); if (!path) return -ENOMEM; while (1) { recow = 0; ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino, search_start, -1); if (ret < 0) break; if (ret > 0 && path->slots[0] > 0 && search_start == start) { leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1); if (key.objectid == inode->i_ino && key.type == BTRFS_EXTENT_DATA_KEY) path->slots[0]--; } ret = 0; next_slot: leaf = path->nodes[0]; if (path->slots[0] >= btrfs_header_nritems(leaf)) { BUG_ON(del_nr > 0); ret = btrfs_next_leaf(root, path); if (ret < 0) break; if (ret > 0) { ret = 0; break; } leaf = path->nodes[0]; recow = 1; } btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); if (key.objectid > inode->i_ino || key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end) break; fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); extent_type = btrfs_file_extent_type(leaf, fi); if (extent_type == BTRFS_FILE_EXTENT_REG || extent_type == BTRFS_FILE_EXTENT_PREALLOC) { disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); extent_offset = btrfs_file_extent_offset(leaf, fi); extent_end = key.offset + btrfs_file_extent_num_bytes(leaf, fi); } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { extent_end = key.offset + btrfs_file_extent_inline_len(leaf, fi); } else { WARN_ON(1); extent_end = search_start; } if (extent_end <= search_start) { path->slots[0]++; goto next_slot; } search_start = max(key.offset, start); if (recow) { btrfs_release_path(root, path); continue; } /* * | - range to drop - | * | -------- extent -------- | */ if (start > key.offset && end < extent_end) { BUG_ON(del_nr > 0); BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); memcpy(&new_key, &key, sizeof(new_key)); new_key.offset = start; ret = btrfs_duplicate_item(trans, root, path, &new_key); if (ret == -EAGAIN) { btrfs_release_path(root, path); continue; } if (ret < 0) break; leaf = path->nodes[0]; fi = btrfs_item_ptr(leaf, path->slots[0] - 1, struct btrfs_file_extent_item); btrfs_set_file_extent_num_bytes(leaf, fi, start - key.offset); fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); extent_offset += start - key.offset; btrfs_set_file_extent_offset(leaf, fi, extent_offset); btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - start); btrfs_mark_buffer_dirty(leaf); if (disk_bytenr > 0) { ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, num_bytes, 0, root->root_key.objectid, new_key.objectid, start - extent_offset); BUG_ON(ret); *hint_byte = disk_bytenr; } key.offset = start; } /* * | ---- range to drop ----- | * | -------- extent -------- | */ if (start <= key.offset && end < extent_end) { BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); memcpy(&new_key, &key, sizeof(new_key)); new_key.offset = end; btrfs_set_item_key_safe(trans, root, path, &new_key); extent_offset += end - key.offset; btrfs_set_file_extent_offset(leaf, fi, extent_offset); btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - end); btrfs_mark_buffer_dirty(leaf); if (disk_bytenr > 0) { inode_sub_bytes(inode, end - key.offset); *hint_byte = disk_bytenr; } break; } search_start = extent_end; /* * | ---- range to drop ----- | * | -------- extent -------- | */ if (start > key.offset && end >= extent_end) { BUG_ON(del_nr > 0); BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); btrfs_set_file_extent_num_bytes(leaf, fi, start - key.offset); btrfs_mark_buffer_dirty(leaf); if (disk_bytenr > 0) { inode_sub_bytes(inode, extent_end - start); *hint_byte = disk_bytenr; } if (end == extent_end) break; path->slots[0]++; goto next_slot; } /* * | ---- range to drop ----- | * | ------ extent ------ | */ if (start <= key.offset && end >= extent_end) { if (del_nr == 0) { del_slot = path->slots[0]; del_nr = 1; } else { BUG_ON(del_slot + del_nr != path->slots[0]); del_nr++; } if (extent_type == BTRFS_FILE_EXTENT_INLINE) { inode_sub_bytes(inode, extent_end - key.offset); extent_end = ALIGN(extent_end, root->sectorsize); } else if (disk_bytenr > 0) { ret = btrfs_free_extent(trans, root, disk_bytenr, num_bytes, 0, root->root_key.objectid, key.objectid, key.offset - extent_offset); BUG_ON(ret); inode_sub_bytes(inode, extent_end - key.offset); *hint_byte = disk_bytenr; } if (end == extent_end) break; if (path->slots[0] + 1 < btrfs_header_nritems(leaf)) { path->slots[0]++; goto next_slot; } ret = btrfs_del_items(trans, root, path, del_slot, del_nr); BUG_ON(ret); del_nr = 0; del_slot = 0; btrfs_release_path(root, path); continue; } BUG_ON(1); }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; u32 rocr; u8 *ext_csd = NULL; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); #if 0 /* Original code before adding temporary workaround for broken MMC parts */ if (err) goto err; #else if (err){ if (err == -ETIMEDOUT || err == -EILSEQ) { pr_debug("%s: Ignoring error %d for mmc_all_send_cid\n", __func__, err); err = 0; } else { goto err; } } #endif if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_get_ext_csd(card, &ext_csd); if (err) goto free_card; err = mmc_read_ext_csd(card, ext_csd); if (err) goto free_card; /* If doing byte addressing, check if required to do sector * addressing. Handle the case of <2GB cards needing sector * addressing. See section 8.1 JEDEC Standard JED84-A441; * ocr register has bit 30 set for sector addressing. */ if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) mmc_card_set_blockaddr(card); /* Erase size depends on CSD and Extended CSD */ mmc_set_erase_size(card); } /* * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF * bit. This bit will be lost every time after a reset or power off. */ if (card->ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1, 0); if (err && err != -EBADMSG) goto free_card; if (err) { err = 0; /* * Just disable enhanced area off & sz * will try to enable ERASE_GROUP_DEF * during next time reinit */ card->ext_csd.enhanced_area_offset = -EINVAL; card->ext_csd.enhanced_area_size = -EINVAL; } else { card->ext_csd.erase_group_def = 1; /* * enable ERASE_GRP_DEF successfully. * This will affect the erase size, so * here need to reset erase size */ mmc_set_erase_size(card); } } /* * Ensure eMMC user default partition is enabled */ if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, card->ext_csd.part_config, card->ext_csd.part_time); if (err && err != -EBADMSG) goto free_card; } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && #ifdef CONFIG_MMC_BCM_SD (host->f_max > SDHCI_HOST_MAX_CLK_LS_MODE) && #endif (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1, 0); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to highspeed failed\n", mmc_hostname(card->host)); err = 0; } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && ((host->caps & (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && ((host->caps & (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_2V_DDR_MODE; } /* * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { static unsigned ext_csd_bits[][2] = { { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 }, { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 }, }; static unsigned bus_widths[] = { MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_4, MMC_BUS_WIDTH_1 }; unsigned idx, bus_width = 0; if (host->caps & MMC_CAP_8_BIT_DATA) idx = 0; else idx = 1; for (; idx < ARRAY_SIZE(bus_widths); idx++) { bus_width = bus_widths[idx]; if (bus_width == MMC_BUS_WIDTH_1) ddr = 0; /* no DDR for 1-bit width */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0], 0); if (!err) { mmc_set_bus_width(card->host, bus_width); /* * If controller can't handle bus width test, * compare ext_csd previously read in 1 bit mode * against ext_csd at new bus width */ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) err = mmc_compare_ext_csds(card, bus_width); else err = mmc_bus_test(card, bus_width); if (!err) break; } } if (!err && ddr) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1], 0); } if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), 1 << bus_width, ddr); goto free_card; } else if (ddr) { /* * eMMC cards can support 3.3V to 1.2V i/o (vccq) * signaling. * * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. * * 1.8V vccq at 3.3V core voltage (vcc) is not required * in the JEDEC spec for DDR. * * Do not force change in vccq since we are obviously * working and no change to vccq is needed. * * WARNING: eMMC rules are NOT the same as SD DDR */ if (ddr == MMC_1_2V_DDR_MODE) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0); if (err) goto err; } mmc_card_set_ddr_mode(card); mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50); mmc_set_bus_width(card->host, bus_width); } } if (!oldcard) host->card = card; mmc_free_ext_csd(ext_csd); return 0; free_card: if (!oldcard) mmc_remove_card(card); err: mmc_free_ext_csd(ext_csd); return err; }
int ext4_mpage_readpages(struct address_space *mapping, struct list_head *pages, struct page *page, unsigned nr_pages) { struct bio *bio = NULL; sector_t last_block_in_bio = 0; struct inode *inode = mapping->host; const unsigned blkbits = inode->i_blkbits; const unsigned blocks_per_page = PAGE_SIZE >> blkbits; const unsigned blocksize = 1 << blkbits; sector_t block_in_file; sector_t last_block; sector_t last_block_in_file; sector_t blocks[MAX_BUF_PER_PAGE]; unsigned page_block; struct block_device *bdev = inode->i_sb->s_bdev; int length; unsigned relative_block = 0; struct ext4_map_blocks map; map.m_pblk = 0; map.m_lblk = 0; map.m_len = 0; map.m_flags = 0; for (; nr_pages; nr_pages--) { int fully_mapped = 1; unsigned first_hole = blocks_per_page; prefetchw(&page->flags); if (pages) { page = list_entry(pages->prev, struct page, lru); list_del(&page->lru); if (add_to_page_cache_lru(page, mapping, page->index, readahead_gfp_mask(mapping))) goto next_page; } if (page_has_buffers(page)) goto confused; block_in_file = (sector_t)page->index << (PAGE_SHIFT - blkbits); last_block = block_in_file + nr_pages * blocks_per_page; last_block_in_file = (i_size_read(inode) + blocksize - 1) >> blkbits; if (last_block > last_block_in_file) last_block = last_block_in_file; page_block = 0; /* * Map blocks using the previous result first. */ if ((map.m_flags & EXT4_MAP_MAPPED) && block_in_file > map.m_lblk && block_in_file < (map.m_lblk + map.m_len)) { unsigned map_offset = block_in_file - map.m_lblk; unsigned last = map.m_len - map_offset; for (relative_block = 0; ; relative_block++) { if (relative_block == last) { /* needed? */ map.m_flags &= ~EXT4_MAP_MAPPED; break; } if (page_block == blocks_per_page) break; blocks[page_block] = map.m_pblk + map_offset + relative_block; page_block++; block_in_file++; } } /* * Then do more ext4_map_blocks() calls until we are * done with this page. */ while (page_block < blocks_per_page) { if (block_in_file < last_block) { map.m_lblk = block_in_file; map.m_len = last_block - block_in_file; if (ext4_map_blocks(NULL, inode, &map, 0) < 0) { set_error_page: SetPageError(page); zero_user_segment(page, 0, PAGE_SIZE); unlock_page(page); goto next_page; } } if ((map.m_flags & EXT4_MAP_MAPPED) == 0) { fully_mapped = 0; if (first_hole == blocks_per_page) first_hole = page_block; page_block++; block_in_file++; continue; } if (first_hole != blocks_per_page) goto confused; /* hole -> non-hole */ /* Contiguous blocks? */ if (page_block && blocks[page_block-1] != map.m_pblk-1) goto confused; for (relative_block = 0; ; relative_block++) { if (relative_block == map.m_len) { /* needed? */ map.m_flags &= ~EXT4_MAP_MAPPED; break; } else if (page_block == blocks_per_page) break; blocks[page_block] = map.m_pblk+relative_block; page_block++; block_in_file++; } } if (first_hole != blocks_per_page) { zero_user_segment(page, first_hole << blkbits, PAGE_SIZE); if (first_hole == 0) { SetPageUptodate(page); unlock_page(page); goto next_page; } } else if (fully_mapped) { SetPageMappedToDisk(page); } if (fully_mapped && blocks_per_page == 1 && !PageUptodate(page) && cleancache_get_page(page) == 0) { SetPageUptodate(page); goto confused; } /* * This page will go to BIO. Do we need to send this * BIO off first? */ if (bio && (last_block_in_bio != blocks[0] - 1)) { submit_and_realloc: submit_bio(bio); bio = NULL; } if (bio == NULL) { struct fscrypt_ctx *ctx = NULL; if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { ctx = fscrypt_get_ctx(inode, GFP_NOFS); if (IS_ERR(ctx)) goto set_error_page; } bio = bio_alloc(GFP_KERNEL, min_t(int, nr_pages, BIO_MAX_PAGES)); if (!bio) { if (ctx) fscrypt_release_ctx(ctx); goto set_error_page; } bio->bi_bdev = bdev; bio->bi_iter.bi_sector = blocks[0] << (blkbits - 9); bio->bi_end_io = mpage_end_io; bio->bi_private = ctx; bio_set_op_attrs(bio, REQ_OP_READ, 0); } length = first_hole << blkbits; if (bio_add_page(bio, page, length, 0) < length) goto submit_and_realloc; if (((map.m_flags & EXT4_MAP_BOUNDARY) && (relative_block == map.m_len)) || (first_hole != blocks_per_page)) { submit_bio(bio); bio = NULL; } else last_block_in_bio = blocks[blocks_per_page - 1]; goto next_page; confused: if (bio) { submit_bio(bio); bio = NULL; } if (!PageUptodate(page)) block_read_full_page(page, ext4_get_block); else unlock_page(page); next_page: if (pages) put_page(page); } BUG_ON(pages && !list_empty(pages)); if (bio) submit_bio(bio); return 0; }
/* * Decode extended CSD. */ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) { int err = 0; BUG_ON(!card); if (!ext_csd) return 0; /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; if (card->csd.structure == 3) { if (card->ext_csd.raw_ext_csd_structure > 2) { printk(KERN_ERR "%s: unrecognised EXT_CSD structure " "version %d\n", mmc_hostname(card->host), card->ext_csd.raw_ext_csd_structure); err = -EINVAL; goto out; } } card->ext_csd.rev = ext_csd[EXT_CSD_REV]; #ifdef CONFIG_MMC_BCM_SD if (card->ext_csd.rev > 6) { #else if (card->ext_csd.rev > 3) { #endif printk(KERN_ERR "%s: unrecognised EXT_CSD structure " "version %d\n", mmc_hostname(card->host), card->ext_csd.rev); err = -EINVAL; goto out; } card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3]; if (card->ext_csd.rev >= 2) { card->ext_csd.sectors = ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; /* Cards with density > 2GiB are sector addressed */ if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) mmc_card_set_blockaddr(card); } card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52; break; case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V; break; case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V; break; case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; break; case EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 26000000; break; default: /* MMC v4 spec says this cannot happen */ printk(KERN_WARNING "%s: card is mmc v4 but doesn't " "support any high-speed modes.\n", mmc_hostname(card->host)); } card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; card->ext_csd.raw_erase_timeout_mult = ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; card->ext_csd.raw_hc_erase_grp_size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; if (card->ext_csd.rev >= 3) { u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; /* EXT_CSD value is in units of 10ms, but we store in ms */ card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; /* Sleep / awake timeout in 100ns units */ if (sa_shift > 0 && sa_shift <= 0x17) card->ext_csd.sa_timeout = 1 << ext_csd[EXT_CSD_S_A_TIMEOUT]; card->ext_csd.erase_group_def = ext_csd[EXT_CSD_ERASE_GROUP_DEF]; card->ext_csd.hc_erase_timeout = 300 * ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; card->ext_csd.hc_erase_size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C]; /* * There are two boot regions of equal size, defined in * multiples of 128K. */ card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; } card->ext_csd.raw_hc_erase_gap_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; card->ext_csd.raw_sec_trim_mult = ext_csd[EXT_CSD_SEC_TRIM_MULT]; card->ext_csd.raw_sec_erase_mult = ext_csd[EXT_CSD_SEC_ERASE_MULT]; card->ext_csd.raw_sec_feature_support = ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; card->ext_csd.raw_trim_mult = ext_csd[EXT_CSD_TRIM_MULT]; if (card->ext_csd.rev >= 4) { /* * Enhanced area feature support -- check whether the eMMC * card has the Enhanced area enabled. If so, export enhanced * area offset and size to user by adding sysfs interface. */ card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { u8 hc_erase_grp_sz = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; u8 hc_wp_grp_sz = ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; card->ext_csd.enhanced_area_en = 1; /* * calculate the enhanced data area offset, in bytes */ card->ext_csd.enhanced_area_offset = (ext_csd[139] << 24) + (ext_csd[138] << 16) + (ext_csd[137] << 8) + ext_csd[136]; if (mmc_card_blockaddr(card)) card->ext_csd.enhanced_area_offset <<= 9; /* * calculate the enhanced data area size, in kilobytes */ card->ext_csd.enhanced_area_size = (ext_csd[142] << 16) + (ext_csd[141] << 8) + ext_csd[140]; card->ext_csd.enhanced_area_size *= (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); card->ext_csd.enhanced_area_size <<= 9; } else { /* * If the enhanced area is not enabled, disable these * device attributes. */ card->ext_csd.enhanced_area_offset = -EINVAL; card->ext_csd.enhanced_area_size = -EINVAL; } card->ext_csd.sec_trim_mult = ext_csd[EXT_CSD_SEC_TRIM_MULT]; card->ext_csd.sec_erase_mult = ext_csd[EXT_CSD_SEC_ERASE_MULT]; card->ext_csd.sec_feature_support = ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; card->ext_csd.trim_timeout = 300 * ext_csd[EXT_CSD_TRIM_MULT]; card->ext_csd.rpmb_size = ext_csd[EXT_CSD_RPMB_SIZE_MULT] << 17; printk(KERN_INFO "%s: card->ext_csd.rpmb_size: %d\n", __func__, card->ext_csd.rpmb_size); } if (card->ext_csd.rev >= 5) card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) card->erased_byte = 0xFF; else card->erased_byte = 0x0; #ifdef CONFIG_MMC_45_FEATURE_SUPPORT /* eMMC v4.5(Revision 1.6) or later */ if (card->ext_csd.rev >= 6) { /* Discard should be supported */ /* Senitize should be supported */ } #ifdef CONFIG_MMC_DISCARD_SAMSUNG_eMMC_SUPPORT card->ext_csd.optimized_features = ext_csd[EXT_CSD_OPTIMIZED_FEATURES]; #endif #endif out: return err; } static inline void mmc_free_ext_csd(u8 *ext_csd) { kfree(ext_csd); }
/* * Starting point for MMC card init. */ int mmc_attach_mmc(struct mmc_host *host) { int err; u32 ocr; BUG_ON(!host); WARN_ON(!host->claimed); err = mmc_send_op_cond(host, 0, &ocr); if (err) return err; mmc_attach_bus_ops(host); if (host->ocr_avail_mmc) host->ocr_avail = host->ocr_avail_mmc; /* * We need to get OCR a different way for SPI. */ if (mmc_host_is_spi(host)) { err = mmc_spi_read_ocr(host, 1, &ocr); if (err) goto err; } /* * Sanity check the voltages that the card claims to * support. */ if (ocr & 0x7F) { printk(KERN_WARNING "%s: card claims to support voltages " "below the defined range. These will be ignored.\n", mmc_hostname(host)); ocr &= ~0x7F; } host->ocr = mmc_select_voltage(host, ocr); /* * Can we support the voltage of the card? */ if (!host->ocr) { err = -EINVAL; goto err; } /* * Detect and init the card. */ err = mmc_init_card(host, host->ocr, NULL); if (err) goto err; mmc_release_host(host); err = mmc_add_card(host->card); mmc_claim_host(host); if (err) goto remove_card; return 0; remove_card: mmc_release_host(host); mmc_remove_card(host->card); mmc_claim_host(host); host->card = NULL; err: mmc_detach_bus(host); printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", mmc_hostname(host), err); return err; }
int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, void **ret_data) { int ret; unsigned int locklen; struct dlm_ctxt *dlm = data; struct dlm_lock_resource *res = NULL; struct dlm_lock *lock = NULL; struct dlm_proxy_ast *past = (struct dlm_proxy_ast *) msg->buf; char *name; struct list_head *head = NULL; __be64 cookie; u32 flags; u8 node; if (!dlm_grab(dlm)) { dlm_error(DLM_REJECTED); return DLM_REJECTED; } mlog_bug_on_msg(!dlm_domain_fully_joined(dlm), "Domain %s not fully joined!\n", dlm->name); name = past->name; locklen = past->namelen; cookie = past->cookie; flags = be32_to_cpu(past->flags); node = past->node_idx; if (locklen > DLM_LOCKID_NAME_MAX) { ret = DLM_IVBUFLEN; mlog(ML_ERROR, "Invalid name length (%d) in proxy ast " "handler!\n", locklen); goto leave; } if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) == (LKM_PUT_LVB|LKM_GET_LVB)) { mlog(ML_ERROR, "Both PUT and GET lvb specified, (0x%x)\n", flags); ret = DLM_BADARGS; goto leave; } mlog(0, "lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" : (flags & LKM_GET_LVB ? "get lvb" : "none")); mlog(0, "type=%d, blocked_type=%d\n", past->type, past->blocked_type); if (past->type != DLM_AST && past->type != DLM_BAST) { mlog(ML_ERROR, "Unknown ast type! %d, cookie=%u:%llu" "name=%.*s, node=%u\n", past->type, dlm_get_lock_cookie_node(be64_to_cpu(cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), locklen, name, node); ret = DLM_IVLOCKID; goto leave; } res = dlm_lookup_lockres(dlm, name, locklen); if (!res) { mlog(0, "Got %sast for unknown lockres! cookie=%u:%llu, " "name=%.*s, node=%u\n", (past->type == DLM_AST ? "" : "b"), dlm_get_lock_cookie_node(be64_to_cpu(cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), locklen, name, node); ret = DLM_IVLOCKID; goto leave; } /* cannot get a proxy ast message if this node owns it */ BUG_ON(res->owner == dlm->node_num); mlog(0, "%s: res %.*s\n", dlm->name, res->lockname.len, res->lockname.name); spin_lock(&res->spinlock); if (res->state & DLM_LOCK_RES_RECOVERING) { mlog(0, "Responding with DLM_RECOVERING!\n"); ret = DLM_RECOVERING; goto unlock_out; } if (res->state & DLM_LOCK_RES_MIGRATING) { mlog(0, "Responding with DLM_MIGRATING!\n"); ret = DLM_MIGRATING; goto unlock_out; } /* try convert queue for both ast/bast */ head = &res->converting; lock = NULL; list_for_each_entry(lock, head, list) { if (lock->ml.cookie == cookie) goto do_ast; } /* if not on convert, try blocked for ast, granted for bast */ if (past->type == DLM_AST) head = &res->blocked; else head = &res->granted; list_for_each_entry(lock, head, list) { /* if lock is found but unlock is pending ignore the bast */ if (lock->ml.cookie == cookie) { if (lock->unlock_pending) break; goto do_ast; } } mlog(0, "Got %sast for unknown lock! cookie=%u:%llu, name=%.*s, " "node=%u\n", past->type == DLM_AST ? "" : "b", dlm_get_lock_cookie_node(be64_to_cpu(cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), locklen, name, node); ret = DLM_NORMAL; unlock_out: spin_unlock(&res->spinlock); goto leave; do_ast: ret = DLM_NORMAL; if (past->type == DLM_AST) { /* do not alter lock refcount. switching lists. */ list_move_tail(&lock->list, &res->granted); mlog(0, "%s: res %.*s, lock %u:%llu, Granted type %d => %d\n", dlm->name, res->lockname.len, res->lockname.name, dlm_get_lock_cookie_node(be64_to_cpu(cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), lock->ml.type, lock->ml.convert_type); if (lock->ml.convert_type != LKM_IVMODE) { lock->ml.type = lock->ml.convert_type; lock->ml.convert_type = LKM_IVMODE; } else { // should already be there.... } lock->lksb->status = DLM_NORMAL; /* if we requested the lvb, fetch it into our lksb now */ if (flags & LKM_GET_LVB) { BUG_ON(!(lock->lksb->flags & DLM_LKSB_GET_LVB)); memcpy(lock->lksb->lvb, past->lvb, DLM_LVB_LEN); } } spin_unlock(&res->spinlock); if (past->type == DLM_AST) dlm_do_local_ast(dlm, res, lock); else dlm_do_local_bast(dlm, res, lock, past->blocked_type); leave: if (res) dlm_lockres_put(res); dlm_put(dlm); return ret; }
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; mlog_entry("(0x%p, size:%llu)\n", inode, (unsigned long long)le64_to_cpu(fe->i_size)); 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); inode->i_uid = le32_to_cpu(fe->i_uid); inode->i_gid = 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; 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)); inode->i_nlink = ocfs2_read_links_count(fe); 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; mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino); } 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)) { mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino); /* 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)); break; case S_IFLNK: if (ocfs2_inode_is_fast_symlink(inode)) inode->i_op = &ocfs2_fast_symlink_inode_operations; else 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); mlog_exit_void(); }
int fthd_isp_cmd_set_loadfile(struct fthd_private *dev_priv) { struct isp_cmd_set_loadfile cmd; struct isp_mem_obj *file; const struct firmware *fw; const char *filename = NULL; const char *vendor, *board; int ret = 0; pr_debug("set loadfile\n"); vendor = dmi_get_system_info(DMI_BOARD_VENDOR); board = dmi_get_system_info(DMI_BOARD_NAME); memset(&cmd, 0, sizeof(cmd)); switch(dev_priv->sensor_id1) { case 0x164: filename = "facetimehd/8221_01XX.dat"; break; case 0x190: filename = "facetimehd/1222_01XX.dat"; break; case 0x8830: filename = "facetimehd/9112_01XX.dat"; break; case 0x9770: if (vendor && board && !strcmp(vendor, "Apple Inc.") && !strncmp(board, "MacBookAir", sizeof("MacBookAir")-1)) { filename = "facetimehd/1771_01XX.dat"; break; } switch(dev_priv->sensor_id0) { case 4: filename = "facetimehd/1874_01XX.dat"; break; default: filename = "facetimehd/1871_01XX.dat"; break; } break; case 0x9774: switch(dev_priv->sensor_id0) { case 4: filename = "facetimehd/1674_01XX.dat"; break; case 5: filename = "facetimehd/1675_01XX.dat"; break; default: filename = "facetimehd/1671_01XX.dat"; break; } break; default: break; } if (!filename) { pr_err("no set file for sensorid %04x %04x found\n", dev_priv->sensor_id0, dev_priv->sensor_id1); return -EINVAL; } /* The set file is allowed to be missing but we don't get calibration */ ret = request_firmware(&fw, filename, &dev_priv->pdev->dev); if (ret) return 0; /* Firmware memory is preallocated at init time */ BUG_ON(dev_priv->set_file); file = isp_mem_create(dev_priv, FTHD_MEM_SET_FILE, fw->size); FTHD_S2_MEMCPY_TOIO(file->offset, fw->data, fw->size); release_firmware(fw); dev_priv->set_file = file; pr_debug("set file: addr %08lx, size %d\n", file->offset, (int)file->size); cmd.addr = file->offset; cmd.length = file->size; return fthd_isp_cmd(dev_priv, CISP_CMD_CH_SET_FILE_LOAD, &cmd, sizeof(cmd), NULL); }
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; mlog_entry("(0x%p, 0x%p)\n", inode, args); status = -EINVAL; if (inode == NULL || inode->i_sb == NULL) { mlog(ML_ERROR, "bad inode\n"); return status; } sb = inode->i_sb; osb = OCFS2_SB(sb); if (!args) { mlog(ML_ERROR, "bad inode args\n"); make_bad_inode(inode); return status; } /* * 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-accesible 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); /* * 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); if (args && bh) brelse(bh); mlog_exit(status); return status; }
/* * Atomic create+open operation * * If the filesystem doesn't support this, then fall back to separate * 'mknod' + 'open' requests. */ static int fuse_create_open(struct inode *dir, struct dentry *entry, struct file *file, unsigned flags, umode_t mode, int *opened) { int err; struct inode *inode; struct fuse_conn *fc = get_fuse_conn(dir); FUSE_ARGS(args); struct fuse_forget_link *forget; struct fuse_create_in inarg; struct fuse_open_out outopen; struct fuse_entry_out outentry; struct fuse_file *ff; /* Userspace expects S_IFREG in create mode */ BUG_ON((mode & S_IFMT) != S_IFREG); forget = fuse_alloc_forget(); err = -ENOMEM; if (!forget) goto out_err; err = -ENOMEM; ff = fuse_file_alloc(fc); if (!ff) goto out_put_forget_req; if (!fc->dont_mask) mode &= ~current_umask(); flags &= ~O_NOCTTY; memset(&inarg, 0, sizeof(inarg)); memset(&outentry, 0, sizeof(outentry)); inarg.flags = flags; inarg.mode = mode; inarg.umask = current_umask(); args.in.h.opcode = FUSE_CREATE; args.in.h.nodeid = get_node_id(dir); args.in.numargs = 2; args.in.args[0].size = sizeof(inarg); args.in.args[0].value = &inarg; args.in.args[1].size = entry->d_name.len + 1; args.in.args[1].value = entry->d_name.name; args.out.numargs = 2; args.out.args[0].size = sizeof(outentry); args.out.args[0].value = &outentry; args.out.args[1].size = sizeof(outopen); args.out.args[1].value = &outopen; err = fuse_simple_request(fc, &args); if (err) goto out_free_ff; err = -EIO; if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) goto out_free_ff; ff->fh = outopen.fh; ff->nodeid = outentry.nodeid; ff->open_flags = outopen.open_flags; inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, &outentry.attr, entry_attr_timeout(&outentry), 0); if (!inode) { flags &= ~(O_CREAT | O_EXCL | O_TRUNC); fuse_sync_release(ff, flags); fuse_queue_forget(fc, forget, outentry.nodeid, 1); err = -ENOMEM; goto out_err; } kfree(forget); d_instantiate(entry, inode); fuse_change_entry_timeout(entry, &outentry); fuse_invalidate_attr(dir); err = finish_open(file, entry, generic_file_open, opened); if (err) { fuse_sync_release(ff, flags); } else { file->private_data = fuse_file_get(ff); fuse_finish_open(inode, file); } return err; out_free_ff: fuse_file_free(ff); out_put_forget_req: kfree(forget); out_err: return err; }
/* * path points to first direct item of the file regardless of how many of * them are there */ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode, struct treepath *path, struct buffer_head *unbh, loff_t tail_offset) { struct super_block *sb = inode->i_sb; struct buffer_head *up_to_date_bh; struct item_head *p_le_ih = tp_item_head(path); unsigned long total_tail = 0; /* Key to search for the last byte of the converted item. */ struct cpu_key end_key; /* * new indirect item to be inserted or key * of unfm pointer to be pasted */ struct item_head ind_ih; int blk_size; /* returned value for reiserfs_insert_item and clones */ int retval; /* Handle on an unformatted node that will be inserted in the tree. */ unp_t unfm_ptr; BUG_ON(!th->t_trans_id); REISERFS_SB(sb)->s_direct2indirect++; blk_size = sb->s_blocksize; /* * and key to search for append or insert pointer to the new * unformatted node. */ copy_item_head(&ind_ih, p_le_ih); set_le_ih_k_offset(&ind_ih, tail_offset); set_le_ih_k_type(&ind_ih, TYPE_INDIRECT); /* Set the key to search for the place for new unfm pointer */ make_cpu_key(&end_key, inode, tail_offset, TYPE_INDIRECT, 4); /* FIXME: we could avoid this */ if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) { reiserfs_error(sb, "PAP-14030", "pasted or inserted byte exists in " "the tree %K. Use fsck to repair.", &end_key); pathrelse(path); return -EIO; } p_le_ih = tp_item_head(path); unfm_ptr = cpu_to_le32(unbh->b_blocknr); if (is_statdata_le_ih(p_le_ih)) { /* Insert new indirect item. */ set_ih_free_space(&ind_ih, 0); /* delete at nearest future */ put_ih_item_len(&ind_ih, UNFM_P_SIZE); PATH_LAST_POSITION(path)++; retval = reiserfs_insert_item(th, path, &end_key, &ind_ih, inode, (char *)&unfm_ptr); } else { /* Paste into last indirect item of an object. */ retval = reiserfs_paste_into_item(th, path, &end_key, inode, (char *)&unfm_ptr, UNFM_P_SIZE); } if (retval) { return retval; } /* * note: from here there are two keys which have matching first * three key components. They only differ by the fourth one. */ /* Set the key to search for the direct items of the file */ make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT, 4); /* * Move bytes from the direct items to the new unformatted node * and delete them. */ while (1) { int tail_size; /* * end_key.k_offset is set so, that we will always have found * last item of the file */ if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) reiserfs_panic(sb, "PAP-14050", "direct item (%K) not found", &end_key); p_le_ih = tp_item_head(path); RFALSE(!is_direct_le_ih(p_le_ih), "vs-14055: direct item expected(%K), found %h", &end_key, p_le_ih); tail_size = (le_ih_k_offset(p_le_ih) & (blk_size - 1)) + ih_item_len(p_le_ih) - 1; /* * we only send the unbh pointer if the buffer is not * up to date. this avoids overwriting good data from * writepage() with old data from the disk or buffer cache * Special case: unbh->b_page will be NULL if we are coming * through DIRECT_IO handler here. */ if (!unbh->b_page || buffer_uptodate(unbh) || PageUptodate(unbh->b_page)) { up_to_date_bh = NULL; } else { up_to_date_bh = unbh; } retval = reiserfs_delete_item(th, path, &end_key, inode, up_to_date_bh); total_tail += retval; /* done: file does not have direct items anymore */ if (tail_size == retval) break; } /* * if we've copied bytes from disk into the page, we need to zero * out the unused part of the block (it was not up to date before) */ if (up_to_date_bh) { unsigned pgoff = (tail_offset + total_tail - 1) & (PAGE_SIZE - 1); char *kaddr = kmap_atomic(up_to_date_bh->b_page); memset(kaddr + pgoff, 0, blk_size - total_tail); kunmap_atomic(kaddr); } REISERFS_I(inode)->i_first_direct_byte = U32_MAX; return 0; }
static int isl_upload_firmware(islpci_private *priv) { u32 reg, rc; void __iomem *device_base = priv->device_base; /* clear the RAMBoot and the Reset bit */ reg = readl(device_base + ISL38XX_CTRL_STAT_REG); reg &= ~ISL38XX_CTRL_STAT_RESET; reg &= ~ISL38XX_CTRL_STAT_RAMBOOT; writel(reg, device_base + ISL38XX_CTRL_STAT_REG); wmb(); udelay(ISL38XX_WRITEIO_DELAY); /* set the Reset bit without reading the register ! */ reg |= ISL38XX_CTRL_STAT_RESET; writel(reg, device_base + ISL38XX_CTRL_STAT_REG); wmb(); udelay(ISL38XX_WRITEIO_DELAY); /* clear the Reset bit */ reg &= ~ISL38XX_CTRL_STAT_RESET; writel(reg, device_base + ISL38XX_CTRL_STAT_REG); wmb(); /* wait a while for the device to reboot */ mdelay(50); { const struct firmware *fw_entry = NULL; long fw_len; const u32 *fw_ptr; rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV); if (rc) { printk(KERN_ERR "%s: request_firmware() failed for '%s'\n", "prism54", priv->firmware); return rc; } /* prepare the Direct Memory Base register */ reg = ISL38XX_DEV_FIRMWARE_ADDRES; fw_ptr = (u32 *) fw_entry->data; fw_len = fw_entry->size; if (fw_len % 4) { printk(KERN_ERR "%s: firmware '%s' size is not multiple of 32bit, aborting!\n", "prism54", priv->firmware); release_firmware(fw_entry); return -EILSEQ; /* Illegal byte sequence */; } while (fw_len > 0) { long _fw_len = (fw_len > ISL38XX_MEMORY_WINDOW_SIZE) ? ISL38XX_MEMORY_WINDOW_SIZE : fw_len; u32 __iomem *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN; /* set the card's base address for writing the data */ isl38xx_w32_flush(device_base, reg, ISL38XX_DIR_MEM_BASE_REG); wmb(); /* be paranoid */ /* increment the write address for next iteration */ reg += _fw_len; fw_len -= _fw_len; /* write the data to the Direct Memory Window 32bit-wise */ /* memcpy_toio() doesn't guarantee 32bit writes :-| */ while (_fw_len > 0) { /* use non-swapping writel() */ __raw_writel(*fw_ptr, dev_fw_ptr); fw_ptr++, dev_fw_ptr++; _fw_len -= 4; } /* flush PCI posting */ (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH); wmb(); /* be paranoid again */ BUG_ON(_fw_len != 0); } BUG_ON(fw_len != 0); /* Firmware version is at offset 40 (also for "newmac") */ printk(KERN_DEBUG "%s: firmware version: %.8s\n", priv->ndev->name, fw_entry->data + 40); release_firmware(fw_entry); } /* now reset the device * clear the Reset & ClkRun bit, set the RAMBoot bit */ reg = readl(device_base + ISL38XX_CTRL_STAT_REG); reg &= ~ISL38XX_CTRL_STAT_CLKRUN; reg &= ~ISL38XX_CTRL_STAT_RESET; reg |= ISL38XX_CTRL_STAT_RAMBOOT; isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG); wmb(); udelay(ISL38XX_WRITEIO_DELAY); /* set the reset bit latches the host override and RAMBoot bits * into the device for operation when the reset bit is reset */ reg |= ISL38XX_CTRL_STAT_RESET; writel(reg, device_base + ISL38XX_CTRL_STAT_REG); /* don't do flush PCI posting here! */ wmb(); udelay(ISL38XX_WRITEIO_DELAY); /* clear the reset bit should start the whole circus */ reg &= ~ISL38XX_CTRL_STAT_RESET; writel(reg, device_base + ISL38XX_CTRL_STAT_REG); /* don't do flush PCI posting here! */ wmb(); udelay(ISL38XX_WRITEIO_DELAY); return 0; }
static void print_extent_item(struct extent_buffer *eb, int slot) { struct btrfs_extent_item *ei; struct btrfs_extent_inline_ref *iref; struct btrfs_extent_data_ref *dref; struct btrfs_shared_data_ref *sref; struct btrfs_disk_key key; unsigned long end; unsigned long ptr; int type; u32 item_size = btrfs_item_size_nr(eb, slot); u64 flags; u64 offset; if (item_size < sizeof(*ei)) { #ifdef BTRFS_COMPAT_EXTENT_TREE_V0 struct btrfs_extent_item_v0 *ei0; BUG_ON(item_size != sizeof(*ei0)); ei0 = btrfs_item_ptr(eb, slot, struct btrfs_extent_item_v0); printk(KERN_INFO "\t\textent refs %u\n", btrfs_extent_refs_v0(eb, ei0)); return; #else BUG(); #endif } ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item); flags = btrfs_extent_flags(eb, ei); printk(KERN_INFO "\t\textent refs %llu gen %llu flags %llu\n", (unsigned long long)btrfs_extent_refs(eb, ei), (unsigned long long)btrfs_extent_generation(eb, ei), (unsigned long long)flags); if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { struct btrfs_tree_block_info *info; info = (struct btrfs_tree_block_info *)(ei + 1); btrfs_tree_block_key(eb, info, &key); printk(KERN_INFO "\t\ttree block key (%llu %x %llu) " "level %d\n", (unsigned long long)btrfs_disk_key_objectid(&key), key.type, (unsigned long long)btrfs_disk_key_offset(&key), btrfs_tree_block_level(eb, info)); iref = (struct btrfs_extent_inline_ref *)(info + 1); } else { iref = (struct btrfs_extent_inline_ref *)(ei + 1); } ptr = (unsigned long)iref; end = (unsigned long)ei + item_size; while (ptr < end) { iref = (struct btrfs_extent_inline_ref *)ptr; type = btrfs_extent_inline_ref_type(eb, iref); offset = btrfs_extent_inline_ref_offset(eb, iref); switch (type) { case BTRFS_TREE_BLOCK_REF_KEY: printk(KERN_INFO "\t\ttree block backref " "root %llu\n", (unsigned long long)offset); break; case BTRFS_SHARED_BLOCK_REF_KEY: printk(KERN_INFO "\t\tshared block backref " "parent %llu\n", (unsigned long long)offset); break; case BTRFS_EXTENT_DATA_REF_KEY: dref = (struct btrfs_extent_data_ref *)(&iref->offset); print_extent_data_ref(eb, dref); break; case BTRFS_SHARED_DATA_REF_KEY: sref = (struct btrfs_shared_data_ref *)(iref + 1); printk(KERN_INFO "\t\tshared data backref " "parent %llu count %u\n", (unsigned long long)offset, btrfs_shared_data_ref_count(eb, sref)); break; default: BUG(); } ptr += btrfs_extent_inline_ref_size(type); } WARN_ON(ptr > end); }
int AppLayerParserFromFile(AppProto alproto, char *filename) { int result = 1; Flow *f = NULL; TcpSession ssn; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&ssn, 0, sizeof(ssn)); f = SCCalloc(1, sizeof(Flow)); if (f == NULL) goto end; FLOW_INITIALIZE(f); f->flags |= FLOW_IPV4; f->src.addr_data32[0] = 0x01020304; f->dst.addr_data32[0] = 0x05060708; f->sp = 10000; f->dp = 80; f->protoctx = &ssn; f->proto = IPPROTO_TCP; f->alproto = alproto; uint8_t buffer[64]; #ifdef AFLFUZZ_PERSISTANT_MODE while (__AFL_LOOP(1000)) { /* reset state */ memset(buffer, 0, sizeof(buffer)); #endif /* AFLFUZZ_PERSISTANT_MODE */ FILE *fp = fopen(filename, "r"); BUG_ON(fp == NULL); int start = 1; int flip = 0; while (1) { int done = 0; size_t result = fread(&buffer, 1, sizeof(buffer), fp); if (result < sizeof(buffer)) done = 1; //SCLogInfo("result %u done %d start %d", (uint)result, done, start); uint8_t flags = 0; if (flip) { flags = STREAM_TOCLIENT; flip = 0; } else { flags = STREAM_TOSERVER; flip = 1; } if (start--) { flags |= STREAM_START; } if (done) { flags |= STREAM_EOF; } //PrintRawDataFp(stdout, buffer, result); (void)AppLayerParserParse(alp_tctx, f, alproto, flags, buffer, result); if (done) break; } fclose(fp); #ifdef AFLFUZZ_PERSISTANT_MODE } #endif /* AFLFUZZ_PERSISTANT_MODE */ result = 0; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (f != NULL) { FlowFree(f); } return result; }
static inline unsigned p2m_top_index(unsigned long pfn) { BUG_ON(pfn >= MAX_DOMAIN_PAGES); return pfn / P2M_ENTRIES_PER_PAGE; }
/** * \brief Get 'active' tx id, meaning the lowest id that still need work. * * \retval id tx id */ static uint64_t AppLayerTransactionGetActive(Flow *f, uint8_t flags) { BUG_ON(AppLayerGetActiveTxIdFuncPtr == NULL); return AppLayerGetActiveTxIdFuncPtr(f, flags); }
static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { struct virtio_blk *vblk = hctx->queue->queuedata; struct request *req = bd->rq; struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); unsigned long flags; unsigned int num; int qid = hctx->queue_num; int err; bool notify = false; u32 type; BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); switch (req_op(req)) { case REQ_OP_READ: case REQ_OP_WRITE: type = 0; break; case REQ_OP_FLUSH: type = VIRTIO_BLK_T_FLUSH; break; case REQ_OP_SCSI_IN: case REQ_OP_SCSI_OUT: type = VIRTIO_BLK_T_SCSI_CMD; break; case REQ_OP_DRV_IN: type = VIRTIO_BLK_T_GET_ID; break; default: WARN_ON_ONCE(1); return BLK_MQ_RQ_QUEUE_ERROR; } vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, type); vbr->out_hdr.sector = type ? 0 : cpu_to_virtio64(vblk->vdev, blk_rq_pos(req)); vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(req)); blk_mq_start_request(req); num = blk_rq_map_sg(hctx->queue, req, vbr->sg); if (num) { if (rq_data_dir(req) == WRITE) vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_OUT); else vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_IN); } spin_lock_irqsave(&vblk->vqs[qid].lock, flags); if (req_op(req) == REQ_OP_SCSI_IN || req_op(req) == REQ_OP_SCSI_OUT) err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num); else err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); if (err) { virtqueue_kick(vblk->vqs[qid].vq); blk_mq_stop_hw_queue(hctx); spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); /* Out of mem doesn't actually happen, since we fall back * to direct descriptors */ if (err == -ENOMEM || err == -ENOSPC) return BLK_MQ_RQ_QUEUE_BUSY; return BLK_MQ_RQ_QUEUE_ERROR; } if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) notify = true; spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); if (notify) virtqueue_notify(vblk->vqs[qid].vq); return BLK_MQ_RQ_QUEUE_OK; }
int AppLayerParserParse(AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len) { SCEnter(); #ifdef DEBUG_VALIDATION BUG_ON(f->protomap != FlowGetProtoMapping(f->proto)); #endif AppLayerParserState *pstate = NULL; AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][alproto]; void *alstate = NULL; /* we don't have the parser registered for this protocol */ if (p->StateAlloc == NULL) goto end; /* Do this check before calling AppLayerParse */ if (flags & STREAM_GAP) { SCLogDebug("stream gap detected (missing packets), " "this is not yet supported."); if (f->alstate != NULL) AppLayerParserStreamTruncated(f->proto, alproto, f->alstate, flags); goto error; } /* Get the parser state (if any) */ pstate = f->alparser; if (pstate == NULL) { f->alparser = pstate = AppLayerParserStateAlloc(); if (pstate == NULL) goto error; } pstate->version++; SCLogDebug("app layer parser state version incremented to %"PRIu8, pstate->version); if (flags & STREAM_EOF) AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF); alstate = f->alstate; if (alstate == NULL) { f->alstate = alstate = p->StateAlloc(); if (alstate == NULL) goto error; SCLogDebug("alloced new app layer state %p (name %s)", alstate, AppLayerGetProtoName(f->alproto)); } else { SCLogDebug("using existing app layer state %p (name %s))", alstate, AppLayerGetProtoName(f->alproto)); } /* invoke the recursive parser, but only on data. We may get empty msgs on EOF */ if (input_len > 0 || (flags & STREAM_EOF)) { /* invoke the parser */ if (p->Parser[(flags & STREAM_TOSERVER) ? 0 : 1](f, alstate, pstate, input, input_len, alp_tctx->alproto_local_storage[f->protomap][alproto]) < 0) { goto error; } } /* set the packets to no inspection and reassembly if required */ if (pstate->flags & APP_LAYER_PARSER_NO_INSPECTION) { AppLayerParserSetEOF(pstate); FlowSetNoPayloadInspectionFlag(f); if (f->proto == IPPROTO_TCP) { StreamTcpDisableAppLayer(f); /* Set the no reassembly flag for both the stream in this TcpSession */ if (pstate->flags & APP_LAYER_PARSER_NO_REASSEMBLY) { /* Used only if it's TCP */ TcpSession *ssn = f->protoctx; if (ssn != NULL) { StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0); StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0); } } } } /* In cases like HeartBleed for TLS we need to inspect AppLayer but not Payload */ if (!(f->flags & FLOW_NOPAYLOAD_INSPECTION) && pstate->flags & APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD) { FlowSetNoPayloadInspectionFlag(f); /* Set the no reassembly flag for both the stream in this TcpSession */ if (f->proto == IPPROTO_TCP) { /* Used only if it's TCP */ TcpSession *ssn = f->protoctx; if (ssn != NULL) { StreamTcpSetDisableRawReassemblyFlag(ssn, 0); StreamTcpSetDisableRawReassemblyFlag(ssn, 1); } } } /* next, see if we can get rid of transactions now */ AppLayerParserTransactionsCleanup(f); /* stream truncated, inform app layer */ if (flags & STREAM_DEPTH) AppLayerParserStreamTruncated(f->proto, alproto, alstate, flags); end: SCReturnInt(0); error: /* Set the no app layer inspection flag for both * the stream in this Flow */ if (f->proto == IPPROTO_TCP) { StreamTcpDisableAppLayer(f); } AppLayerParserSetEOF(pstate); SCReturnInt(-1); }
static int eth_xmit(struct sk_buff *skb, struct net_device *dev) { struct port *port = netdev_priv(dev); unsigned int txreadyq = port->plat->txreadyq; int len, offset, bytes, n; void *mem; u32 phys; struct desc *desc; #if DEBUG_TX printk(KERN_DEBUG "%s: eth_xmit\n", dev->name); #endif if (unlikely(skb->len > MAX_MRU)) { dev_kfree_skb(skb); dev->stats.tx_errors++; return NETDEV_TX_OK; } debug_pkt(dev, "eth_xmit", skb->data, skb->len); len = skb->len; #ifdef __ARMEB__ offset = 0; /* no need to keep alignment */ bytes = len; mem = skb->data; #else offset = (int)skb->data & 3; /* keep 32-bit alignment */ bytes = ALIGN(offset + len, 4); if (!(mem = kmalloc(bytes, GFP_ATOMIC))) { dev_kfree_skb(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; } memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4); dev_kfree_skb(skb); #endif phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE); if (dma_mapping_error(&dev->dev, phys)) { #ifdef __ARMEB__ dev_kfree_skb(skb); #else kfree(mem); #endif dev->stats.tx_dropped++; return NETDEV_TX_OK; } n = queue_get_desc(txreadyq, port, 1); BUG_ON(n < 0); desc = tx_desc_ptr(port, n); #ifdef __ARMEB__ port->tx_buff_tab[n] = skb; #else port->tx_buff_tab[n] = mem; #endif desc->data = phys + offset; desc->buf_len = desc->pkt_len = len; /* NPE firmware pads short frames with zeros internally */ wmb(); queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc); dev->trans_start = jiffies; if (qmgr_stat_empty(txreadyq)) { #if DEBUG_TX printk(KERN_DEBUG "%s: eth_xmit queue full\n", dev->name); #endif netif_stop_queue(dev); /* we could miss TX ready interrupt */ if (!qmgr_stat_empty(txreadyq)) { #if DEBUG_TX printk(KERN_DEBUG "%s: eth_xmit ready again\n", dev->name); #endif netif_wake_queue(dev); } } #if DEBUG_TX printk(KERN_DEBUG "%s: eth_xmit end\n", dev->name); #endif return NETDEV_TX_OK; }
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; mlog(0, "Validating dinode %llu\n", (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; }
/* Kick device. Returns: 0 - queue is empty or throttled. >0 - queue is not empty. NOTE: Called under dev->queue_lock with locally disabled BH. */ static inline int qdisc_restart(struct net_device *dev) { struct Qdisc *q = dev->qdisc; struct sk_buff *skb; /* Dequeue packet */ if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) { unsigned nolock = (dev->features & NETIF_F_LLTX); dev->gso_skb = NULL; /* * When the driver has LLTX set it does its own locking * in start_xmit. No need to add additional overhead by * locking again. These checks are worth it because * even uncongested locks can be quite expensive. * The driver can do trylock like here too, in case * of lock congestion it should return -1 and the packet * will be requeued. */ if (!nolock) { if (!netif_tx_trylock(dev)) { collision: /* So, someone grabbed the driver. */ /* It may be transient configuration error, when hard_start_xmit() recurses. We detect it by checking xmit owner and drop the packet when deadloop is detected. */ if (dev->xmit_lock_owner == smp_processor_id()) { kfree_skb(skb); if (net_ratelimit()) printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name); goto out; } __get_cpu_var(netdev_rx_stat).cpu_collision++; goto requeue; } } { /* And release queue */ spin_unlock(&dev->queue_lock); if (!netif_queue_stopped(dev)) { int ret; ret = dev_hard_start_xmit(skb, dev); if (ret == NETDEV_TX_OK) { if (!nolock) { netif_tx_unlock(dev); } spin_lock(&dev->queue_lock); q = dev->qdisc; goto out; } if (ret == NETDEV_TX_LOCKED && nolock) { spin_lock(&dev->queue_lock); q = dev->qdisc; goto collision; } } /* NETDEV_TX_BUSY - we need to requeue */ /* Release the driver */ if (!nolock) { netif_tx_unlock(dev); } spin_lock(&dev->queue_lock); q = dev->qdisc; } /* Device kicked us out :( This is possible in three cases: 0. driver is locked 1. fastroute is enabled 2. device cannot determine busy state before start of transmission (f.e. dialout) 3. device is buggy (ppp) */ requeue: if (unlikely(q == &noop_qdisc)) kfree_skb(skb); else if (skb->next) dev->gso_skb = skb; else q->ops->requeue(skb, q); netif_schedule(dev); } return 0; out: BUG_ON((int) q->q.qlen < 0); return q->q.qlen; }
const u8 *iwl_legacy_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { BUG_ON(offset >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[offset]; }