/* Initialize the file system structure from disk */ int fs_init(mem_sblock_t sbp) { blocknum_t inode_bitmap_size; blocknum_t block_bitmap_size; blocknum_t i; sbp->filesys_lock = semaphore_new(1); if (NULL == sbp->filesys_lock) { return -1; } fs_lock(sbp); sblock_get(maindisk, sbp); sblock_put(sbp); if (sblock_isvalid(sbp) != 1) { sblock_print(sbp); kprintf("File system is not recognized. "); kprintf("Recommend running './mkfs <blocks>'.\n"); return -2; } inode_bitmap_size = sbp->inode_bitmap_last - sbp->inode_bitmap_first + 1; sbp->inode_bitmap = malloc(inode_bitmap_size * DISK_BLOCK_SIZE); block_bitmap_size = sbp->block_bitmap_last - sbp->block_bitmap_first + 1; sbp->block_bitmap = malloc(block_bitmap_size * DISK_BLOCK_SIZE); if (NULL == sbp->block_bitmap || NULL == sbp->inode_bitmap) { semaphore_V(sbp->filesys_lock); return -1; } /* Get disk bitmap */ for (i = sbp->inode_bitmap_first; i <= sbp->inode_bitmap_last; ++i) { bpull(i, (char*) sbp->inode_bitmap + (i - sbp->inode_bitmap_first) * DISK_BLOCK_SIZE); } for (i = sbp->block_bitmap_first; i <= sbp->block_bitmap_last; ++i) { bpull(i, (char*) sbp->block_bitmap + (i - sbp->block_bitmap_first) * DISK_BLOCK_SIZE); } /* Count free inodes and free blocks */ mainsb->free_inodes = bitmap_count_zero(mainsb->inode_bitmap, mainsb->total_inodes); mainsb->free_blocks = bitmap_count_zero(mainsb->block_bitmap, mainsb->disk_num_blocks); fs_unlock(sbp); return 0; }
/*Transmit interface*/ static int sprdwl_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sprdwl_priv *priv = netdev_priv(dev); struct sblock blk; int ret; u8 *addr = NULL; #ifdef CONFIG_SPRDWL_FW_ZEROCOPY if (priv->tx_free < TX_FLOW_LOW) { dev_err(&dev->dev, "tx flow control full\n"); netif_stop_queue(dev); priv->ndev->stats.tx_fifo_errors++; return NETDEV_TX_BUSY; } #endif /*Get a free sblock.*/ ret = sblock_get(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk, 0); if (ret) { dev_err(&dev->dev, "Failed to get free sblock (%d)!\n", ret); netif_stop_queue(dev); priv->ndev->stats.tx_fifo_errors++; return NETDEV_TX_BUSY; } if (blk.length < skb->len) { dev_err(&dev->dev, "The size of sblock is so tiny!\n"); priv->ndev->stats.tx_fifo_errors++; sblock_put(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk); dev_kfree_skb_any(skb); priv->txrcnt = 0; return NETDEV_TX_OK; } #ifdef CONFIG_SPRDWL_FW_ZEROCOPY addr = blk.addr + SIPC_TRANS_OFFSET; #else addr = blk.addr; #endif priv->tx_free--; if (priv->connect_status == SPRDWL_CONNECTED && priv->cipher_type == SPRDWL_CIPHER_WAPI && /* priv->key_len[GROUP][priv->key_index[GROUP]] != 0 &&*/ priv->key_len[PAIRWISE][priv->key_index[PAIRWISE]] != 0 && (*(u16 *)((u8 *)skb->data + ETH_PKT_TYPE_OFFSET) != 0xb488)) { memcpy(((u8 *)addr), skb->data, ETHERNET_HDR_LEN); blk.length = wlan_tx_wapi_encryption(priv, skb->data, (skb->len - ETHERNET_HDR_LEN), ((u8 *)addr + ETHERNET_HDR_LEN)) + ETHERNET_HDR_LEN; } else { blk.length = skb->len; memcpy(((u8 *)addr), skb->data, skb->len); } #ifdef DUMP_TRANSMIT_PACKET print_hex_dump(KERN_DEBUG, "transmit packet: ", DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, 0); #endif ret = sblock_send(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk); if (ret) { dev_err(&dev->dev, "Failed to send sblock (%d)!\n", ret); sblock_put(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk); priv->tx_free++; priv->ndev->stats.tx_fifo_errors++; if (priv->txrcnt > SETH_RESEND_MAX_NUM) netif_stop_queue(dev); priv->txrcnt++; return NETDEV_TX_BUSY; } /*Statistics*/ priv->ndev->stats.tx_bytes += skb->len; priv->ndev->stats.tx_packets++; dev->trans_start = jiffies; priv->txrcnt = 0; dev_kfree_skb_any(skb); return NETDEV_TX_OK; }