diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-18 21:05:34 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-18 21:05:34 +0300 |
commit | e6874fc29410fabfdbc8c12b467f41a16cbcfd2b (patch) | |
tree | bb869a9b481a6c05bf334a0a4db0b1397ce4ca90 /drivers/staging | |
parent | e444d51b14c4795074f485c79debd234931f0e49 (diff) | |
parent | 3fb73eddba106ad2a265a5c5c29d14b0ed6aaee1 (diff) | |
download | linux-e6874fc29410fabfdbc8c12b467f41a16cbcfd2b.tar.xz |
Merge tag 'staging-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging and IIO driver updates from Greg KH:
"Here is the big staging/iio driver update for 5.4-rc1.
Lots of churn here, with a few driver/filesystems moving out of
staging finally:
- erofs moved out of staging
- greybus core code moved out of staging
Along with that, a new filesytem has been added:
- extfat
to provide support for those devices requiring that filesystem (i.e.
transfer devices to/from windows systems or printers)
Other than that, there a number of new IIO drivers, and lots and lots
and lots of staging driver cleanups and minor fixes as people continue
to dig into those for easy changes.
All of these have been in linux-next for a while with no reported
issues"
* tag 'staging-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (453 commits)
Staging: gasket: Use temporaries to reduce line length.
Staging: octeon: Avoid several usecases of strcpy
staging: vhciq_core: replace snprintf with scnprintf
staging: wilc1000: avoid twice IRQ handler execution for each single interrupt
staging: wilc1000: remove unused interrupt status handling code
staging: fbtft: make several arrays static const, makes object smaller
staging: rtl8188eu: make two arrays static const, makes object smaller
staging: rtl8723bs: core: Remove Macro "IS_MAC_ADDRESS_BROADCAST"
dt-bindings: anybus-controller: move to staging/ tree
staging: emxx_udc: remove local TRUE/FALSE definition
staging: wilc1000: look for rtc_clk clock
staging: dt-bindings: wilc1000: add optional rtc_clk property
staging: nvec: make use of devm_platform_ioremap_resource
staging: exfat: drop unused function parameter
Staging: exfat: Avoid use of strcpy
staging: exfat: use integer constants
staging: exfat: cleanup spacing for casts
staging: exfat: cleanup spacing for operators
staging: rtl8723bs: hal: remove redundant variable n
staging: pi433: Fix typo in documentation
...
Diffstat (limited to 'drivers/staging')
315 files changed, 13004 insertions, 26991 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index cf419d9c942d..b9c7f0dc653b 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -112,8 +112,6 @@ source "drivers/staging/gasket/Kconfig" source "drivers/staging/axis-fifo/Kconfig" -source "drivers/staging/erofs/Kconfig" - source "drivers/staging/fieldbus/Kconfig" source "drivers/staging/kpc2000/Kconfig" @@ -123,4 +121,6 @@ source "drivers/staging/isdn/Kconfig" source "drivers/staging/wusbcore/Kconfig" source "drivers/staging/uwb/Kconfig" +source "drivers/staging/exfat/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 38179bc842a8..4b5962006c4b 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -46,9 +46,9 @@ obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ -obj-$(CONFIG_EROFS_FS) += erofs/ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ obj-$(CONFIG_KPC2000) += kpc2000/ obj-$(CONFIG_ISDN_CAPI) += isdn/ obj-$(CONFIG_UWB) += uwb/ obj-$(CONFIG_USB_WUSB) += wusbcore/ +obj-$(CONFIG_EXFAT_FS) += exfat/ diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO index fbf015cc6d62..767dd98fd92d 100644 --- a/drivers/staging/android/TODO +++ b/drivers/staging/android/TODO @@ -6,8 +6,6 @@ TODO: ion/ - - Add dt-bindings for remaining heaps (chunk and carveout heaps). This would - involve putting appropriate bindings in a memory node for Ion to find. - Split /dev/ion up into multiple nodes (e.g. /dev/ion/heap0) - Better test framework (integration with VGEM was suggested) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 92c2914239e3..e6b1ca141b93 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -30,32 +30,6 @@ static struct ion_device *internal_dev; static int heap_id; /* this function should only be called while dev->lock is held */ -static void ion_buffer_add(struct ion_device *dev, - struct ion_buffer *buffer) -{ - struct rb_node **p = &dev->buffers.rb_node; - struct rb_node *parent = NULL; - struct ion_buffer *entry; - - while (*p) { - parent = *p; - entry = rb_entry(parent, struct ion_buffer, node); - - if (buffer < entry) { - p = &(*p)->rb_left; - } else if (buffer > entry) { - p = &(*p)->rb_right; - } else { - pr_err("%s: buffer already found.", __func__); - BUG(); - } - } - - rb_link_node(&buffer->node, parent, p); - rb_insert_color(&buffer->node, &dev->buffers); -} - -/* this function should only be called while dev->lock is held */ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, struct ion_device *dev, unsigned long len, @@ -100,9 +74,6 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, INIT_LIST_HEAD(&buffer->attachments); mutex_init(&buffer->lock); - mutex_lock(&dev->buffer_lock); - ion_buffer_add(dev, buffer); - mutex_unlock(&dev->buffer_lock); return buffer; err1: @@ -131,11 +102,6 @@ void ion_buffer_destroy(struct ion_buffer *buffer) static void _ion_buffer_destroy(struct ion_buffer *buffer) { struct ion_heap *heap = buffer->heap; - struct ion_device *dev = buffer->dev; - - mutex_lock(&dev->buffer_lock); - rb_erase(&buffer->node, &dev->buffers); - mutex_unlock(&dev->buffer_lock); if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) ion_heap_freelist_add(heap, buffer); @@ -694,8 +660,6 @@ static int ion_device_create(void) } idev->debug_root = debugfs_create_dir("ion", NULL); - idev->buffers = RB_ROOT; - mutex_init(&idev->buffer_lock); init_rwsem(&idev->lock); plist_head_init(&idev->heaps); internal_dev = idev; diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index e291299fd35f..74914a266e25 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -23,7 +23,6 @@ /** * struct ion_buffer - metadata for a particular buffer - * @node: node in the ion_device buffers tree * @list: element in list of deferred freeable buffers * @dev: back pointer to the ion_device * @heap: back pointer to the heap the buffer came from @@ -39,10 +38,7 @@ * @attachments: list of devices attached to this buffer */ struct ion_buffer { - union { - struct rb_node node; - struct list_head list; - }; + struct list_head list; struct ion_device *dev; struct ion_heap *heap; unsigned long flags; @@ -61,14 +57,10 @@ void ion_buffer_destroy(struct ion_buffer *buffer); /** * struct ion_device - the metadata of the ion device node * @dev: the actual misc device - * @buffers: an rb tree of all the existing buffers - * @buffer_lock: lock protecting the tree of buffers * @lock: rwsem protecting the tree of heaps and clients */ struct ion_device { struct miscdevice dev; - struct rb_root buffers; - struct mutex buffer_lock; struct rw_semaphore lock; struct plist_head heaps; struct dentry *debug_root; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index aabcda3f9fc8..28603dfadce2 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -665,11 +665,6 @@ static void db2k_initialize_adc(struct comedi_device *dev) db2k_initialize_tmrs(dev); } -static void db2k_initialize_dac(struct comedi_device *dev) -{ - db2k_dac_disarm(dev); -} - static int db2k_8255_cb(struct comedi_device *dev, int dir, int port, int data, unsigned long iobase) { @@ -719,7 +714,7 @@ static int db2k_auto_attach(struct comedi_device *dev, unsigned long context) return result; db2k_initialize_adc(dev); - db2k_initialize_dac(dev); + db2k_dac_disarm(dev); s = &dev->subdevices[0]; /* ai subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index c175227009f1..f98e3ae27bff 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -596,7 +596,7 @@ static int ni_request_ao_mite_channel(struct comedi_device *dev) if (!mite_chan) { spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); dev_err(dev->class_dev, - "failed to reserve mite dma channel for analog outut\n"); + "failed to reserve mite dma channel for analog output\n"); return -EBUSY; } mite_chan->dir = COMEDI_OUTPUT; diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 3cc40d2544be..54d7605e909f 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1074,7 +1074,7 @@ static int usbduxsigma_pwm_period(struct comedi_device *dev, unsigned int period) { struct usbduxsigma_private *devpriv = dev->private; - int fx2delay = 255; + int fx2delay; if (period < MIN_PWM_PERIOD) return -EAGAIN; diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 4f3c2c13a225..147481bf680c 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -165,7 +165,7 @@ static void _nbu2ss_create_ep0_packet(struct nbu2ss_udc *udc, udc->ep0_req.req.buf = p_buf; udc->ep0_req.req.length = length; udc->ep0_req.req.dma = 0; - udc->ep0_req.req.zero = TRUE; + udc->ep0_req.req.zero = true; udc->ep0_req.req.complete = _nbu2ss_ep0_complete; udc->ep0_req.req.status = -EINPROGRESS; udc->ep0_req.req.context = udc; @@ -668,7 +668,7 @@ static int _nbu2ss_ep0_in_transfer(struct nbu2ss_udc *udc, if ((req->req.actual % EP0_PACKETSIZE) == 0) { if (req->zero) { req->zero = false; - EP0_send_NULL(udc, FALSE); + EP0_send_NULL(udc, false); return 1; } } @@ -695,7 +695,7 @@ static int _nbu2ss_ep0_in_transfer(struct nbu2ss_udc *udc, i_remain_size -= result; if (i_remain_size == 0) { - EP0_send_NULL(udc, FALSE); + EP0_send_NULL(udc, false); return result; } @@ -754,7 +754,7 @@ static int _nbu2ss_ep0_out_transfer(struct nbu2ss_udc *udc, if ((req->req.actual % EP0_PACKETSIZE) == 0) { if (req->zero) { req->zero = false; - EP0_receive_NULL(udc, FALSE); + EP0_receive_NULL(udc, false); return 1; } } @@ -799,7 +799,7 @@ static int _nbu2ss_out_dma(struct nbu2ss_udc *udc, struct nbu2ss_req *req, if (req->dma_flag) return 1; /* DMA is forwarded */ - req->dma_flag = TRUE; + req->dma_flag = true; p_buffer = req->req.dma; p_buffer += req->req.actual; @@ -997,7 +997,7 @@ static int _nbu2ss_in_dma(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep, if (req->req.actual == 0) _nbu2ss_dma_map_single(udc, ep, req, USB_DIR_IN); #endif - req->dma_flag = TRUE; + req->dma_flag = true; /* MAX Packet Size */ mpkt = _nbu2ss_readl(&preg->EP_REGS[num].EP_PCKT_ADRS) & EPN_MPKT; @@ -1166,7 +1166,7 @@ static int _nbu2ss_start_transfer(struct nbu2ss_udc *udc, { int nret = -EINVAL; - req->dma_flag = FALSE; + req->dma_flag = false; req->div_len = 0; if (req->req.length == 0) { @@ -1190,7 +1190,7 @@ static int _nbu2ss_start_transfer(struct nbu2ss_udc *udc, break; case EP0_IN_STATUS_PHASE: - nret = EP0_send_NULL(udc, TRUE); + nret = EP0_send_NULL(udc, true); break; default: @@ -1216,7 +1216,7 @@ static int _nbu2ss_start_transfer(struct nbu2ss_udc *udc, static void _nbu2ss_restert_transfer(struct nbu2ss_ep *ep) { u32 length; - bool bflag = FALSE; + bool bflag = false; struct nbu2ss_req *req; req = list_first_entry_or_null(&ep->queue, struct nbu2ss_req, queue); @@ -1229,7 +1229,7 @@ static void _nbu2ss_restert_transfer(struct nbu2ss_ep *ep) length &= EPN_LDATA; if (length < ep->ep.maxpacket) - bflag = TRUE; + bflag = true; } _nbu2ss_start_transfer(ep->udc, ep, req, bflag); @@ -1280,7 +1280,7 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, if (bstall) { /* Set STALL */ - ep->halted = TRUE; + ep->halted = true; if (ep_adrs & USB_DIR_IN) data = EPN_BCLR | EPN_ISTL; @@ -1290,7 +1290,7 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, _nbu2ss_bitset(&preg->EP_REGS[num].EP_CONTROL, data); } else { /* Clear STALL */ - ep->stalled = FALSE; + ep->stalled = false; if (ep_adrs & USB_DIR_IN) { _nbu2ss_bitclr(&preg->EP_REGS[num].EP_CONTROL , EPN_ISTL); @@ -1305,9 +1305,9 @@ static void _nbu2ss_set_endpoint_stall(struct nbu2ss_udc *udc, , data); } - ep->stalled = FALSE; + ep->stalled = false; if (ep->halted) { - ep->halted = FALSE; + ep->halted = false; _nbu2ss_restert_transfer(ep); } } @@ -1533,13 +1533,13 @@ static int std_req_get_status(struct nbu2ss_udc *udc) /*-------------------------------------------------------------------------*/ static int std_req_clear_feature(struct nbu2ss_udc *udc) { - return _nbu2ss_req_feature(udc, FALSE); + return _nbu2ss_req_feature(udc, false); } /*-------------------------------------------------------------------------*/ static int std_req_set_feature(struct nbu2ss_udc *udc) { - return _nbu2ss_req_feature(udc, TRUE); + return _nbu2ss_req_feature(udc, true); } /*-------------------------------------------------------------------------*/ @@ -1601,7 +1601,7 @@ static inline void _nbu2ss_read_request_data(struct nbu2ss_udc *udc, u32 *pdata) /*-------------------------------------------------------------------------*/ static inline int _nbu2ss_decode_request(struct nbu2ss_udc *udc) { - bool bcall_back = TRUE; + bool bcall_back = true; int nret = -EINVAL; struct usb_ctrlrequest *p_ctrl; @@ -1623,22 +1623,22 @@ static inline int _nbu2ss_decode_request(struct nbu2ss_udc *udc) switch (p_ctrl->bRequest) { case USB_REQ_GET_STATUS: nret = std_req_get_status(udc); - bcall_back = FALSE; + bcall_back = false; break; case USB_REQ_CLEAR_FEATURE: nret = std_req_clear_feature(udc); - bcall_back = FALSE; + bcall_back = false; break; case USB_REQ_SET_FEATURE: nret = std_req_set_feature(udc); - bcall_back = FALSE; + bcall_back = false; break; case USB_REQ_SET_ADDRESS: nret = std_req_set_address(udc); - bcall_back = FALSE; + bcall_back = false; break; case USB_REQ_SET_CONFIGURATION: @@ -1655,7 +1655,7 @@ static inline int _nbu2ss_decode_request(struct nbu2ss_udc *udc) if (nret >= 0) { /*--------------------------------------*/ /* Status Stage */ - nret = EP0_send_NULL(udc, TRUE); + nret = EP0_send_NULL(udc, true); } } @@ -1688,7 +1688,7 @@ static inline int _nbu2ss_ep0_in_data_stage(struct nbu2ss_udc *udc) nret = _nbu2ss_ep0_in_transfer(udc, req); if (nret == 0) { udc->ep0state = EP0_OUT_STATUS_PAHSE; - EP0_receive_NULL(udc, TRUE); + EP0_receive_NULL(udc, true); } return 0; @@ -1708,7 +1708,7 @@ static inline int _nbu2ss_ep0_out_data_stage(struct nbu2ss_udc *udc) nret = _nbu2ss_ep0_out_transfer(udc, req); if (nret == 0) { udc->ep0state = EP0_IN_STATUS_PHASE; - EP0_send_NULL(udc, TRUE); + EP0_send_NULL(udc, true); } else if (nret < 0) { _nbu2ss_bitset(&udc->p_regs->EP0_CONTROL, EP0_BCLR); @@ -1817,7 +1817,7 @@ static inline void _nbu2ss_ep0_int(struct nbu2ss_udc *udc) if (nret < 0) { /* Send Stall */ - _nbu2ss_set_endpoint_stall(udc, 0, TRUE); + _nbu2ss_set_endpoint_stall(udc, 0, true); } } @@ -1925,7 +1925,7 @@ static inline void _nbu2ss_epn_in_dma_int(struct nbu2ss_udc *udc, preq->actual += req->div_len; req->div_len = 0; - req->dma_flag = FALSE; + req->dma_flag = false; #ifdef USE_DMA _nbu2ss_dma_unmap_single(udc, ep, req, USB_DIR_IN); @@ -1961,7 +1961,7 @@ static inline void _nbu2ss_epn_out_dma_int(struct nbu2ss_udc *udc, if (req->req.actual == req->req.length) { if ((req->req.length % ep->ep.maxpacket) && !req->zero) { req->div_len = 0; - req->dma_flag = FALSE; + req->dma_flag = false; _nbu2ss_ep_done(ep, req, 0); return; } @@ -1990,7 +1990,7 @@ static inline void _nbu2ss_epn_out_dma_int(struct nbu2ss_udc *udc, if ((req->req.actual % ep->ep.maxpacket) > 0) { if (req->req.actual == req->div_len) { req->div_len = 0; - req->dma_flag = FALSE; + req->dma_flag = false; _nbu2ss_ep_done(ep, req, 0); return; } @@ -1998,7 +1998,7 @@ static inline void _nbu2ss_epn_out_dma_int(struct nbu2ss_udc *udc, req->req.actual += req->div_len; req->div_len = 0; - req->dma_flag = FALSE; + req->dma_flag = false; _nbu2ss_epn_out_int(udc, ep, req); } @@ -2187,7 +2187,7 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc) /* USB Interrupt Enable */ _nbu2ss_bitset(&udc->p_regs->USB_INT_ENA, USB_INT_EN_BIT); - udc->udc_enabled = TRUE; + udc->udc_enabled = true; return 0; } @@ -2203,7 +2203,7 @@ static void _nbu2ss_reset_controller(struct nbu2ss_udc *udc) static void _nbu2ss_disable_controller(struct nbu2ss_udc *udc) { if (udc->udc_enabled) { - udc->udc_enabled = FALSE; + udc->udc_enabled = false; _nbu2ss_reset_controller(udc); _nbu2ss_bitset(&udc->p_regs->EPCTR, (DIRPD | EPC_RST)); } @@ -2456,8 +2456,8 @@ static int nbu2ss_ep_enable(struct usb_ep *_ep, ep->direct = desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK; ep->ep_type = ep_type; ep->wedged = 0; - ep->halted = FALSE; - ep->stalled = FALSE; + ep->halted = false; + ep->stalled = false; ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); @@ -2588,9 +2588,9 @@ static int nbu2ss_ep_queue(struct usb_ep *_ep, #ifdef USE_DMA if ((uintptr_t)req->req.buf & 0x3) - req->unaligned = TRUE; + req->unaligned = true; else - req->unaligned = FALSE; + req->unaligned = false; if (req->unaligned) { if (!ep->virt_buf) @@ -2616,7 +2616,7 @@ static int nbu2ss_ep_queue(struct usb_ep *_ep, list_add_tail(&req->queue, &ep->queue); if (bflag && !ep->stalled) { - result = _nbu2ss_start_transfer(udc, ep, req, FALSE); + result = _nbu2ss_start_transfer(udc, ep, req, false); if (result < 0) { dev_err(udc->dev, " *** %s, result = %d\n", __func__, result); @@ -2704,12 +2704,12 @@ static int nbu2ss_ep_set_halt(struct usb_ep *_ep, int value) ep_adrs = ep->epnum | ep->direct; if (value == 0) { _nbu2ss_set_endpoint_stall(udc, ep_adrs, value); - ep->stalled = FALSE; + ep->stalled = false; } else { if (list_empty(&ep->queue)) _nbu2ss_epn_set_stall(udc, ep); else - ep->stalled = TRUE; + ep->stalled = true; } if (value == 0) @@ -3094,10 +3094,8 @@ static int nbu2ss_drv_probe(struct platform_device *pdev) return PTR_ERR(mmio_base); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get IRQ\n"); + if (irq < 0) return irq; - } status = devm_request_irq(&pdev->dev, irq, _nbu2ss_udc_irq, 0, driver_name, udc); diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index b8c3dee5626c..9c2671cb32f7 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -19,11 +19,6 @@ #define USE_DMA 1 #define USE_SUSPEND_WAIT 1 -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - /*------------ Board dependence(Resource) */ #define VBUS_VALUE GPIO_VBUS diff --git a/drivers/staging/erofs/Documentation/filesystems/erofs.txt b/drivers/staging/erofs/Documentation/filesystems/erofs.txt deleted file mode 100644 index 74cf84ac48a3..000000000000 --- a/drivers/staging/erofs/Documentation/filesystems/erofs.txt +++ /dev/null @@ -1,209 +0,0 @@ -Overview -======== - -EROFS file-system stands for Enhanced Read-Only File System. Different -from other read-only file systems, it aims to be designed for flexibility, -scalability, but be kept simple and high performance. - -It is designed as a better filesystem solution for the following scenarios: - - read-only storage media or - - - part of a fully trusted read-only solution, which means it needs to be - immutable and bit-for-bit identical to the official golden image for - their releases due to security and other considerations and - - - hope to save some extra storage space with guaranteed end-to-end performance - by using reduced metadata and transparent file compression, especially - for those embedded devices with limited memory (ex, smartphone); - -Here is the main features of EROFS: - - Little endian on-disk design; - - - Currently 4KB block size (nobh) and therefore maximum 16TB address space; - - - Metadata & data could be mixed by design; - - - 2 inode versions for different requirements: - v1 v2 - Inode metadata size: 32 bytes 64 bytes - Max file size: 4 GB 16 EB (also limited by max. vol size) - Max uids/gids: 65536 4294967296 - File creation time: no yes (64 + 32-bit timestamp) - Max hardlinks: 65536 4294967296 - Metadata reserved: 4 bytes 14 bytes - - - Support extended attributes (xattrs) as an option; - - - Support xattr inline and tail-end data inline for all files; - - - Support POSIX.1e ACLs by using xattrs; - - - Support transparent file compression as an option: - LZ4 algorithm with 4 KB fixed-output compression for high performance; - -The following git tree provides the file system user-space tools under -development (ex, formatting tool mkfs.erofs): ->> git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git - -Bugs and patches are welcome, please kindly help us and send to the following -linux-erofs mailing list: ->> linux-erofs mailing list <linux-erofs@lists.ozlabs.org> - -Note that EROFS is still working in progress as a Linux staging driver, -Cc the staging mailing list as well is highly recommended: ->> Linux Driver Project Developer List <devel@driverdev.osuosl.org> - -Mount options -============= - -fault_injection=%d Enable fault injection in all supported types with - specified injection rate. Supported injection type: - Type_Name Type_Value - FAULT_KMALLOC 0x000000001 - FAULT_READ_IO 0x000000002 -(no)user_xattr Setup Extended User Attributes. Note: xattr is enabled - by default if CONFIG_EROFS_FS_XATTR is selected. -(no)acl Setup POSIX Access Control List. Note: acl is enabled - by default if CONFIG_EROFS_FS_POSIX_ACL is selected. - -On-disk details -=============== - -Summary -------- -Different from other read-only file systems, an EROFS volume is designed -to be as simple as possible: - - |-> aligned with the block size - ____________________________________________________________ - | |SB| | ... | Metadata | ... | Data | Metadata | ... | Data | - |_|__|_|_____|__________|_____|______|__________|_____|______| - 0 +1K - -All data areas should be aligned with the block size, but metadata areas -may not. All metadatas can be now observed in two different spaces (views): - 1. Inode metadata space - Each valid inode should be aligned with an inode slot, which is a fixed - value (32 bytes) and designed to be kept in line with v1 inode size. - - Each inode can be directly found with the following formula: - inode offset = meta_blkaddr * block_size + 32 * nid - - |-> aligned with 8B - |-> followed closely - + meta_blkaddr blocks |-> another slot - _____________________________________________________________________ - | ... | inode | xattrs | extents | data inline | ... | inode ... - |________|_______|(optional)|(optional)|__(optional)_|_____|__________ - |-> aligned with the inode slot size - . . - . . - . . - . . - . . - . . - .____________________________________________________|-> aligned with 4B - | xattr_ibody_header | shared xattrs | inline xattrs | - |____________________|_______________|_______________| - |-> 12 bytes <-|->x * 4 bytes<-| . - . . . - . . . - . . . - ._______________________________.______________________. - | id | id | id | id | ... | id | ent | ... | ent| ... | - |____|____|____|____|______|____|_____|_____|____|_____| - |-> aligned with 4B - |-> aligned with 4B - - Inode could be 32 or 64 bytes, which can be distinguished from a common - field which all inode versions have -- i_advise: - - __________________ __________________ - | i_advise | | i_advise | - |__________________| |__________________| - | ... | | ... | - | | | | - |__________________| 32 bytes | | - | | - |__________________| 64 bytes - - Xattrs, extents, data inline are followed by the corresponding inode with - proper alignes, and they could be optional for different data mappings, - _currently_ there are totally 3 valid data mappings supported: - - 1) flat file data without data inline (no extent); - 2) fixed-output size data compression (must have extents); - 3) flat file data with tail-end data inline (no extent); - - The size of the optional xattrs is indicated by i_xattr_count in inode - header. Large xattrs or xattrs shared by many different files can be - stored in shared xattrs metadata rather than inlined right after inode. - - 2. Shared xattrs metadata space - Shared xattrs space is similar to the above inode space, started with - a specific block indicated by xattr_blkaddr, organized one by one with - proper align. - - Each share xattr can also be directly found by the following formula: - xattr offset = xattr_blkaddr * block_size + 4 * xattr_id - - |-> aligned by 4 bytes - + xattr_blkaddr blocks |-> aligned with 4 bytes - _________________________________________________________________________ - | ... | xattr_entry | xattr data | ... | xattr_entry | xattr data ... - |________|_____________|_____________|_____|______________|_______________ - -Directories ------------ -All directories are now organized in a compact on-disk format. Note that -each directory block is divided into index and name areas in order to support -random file lookup, and all directory entries are _strictly_ recorded in -alphabetical order in order to support improved prefix binary search -algorithm (could refer to the related source code). - - ___________________________ - / | - / ______________|________________ - / / | nameoff1 | nameoffN-1 - ____________.______________._______________v________________v__________ -| dirent | dirent | ... | dirent | filename | filename | ... | filename | -|___.0___|____1___|_____|___N-1__|____0_____|____1_____|_____|___N-1____| - \ ^ - \ | * could have - \ | trailing '\0' - \________________________| nameoff0 - - Directory block - -Note that apart from the offset of the first filename, nameoff0 also indicates -the total number of directory entries in this block since it is no need to -introduce another on-disk field at all. - -Compression ------------ -Currently, EROFS supports 4KB fixed-output clustersize transparent file -compression, as illustrated below: - - |---- Variant-Length Extent ----|-------- VLE --------|----- VLE ----- - clusterofs clusterofs clusterofs - | | | logical data -_________v_______________________________v_____________________v_______________ -... | . | | . | | . | ... -____|____.________|_____________|________.____|_____________|__.__________|____ - |-> cluster <-|-> cluster <-|-> cluster <-|-> cluster <-|-> cluster <-| - size size size size size - . . . . - . . . . - . . . . - _______._____________._____________._____________._____________________ - ... | | | | ... physical data - _______|_____________|_____________|_____________|_____________________ - |-> cluster <-|-> cluster <-|-> cluster <-| - size size size - -Currently each on-disk physical cluster can contain 4KB (un)compressed data -at most. For each logical cluster, there is a corresponding on-disk index to -describe its cluster type, physical cluster address, etc. - -See "struct z_erofs_vle_decompressed_index" in erofs_fs.h for more details. - diff --git a/drivers/staging/erofs/Kconfig b/drivers/staging/erofs/Kconfig deleted file mode 100644 index d04b798a8efb..000000000000 --- a/drivers/staging/erofs/Kconfig +++ /dev/null @@ -1,151 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -config EROFS_FS - tristate "EROFS filesystem support" - depends on BLOCK - help - EROFS(Enhanced Read-Only File System) is a lightweight - read-only file system with modern designs (eg. page-sized - blocks, inline xattrs/data, etc.) for scenarios which need - high-performance read-only requirements, eg. firmwares in - mobile phone or LIVECDs. - - It also provides VLE compression support, focusing on - random read improvements, keeping relatively lower - compression ratios, which is useful for high-performance - devices with limited memory and ROM space. - - If unsure, say N. - -config EROFS_FS_DEBUG - bool "EROFS debugging feature" - depends on EROFS_FS - help - Print EROFS debugging messages and enable more BUG_ONs - which check the filesystem consistency aggressively. - - For daily use, say N. - -config EROFS_FS_XATTR - bool "EROFS extended attributes" - depends on EROFS_FS - default y - help - Extended attributes are name:value pairs associated with inodes by - the kernel or by users (see the attr(5) manual page, or visit - <http://acl.bestbits.at/> for details). - - If unsure, say N. - -config EROFS_FS_POSIX_ACL - bool "EROFS Access Control Lists" - depends on EROFS_FS_XATTR - select FS_POSIX_ACL - default y - help - Posix Access Control Lists (ACLs) support permissions for users and - groups beyond the owner/group/world scheme. - - To learn more about Access Control Lists, visit the POSIX ACLs for - Linux website <http://acl.bestbits.at/>. - - If you don't know what Access Control Lists are, say N. - -config EROFS_FS_SECURITY - bool "EROFS Security Labels" - depends on EROFS_FS_XATTR - help - Security labels provide an access control facility to support Linux - Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO - Linux. This option enables an extended attribute handler for file - security labels in the erofs filesystem, so that it requires enabling - the extended attribute support in advance. - - If you are not using a security module, say N. - -config EROFS_FS_USE_VM_MAP_RAM - bool "EROFS VM_MAP_RAM Support" - depends on EROFS_FS - help - use vm_map_ram/vm_unmap_ram instead of vmap/vunmap. - - If you don't know what these are, say N. - -config EROFS_FAULT_INJECTION - bool "EROFS fault injection facility" - depends on EROFS_FS - help - Test EROFS to inject faults such as ENOMEM, EIO, and so on. - If unsure, say N. - -config EROFS_FS_IO_MAX_RETRIES - int "EROFS IO Maximum Retries" - depends on EROFS_FS - default "5" - help - Maximum retry count of IO Errors. - - If unsure, leave the default value (5 retries, 6 IOs at most). - -config EROFS_FS_ZIP - bool "EROFS Data Compresssion Support" - depends on EROFS_FS - select LZ4_DECOMPRESS - help - Currently we support LZ4 VLE Compression only. - Play at your own risk. - - If you don't want to use compression feature, say N. - -config EROFS_FS_CLUSTER_PAGE_LIMIT - int "EROFS Cluster Pages Hard Limit" - depends on EROFS_FS_ZIP - range 1 256 - default "1" - help - Indicates VLE compressed pages hard limit of a - compressed cluster. - - For example, if files of a image are compressed - into 8k-unit, the hard limit should not be less - than 2. Otherwise, the image cannot be mounted - correctly on this kernel. - -choice - prompt "EROFS VLE Data Decompression mode" - depends on EROFS_FS_ZIP - default EROFS_FS_ZIP_CACHE_BIPOLAR - help - EROFS supports three options for VLE decompression. - "In-place Decompression Only" consumes the minimum memory - with lowest random read. - - "Bipolar Cached Decompression" consumes the maximum memory - with highest random read. - - If unsure, select "Bipolar Cached Decompression" - -config EROFS_FS_ZIP_NO_CACHE - bool "In-place Decompression Only" - help - Read compressed data into page cache and do in-place - decompression directly. - -config EROFS_FS_ZIP_CACHE_UNIPOLAR - bool "Unipolar Cached Decompression" - help - For each request, it caches the last compressed page - for further reading. - It still decompresses in place for the rest compressed pages. - -config EROFS_FS_ZIP_CACHE_BIPOLAR - bool "Bipolar Cached Decompression" - help - For each request, it caches the both end compressed pages - for further reading. - It still decompresses in place for the rest compressed pages. - - Recommended for performance priority. - -endchoice - diff --git a/drivers/staging/erofs/Makefile b/drivers/staging/erofs/Makefile deleted file mode 100644 index e704d9e51514..000000000000 --- a/drivers/staging/erofs/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -EROFS_VERSION = "1.0pre1" - -ccflags-y += -DEROFS_VERSION=\"$(EROFS_VERSION)\" - -obj-$(CONFIG_EROFS_FS) += erofs.o -# staging requirement: to be self-contained in its own directory -ccflags-y += -I $(srctree)/$(src)/include -erofs-objs := super.o inode.o data.o namei.o dir.o utils.o -erofs-$(CONFIG_EROFS_FS_XATTR) += xattr.o -erofs-$(CONFIG_EROFS_FS_ZIP) += unzip_vle.o zmap.o decompressor.o - diff --git a/drivers/staging/erofs/TODO b/drivers/staging/erofs/TODO deleted file mode 100644 index a8608b2f72bd..000000000000 --- a/drivers/staging/erofs/TODO +++ /dev/null @@ -1,46 +0,0 @@ - -EROFS is still working in progress, thus it is not suitable -for all productive uses. play at your own risk :) - -TODO List: - - add the missing error handling code - (mainly existed in xattr and decompression submodules); - - - finalize erofs ondisk format design (which means that - minor on-disk revisions could happen later); - - - documentation and detailed technical analysis; - - - general code review and clean up - (including confusing variable names and code snippets); - - - support larger compressed clustersizes for selection - (currently erofs only works as expected with the page-sized - compressed cluster configuration, usually 4KB); - - - support more lossless data compression algorithms - in addition to LZ4 algorithms in VLE approach; - - - data deduplication and other useful features. - -The following git tree provides the file system user-space -tools under development (ex, formatting tool mkfs.erofs): ->> git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git - -The open-source development of erofs-utils is at the early stage. -Contact the original author Li Guifu <bluce.liguifu@huawei.com> and -the co-maintainer Fang Wei <fangwei1@huawei.com> for the latest news -and more details. - -Code, suggestions, etc, are welcome. Please feel free to -ask and send patches, - -To: - linux-erofs mailing list <linux-erofs@lists.ozlabs.org> - Gao Xiang <gaoxiang25@huawei.com> - Chao Yu <yuchao0@huawei.com> - -Cc: (for linux-kernel upstream patches) - Greg Kroah-Hartman <gregkh@linuxfoundation.org> - linux-staging mailing list <devel@driverdev.osuosl.org> - diff --git a/drivers/staging/erofs/compress.h b/drivers/staging/erofs/compress.h deleted file mode 100644 index c43aa3374d28..000000000000 --- a/drivers/staging/erofs/compress.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * linux/drivers/staging/erofs/compress.h - * - * Copyright (C) 2019 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - */ -#ifndef __EROFS_FS_COMPRESS_H -#define __EROFS_FS_COMPRESS_H - -#include "internal.h" - -enum { - Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX, - Z_EROFS_COMPRESSION_RUNTIME_MAX -}; - -struct z_erofs_decompress_req { - struct super_block *sb; - struct page **in, **out; - - unsigned short pageofs_out; - unsigned int inputsize, outputsize; - - /* indicate the algorithm will be used for decompression */ - unsigned int alg; - bool inplace_io, partial_decoding; -}; - -/* - * - 0x5A110C8D ('sallocated', Z_EROFS_MAPPING_STAGING) - - * used to mark temporary allocated pages from other - * file/cached pages and NULL mapping pages. - */ -#define Z_EROFS_MAPPING_STAGING ((void *)0x5A110C8D) - -/* check if a page is marked as staging */ -static inline bool z_erofs_page_is_staging(struct page *page) -{ - return page->mapping == Z_EROFS_MAPPING_STAGING; -} - -static inline bool z_erofs_put_stagingpage(struct list_head *pagepool, - struct page *page) -{ - if (!z_erofs_page_is_staging(page)) - return false; - - /* staging pages should not be used by others at the same time */ - if (page_ref_count(page) > 1) - put_page(page); - else - list_add(&page->lru, pagepool); - return true; -} - -int z_erofs_decompress(struct z_erofs_decompress_req *rq, - struct list_head *pagepool); - -#endif - diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c deleted file mode 100644 index cc31c3e5984c..000000000000 --- a/drivers/staging/erofs/data.c +++ /dev/null @@ -1,400 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/data.c - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#include "internal.h" -#include <linux/prefetch.h> - -#include <trace/events/erofs.h> - -static inline void read_endio(struct bio *bio) -{ - struct super_block *const sb = bio->bi_private; - struct bio_vec *bvec; - blk_status_t err = bio->bi_status; - struct bvec_iter_all iter_all; - - if (time_to_inject(EROFS_SB(sb), FAULT_READ_IO)) { - erofs_show_injection_info(FAULT_READ_IO); - err = BLK_STS_IOERR; - } - - bio_for_each_segment_all(bvec, bio, iter_all) { - struct page *page = bvec->bv_page; - - /* page is already locked */ - DBG_BUGON(PageUptodate(page)); - - if (unlikely(err)) - SetPageError(page); - else - SetPageUptodate(page); - - unlock_page(page); - /* page could be reclaimed now */ - } - bio_put(bio); -} - -/* prio -- true is used for dir */ -struct page *__erofs_get_meta_page(struct super_block *sb, - erofs_blk_t blkaddr, bool prio, bool nofail) -{ - struct inode *const bd_inode = sb->s_bdev->bd_inode; - struct address_space *const mapping = bd_inode->i_mapping; - /* prefer retrying in the allocator to blindly looping below */ - const gfp_t gfp = mapping_gfp_constraint(mapping, ~__GFP_FS) | - (nofail ? __GFP_NOFAIL : 0); - unsigned int io_retries = nofail ? EROFS_IO_MAX_RETRIES_NOFAIL : 0; - struct page *page; - int err; - -repeat: - page = find_or_create_page(mapping, blkaddr, gfp); - if (unlikely(!page)) { - DBG_BUGON(nofail); - return ERR_PTR(-ENOMEM); - } - DBG_BUGON(!PageLocked(page)); - - if (!PageUptodate(page)) { - struct bio *bio; - - bio = erofs_grab_bio(sb, blkaddr, 1, sb, read_endio, nofail); - if (IS_ERR(bio)) { - DBG_BUGON(nofail); - err = PTR_ERR(bio); - goto err_out; - } - - err = bio_add_page(bio, page, PAGE_SIZE, 0); - if (unlikely(err != PAGE_SIZE)) { - err = -EFAULT; - goto err_out; - } - - __submit_bio(bio, REQ_OP_READ, - REQ_META | (prio ? REQ_PRIO : 0)); - - lock_page(page); - - /* this page has been truncated by others */ - if (unlikely(page->mapping != mapping)) { -unlock_repeat: - unlock_page(page); - put_page(page); - goto repeat; - } - - /* more likely a read error */ - if (unlikely(!PageUptodate(page))) { - if (io_retries) { - --io_retries; - goto unlock_repeat; - } - err = -EIO; - goto err_out; - } - } - return page; - -err_out: - unlock_page(page); - put_page(page); - return ERR_PTR(err); -} - -static int erofs_map_blocks_flatmode(struct inode *inode, - struct erofs_map_blocks *map, - int flags) -{ - int err = 0; - erofs_blk_t nblocks, lastblk; - u64 offset = map->m_la; - struct erofs_vnode *vi = EROFS_V(inode); - - trace_erofs_map_blocks_flatmode_enter(inode, map, flags); - - nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE); - lastblk = nblocks - is_inode_flat_inline(inode); - - if (unlikely(offset >= inode->i_size)) { - /* leave out-of-bound access unmapped */ - map->m_flags = 0; - map->m_plen = 0; - goto out; - } - - /* there is no hole in flatmode */ - map->m_flags = EROFS_MAP_MAPPED; - - if (offset < blknr_to_addr(lastblk)) { - map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la; - map->m_plen = blknr_to_addr(lastblk) - offset; - } else if (is_inode_flat_inline(inode)) { - /* 2 - inode inline B: inode, [xattrs], inline last blk... */ - struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); - - map->m_pa = iloc(sbi, vi->nid) + vi->inode_isize + - vi->xattr_isize + erofs_blkoff(map->m_la); - map->m_plen = inode->i_size - offset; - - /* inline data should locate in one meta block */ - if (erofs_blkoff(map->m_pa) + map->m_plen > PAGE_SIZE) { - DBG_BUGON(1); - err = -EIO; - goto err_out; - } - - map->m_flags |= EROFS_MAP_META; - } else { - errln("internal error @ nid: %llu (size %llu), m_la 0x%llx", - vi->nid, inode->i_size, map->m_la); - DBG_BUGON(1); - err = -EIO; - goto err_out; - } - -out: - map->m_llen = map->m_plen; - -err_out: - trace_erofs_map_blocks_flatmode_exit(inode, map, flags, 0); - return err; -} - -int erofs_map_blocks(struct inode *inode, - struct erofs_map_blocks *map, int flags) -{ - if (unlikely(is_inode_layout_compression(inode))) { - int err = z_erofs_map_blocks_iter(inode, map, flags); - - if (map->mpage) { - put_page(map->mpage); - map->mpage = NULL; - } - return err; - } - return erofs_map_blocks_flatmode(inode, map, flags); -} - -static inline struct bio *erofs_read_raw_page(struct bio *bio, - struct address_space *mapping, - struct page *page, - erofs_off_t *last_block, - unsigned int nblocks, - bool ra) -{ - struct inode *const inode = mapping->host; - struct super_block *const sb = inode->i_sb; - erofs_off_t current_block = (erofs_off_t)page->index; - int err; - - DBG_BUGON(!nblocks); - - if (PageUptodate(page)) { - err = 0; - goto has_updated; - } - - if (cleancache_get_page(page) == 0) { - err = 0; - SetPageUptodate(page); - goto has_updated; - } - - /* note that for readpage case, bio also equals to NULL */ - if (bio && - /* not continuous */ - *last_block + 1 != current_block) { -submit_bio_retry: - __submit_bio(bio, REQ_OP_READ, 0); - bio = NULL; - } - - if (!bio) { - struct erofs_map_blocks map = { - .m_la = blknr_to_addr(current_block), - }; - erofs_blk_t blknr; - unsigned int blkoff; - - err = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW); - if (unlikely(err)) - goto err_out; - - /* zero out the holed page */ - if (unlikely(!(map.m_flags & EROFS_MAP_MAPPED))) { - zero_user_segment(page, 0, PAGE_SIZE); - SetPageUptodate(page); - - /* imply err = 0, see erofs_map_blocks */ - goto has_updated; - } - - /* for RAW access mode, m_plen must be equal to m_llen */ - DBG_BUGON(map.m_plen != map.m_llen); - - blknr = erofs_blknr(map.m_pa); - blkoff = erofs_blkoff(map.m_pa); - - /* deal with inline page */ - if (map.m_flags & EROFS_MAP_META) { - void *vsrc, *vto; - struct page *ipage; - - DBG_BUGON(map.m_plen > PAGE_SIZE); - - ipage = erofs_get_meta_page(inode->i_sb, blknr, 0); - - if (IS_ERR(ipage)) { - err = PTR_ERR(ipage); - goto err_out; - } - - vsrc = kmap_atomic(ipage); - vto = kmap_atomic(page); - memcpy(vto, vsrc + blkoff, map.m_plen); - memset(vto + map.m_plen, 0, PAGE_SIZE - map.m_plen); - kunmap_atomic(vto); - kunmap_atomic(vsrc); - flush_dcache_page(page); - - SetPageUptodate(page); - /* TODO: could we unlock the page earlier? */ - unlock_page(ipage); - put_page(ipage); - - /* imply err = 0, see erofs_map_blocks */ - goto has_updated; - } - - /* pa must be block-aligned for raw reading */ - DBG_BUGON(erofs_blkoff(map.m_pa)); - - /* max # of continuous pages */ - if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE)) - nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE); - if (nblocks > BIO_MAX_PAGES) - nblocks = BIO_MAX_PAGES; - - bio = erofs_grab_bio(sb, blknr, nblocks, sb, - read_endio, false); - if (IS_ERR(bio)) { - err = PTR_ERR(bio); - bio = NULL; - goto err_out; - } - } - - err = bio_add_page(bio, page, PAGE_SIZE, 0); - /* out of the extent or bio is full */ - if (err < PAGE_SIZE) - goto submit_bio_retry; - - *last_block = current_block; - - /* shift in advance in case of it followed by too many gaps */ - if (bio->bi_iter.bi_size >= bio->bi_max_vecs * PAGE_SIZE) { - /* err should reassign to 0 after submitting */ - err = 0; - goto submit_bio_out; - } - - return bio; - -err_out: - /* for sync reading, set page error immediately */ - if (!ra) { - SetPageError(page); - ClearPageUptodate(page); - } -has_updated: - unlock_page(page); - - /* if updated manually, continuous pages has a gap */ - if (bio) -submit_bio_out: - __submit_bio(bio, REQ_OP_READ, 0); - - return unlikely(err) ? ERR_PTR(err) : NULL; -} - -/* - * since we dont have write or truncate flows, so no inode - * locking needs to be held at the moment. - */ -static int erofs_raw_access_readpage(struct file *file, struct page *page) -{ - erofs_off_t last_block; - struct bio *bio; - - trace_erofs_readpage(page, true); - - bio = erofs_read_raw_page(NULL, page->mapping, - page, &last_block, 1, false); - - if (IS_ERR(bio)) - return PTR_ERR(bio); - - DBG_BUGON(bio); /* since we have only one bio -- must be NULL */ - return 0; -} - -static int erofs_raw_access_readpages(struct file *filp, - struct address_space *mapping, - struct list_head *pages, - unsigned int nr_pages) -{ - erofs_off_t last_block; - struct bio *bio = NULL; - gfp_t gfp = readahead_gfp_mask(mapping); - struct page *page = list_last_entry(pages, struct page, lru); - - trace_erofs_readpages(mapping->host, page, nr_pages, true); - - for (; nr_pages; --nr_pages) { - page = list_entry(pages->prev, struct page, lru); - - prefetchw(&page->flags); - list_del(&page->lru); - - if (!add_to_page_cache_lru(page, mapping, page->index, gfp)) { - bio = erofs_read_raw_page(bio, mapping, page, - &last_block, nr_pages, true); - - /* all the page errors are ignored when readahead */ - if (IS_ERR(bio)) { - pr_err("%s, readahead error at page %lu of nid %llu\n", - __func__, page->index, - EROFS_V(mapping->host)->nid); - - bio = NULL; - } - } - - /* pages could still be locked */ - put_page(page); - } - DBG_BUGON(!list_empty(pages)); - - /* the rare case (end in gaps) */ - if (unlikely(bio)) - __submit_bio(bio, REQ_OP_READ, 0); - return 0; -} - -/* for uncompressed (aligned) files and raw access for other files */ -const struct address_space_operations erofs_raw_access_aops = { - .readpage = erofs_raw_access_readpage, - .readpages = erofs_raw_access_readpages, -}; - diff --git a/drivers/staging/erofs/decompressor.c b/drivers/staging/erofs/decompressor.c deleted file mode 100644 index 1fb0abb98dff..000000000000 --- a/drivers/staging/erofs/decompressor.c +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/decompressor.c - * - * Copyright (C) 2019 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - */ -#include "compress.h" -#include <linux/lz4.h> - -#ifndef LZ4_DISTANCE_MAX /* history window size */ -#define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */ -#endif - -#define LZ4_MAX_DISTANCE_PAGES (DIV_ROUND_UP(LZ4_DISTANCE_MAX, PAGE_SIZE) + 1) -#ifndef LZ4_DECOMPRESS_INPLACE_MARGIN -#define LZ4_DECOMPRESS_INPLACE_MARGIN(srcsize) (((srcsize) >> 8) + 32) -#endif - -struct z_erofs_decompressor { - /* - * if destpages have sparsed pages, fill them with bounce pages. - * it also check whether destpages indicate continuous physical memory. - */ - int (*prepare_destpages)(struct z_erofs_decompress_req *rq, - struct list_head *pagepool); - int (*decompress)(struct z_erofs_decompress_req *rq, u8 *out); - char *name; -}; - -static int lz4_prepare_destpages(struct z_erofs_decompress_req *rq, - struct list_head *pagepool) -{ - const unsigned int nr = - PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; - struct page *availables[LZ4_MAX_DISTANCE_PAGES] = { NULL }; - unsigned long bounced[DIV_ROUND_UP(LZ4_MAX_DISTANCE_PAGES, - BITS_PER_LONG)] = { 0 }; - void *kaddr = NULL; - unsigned int i, j, top; - - top = 0; - for (i = j = 0; i < nr; ++i, ++j) { - struct page *const page = rq->out[i]; - struct page *victim; - - if (j >= LZ4_MAX_DISTANCE_PAGES) - j = 0; - - /* 'valid' bounced can only be tested after a complete round */ - if (test_bit(j, bounced)) { - DBG_BUGON(i < LZ4_MAX_DISTANCE_PAGES); - DBG_BUGON(top >= LZ4_MAX_DISTANCE_PAGES); - availables[top++] = rq->out[i - LZ4_MAX_DISTANCE_PAGES]; - } - - if (page) { - __clear_bit(j, bounced); - if (kaddr) { - if (kaddr + PAGE_SIZE == page_address(page)) - kaddr += PAGE_SIZE; - else - kaddr = NULL; - } else if (!i) { - kaddr = page_address(page); - } - continue; - } - kaddr = NULL; - __set_bit(j, bounced); - - if (top) { - victim = availables[--top]; - get_page(victim); - } else { - if (!list_empty(pagepool)) { - victim = lru_to_page(pagepool); - list_del(&victim->lru); - DBG_BUGON(page_ref_count(victim) != 1); - } else { - victim = alloc_pages(GFP_KERNEL, 0); - if (!victim) - return -ENOMEM; - } - victim->mapping = Z_EROFS_MAPPING_STAGING; - } - rq->out[i] = victim; - } - return kaddr ? 1 : 0; -} - -static void *generic_copy_inplace_data(struct z_erofs_decompress_req *rq, - u8 *src, unsigned int pageofs_in) -{ - /* - * if in-place decompression is ongoing, those decompressed - * pages should be copied in order to avoid being overlapped. - */ - struct page **in = rq->in; - u8 *const tmp = erofs_get_pcpubuf(0); - u8 *tmpp = tmp; - unsigned int inlen = rq->inputsize - pageofs_in; - unsigned int count = min_t(uint, inlen, PAGE_SIZE - pageofs_in); - - while (tmpp < tmp + inlen) { - if (!src) - src = kmap_atomic(*in); - memcpy(tmpp, src + pageofs_in, count); - kunmap_atomic(src); - src = NULL; - tmpp += count; - pageofs_in = 0; - count = PAGE_SIZE; - ++in; - } - return tmp; -} - -static int lz4_decompress(struct z_erofs_decompress_req *rq, u8 *out) -{ - unsigned int inputmargin, inlen; - u8 *src; - bool copied, support_0padding; - int ret; - - if (rq->inputsize > PAGE_SIZE) - return -ENOTSUPP; - - src = kmap_atomic(*rq->in); - inputmargin = 0; - support_0padding = false; - - /* decompression inplace is only safe when 0padding is enabled */ - if (EROFS_SB(rq->sb)->requirements & EROFS_REQUIREMENT_LZ4_0PADDING) { - support_0padding = true; - - while (!src[inputmargin & ~PAGE_MASK]) - if (!(++inputmargin & ~PAGE_MASK)) - break; - - if (inputmargin >= rq->inputsize) { - kunmap_atomic(src); - return -EIO; - } - } - - copied = false; - inlen = rq->inputsize - inputmargin; - if (rq->inplace_io) { - const uint oend = (rq->pageofs_out + - rq->outputsize) & ~PAGE_MASK; - const uint nr = PAGE_ALIGN(rq->pageofs_out + - rq->outputsize) >> PAGE_SHIFT; - - if (rq->partial_decoding || !support_0padding || - rq->out[nr - 1] != rq->in[0] || - rq->inputsize - oend < - LZ4_DECOMPRESS_INPLACE_MARGIN(inlen)) { - src = generic_copy_inplace_data(rq, src, inputmargin); - inputmargin = 0; - copied = true; - } - } - - ret = LZ4_decompress_safe_partial(src + inputmargin, out, - inlen, rq->outputsize, - rq->outputsize); - if (ret < 0) { - errln("%s, failed to decompress, in[%p, %u, %u] out[%p, %u]", - __func__, src + inputmargin, inlen, inputmargin, - out, rq->outputsize); - WARN_ON(1); - print_hex_dump(KERN_DEBUG, "[ in]: ", DUMP_PREFIX_OFFSET, - 16, 1, src + inputmargin, inlen, true); - print_hex_dump(KERN_DEBUG, "[out]: ", DUMP_PREFIX_OFFSET, - 16, 1, out, rq->outputsize, true); - ret = -EIO; - } - - if (copied) - erofs_put_pcpubuf(src); - else - kunmap_atomic(src); - return ret; -} - -static struct z_erofs_decompressor decompressors[] = { - [Z_EROFS_COMPRESSION_SHIFTED] = { - .name = "shifted" - }, - [Z_EROFS_COMPRESSION_LZ4] = { - .prepare_destpages = lz4_prepare_destpages, - .decompress = lz4_decompress, - .name = "lz4" - }, -}; - -static void copy_from_pcpubuf(struct page **out, const char *dst, - unsigned short pageofs_out, - unsigned int outputsize) -{ - const char *end = dst + outputsize; - const unsigned int righthalf = PAGE_SIZE - pageofs_out; - const char *cur = dst - pageofs_out; - - while (cur < end) { - struct page *const page = *out++; - - if (page) { - char *buf = kmap_atomic(page); - - if (cur >= dst) { - memcpy(buf, cur, min_t(uint, PAGE_SIZE, - end - cur)); - } else { - memcpy(buf + pageofs_out, cur + pageofs_out, - min_t(uint, righthalf, end - cur)); - } - kunmap_atomic(buf); - } - cur += PAGE_SIZE; - } -} - -static int decompress_generic(struct z_erofs_decompress_req *rq, - struct list_head *pagepool) -{ - const unsigned int nrpages_out = - PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; - const struct z_erofs_decompressor *alg = decompressors + rq->alg; - unsigned int dst_maptype; - void *dst; - int ret; - - if (nrpages_out == 1 && !rq->inplace_io) { - DBG_BUGON(!*rq->out); - dst = kmap_atomic(*rq->out); - dst_maptype = 0; - goto dstmap_out; - } - - /* - * For the case of small output size (especially much less - * than PAGE_SIZE), memcpy the decompressed data rather than - * compressed data is preferred. - */ - if (rq->outputsize <= PAGE_SIZE * 7 / 8) { - dst = erofs_get_pcpubuf(0); - if (IS_ERR(dst)) - return PTR_ERR(dst); - - rq->inplace_io = false; - ret = alg->decompress(rq, dst); - if (!ret) - copy_from_pcpubuf(rq->out, dst, rq->pageofs_out, - rq->outputsize); - - erofs_put_pcpubuf(dst); - return ret; - } - - ret = alg->prepare_destpages(rq, pagepool); - if (ret < 0) { - return ret; - } else if (ret) { - dst = page_address(*rq->out); - dst_maptype = 1; - goto dstmap_out; - } - - dst = erofs_vmap(rq->out, nrpages_out); - if (!dst) - return -ENOMEM; - dst_maptype = 2; - -dstmap_out: - ret = alg->decompress(rq, dst + rq->pageofs_out); - - if (!dst_maptype) - kunmap_atomic(dst); - else if (dst_maptype == 2) - erofs_vunmap(dst, nrpages_out); - return ret; -} - -static int shifted_decompress(const struct z_erofs_decompress_req *rq, - struct list_head *pagepool) -{ - const unsigned int nrpages_out = - PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; - const unsigned int righthalf = PAGE_SIZE - rq->pageofs_out; - unsigned char *src, *dst; - - if (nrpages_out > 2) { - DBG_BUGON(1); - return -EIO; - } - - if (rq->out[0] == *rq->in) { - DBG_BUGON(nrpages_out != 1); - return 0; - } - - src = kmap_atomic(*rq->in); - if (!rq->out[0]) { - dst = NULL; - } else { - dst = kmap_atomic(rq->out[0]); - memcpy(dst + rq->pageofs_out, src, righthalf); - } - - if (rq->out[1] == *rq->in) { - memmove(src, src + righthalf, rq->pageofs_out); - } else if (nrpages_out == 2) { - if (dst) - kunmap_atomic(dst); - DBG_BUGON(!rq->out[1]); - dst = kmap_atomic(rq->out[1]); - memcpy(dst, src + righthalf, rq->pageofs_out); - } - if (dst) - kunmap_atomic(dst); - kunmap_atomic(src); - return 0; -} - -int z_erofs_decompress(struct z_erofs_decompress_req *rq, - struct list_head *pagepool) -{ - if (rq->alg == Z_EROFS_COMPRESSION_SHIFTED) - return shifted_decompress(rq, pagepool); - return decompress_generic(rq, pagepool); -} - diff --git a/drivers/staging/erofs/dir.c b/drivers/staging/erofs/dir.c deleted file mode 100644 index dbf6a151886c..000000000000 --- a/drivers/staging/erofs/dir.c +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/dir.c - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#include "internal.h" - -static const unsigned char erofs_filetype_table[EROFS_FT_MAX] = { - [EROFS_FT_UNKNOWN] = DT_UNKNOWN, - [EROFS_FT_REG_FILE] = DT_REG, - [EROFS_FT_DIR] = DT_DIR, - [EROFS_FT_CHRDEV] = DT_CHR, - [EROFS_FT_BLKDEV] = DT_BLK, - [EROFS_FT_FIFO] = DT_FIFO, - [EROFS_FT_SOCK] = DT_SOCK, - [EROFS_FT_SYMLINK] = DT_LNK, -}; - -static void debug_one_dentry(unsigned char d_type, const char *de_name, - unsigned int de_namelen) -{ -#ifdef CONFIG_EROFS_FS_DEBUG - /* since the on-disk name could not have the trailing '\0' */ - unsigned char dbg_namebuf[EROFS_NAME_LEN + 1]; - - memcpy(dbg_namebuf, de_name, de_namelen); - dbg_namebuf[de_namelen] = '\0'; - - debugln("found dirent %s de_len %u d_type %d", dbg_namebuf, - de_namelen, d_type); -#endif -} - -static int erofs_fill_dentries(struct dir_context *ctx, - void *dentry_blk, unsigned int *ofs, - unsigned int nameoff, unsigned int maxsize) -{ - struct erofs_dirent *de = dentry_blk + *ofs; - const struct erofs_dirent *end = dentry_blk + nameoff; - - while (de < end) { - const char *de_name; - unsigned int de_namelen; - unsigned char d_type; - - if (de->file_type < EROFS_FT_MAX) - d_type = erofs_filetype_table[de->file_type]; - else - d_type = DT_UNKNOWN; - - nameoff = le16_to_cpu(de->nameoff); - de_name = (char *)dentry_blk + nameoff; - - /* the last dirent in the block? */ - if (de + 1 >= end) - de_namelen = strnlen(de_name, maxsize - nameoff); - else - de_namelen = le16_to_cpu(de[1].nameoff) - nameoff; - - /* a corrupted entry is found */ - if (unlikely(nameoff + de_namelen > maxsize || - de_namelen > EROFS_NAME_LEN)) { - DBG_BUGON(1); - return -EIO; - } - - debug_one_dentry(d_type, de_name, de_namelen); - if (!dir_emit(ctx, de_name, de_namelen, - le64_to_cpu(de->nid), d_type)) - /* stopped by some reason */ - return 1; - ++de; - *ofs += sizeof(struct erofs_dirent); - } - *ofs = maxsize; - return 0; -} - -static int erofs_readdir(struct file *f, struct dir_context *ctx) -{ - struct inode *dir = file_inode(f); - struct address_space *mapping = dir->i_mapping; - const size_t dirsize = i_size_read(dir); - unsigned int i = ctx->pos / EROFS_BLKSIZ; - unsigned int ofs = ctx->pos % EROFS_BLKSIZ; - int err = 0; - bool initial = true; - - while (ctx->pos < dirsize) { - struct page *dentry_page; - struct erofs_dirent *de; - unsigned int nameoff, maxsize; - - dentry_page = read_mapping_page(mapping, i, NULL); - if (IS_ERR(dentry_page)) - continue; - - de = (struct erofs_dirent *)kmap(dentry_page); - - nameoff = le16_to_cpu(de->nameoff); - - if (unlikely(nameoff < sizeof(struct erofs_dirent) || - nameoff >= PAGE_SIZE)) { - errln("%s, invalid de[0].nameoff %u", - __func__, nameoff); - - err = -EIO; - goto skip_this; - } - - maxsize = min_t(unsigned int, - dirsize - ctx->pos + ofs, PAGE_SIZE); - - /* search dirents at the arbitrary position */ - if (unlikely(initial)) { - initial = false; - - ofs = roundup(ofs, sizeof(struct erofs_dirent)); - if (unlikely(ofs >= nameoff)) - goto skip_this; - } - - err = erofs_fill_dentries(ctx, de, &ofs, nameoff, maxsize); -skip_this: - kunmap(dentry_page); - - put_page(dentry_page); - - ctx->pos = blknr_to_addr(i) + ofs; - - if (unlikely(err)) - break; - ++i; - ofs = 0; - } - return err < 0 ? err : 0; -} - -const struct file_operations erofs_dir_fops = { - .llseek = generic_file_llseek, - .read = generic_read_dir, - .iterate_shared = erofs_readdir, -}; - diff --git a/drivers/staging/erofs/erofs_fs.h b/drivers/staging/erofs/erofs_fs.h deleted file mode 100644 index 9f61abb7c1ca..000000000000 --- a/drivers/staging/erofs/erofs_fs.h +++ /dev/null @@ -1,322 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 - * - * linux/drivers/staging/erofs/erofs_fs.h - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is dual-licensed; you may select either the GNU General Public - * License version 2 or Apache License, Version 2.0. See the file COPYING - * in the main directory of the Linux distribution for more details. - */ -#ifndef __EROFS_FS_H -#define __EROFS_FS_H - -/* Enhanced(Extended) ROM File System */ -#define EROFS_SUPER_MAGIC_V1 0xE0F5E1E2 -#define EROFS_SUPER_OFFSET 1024 - -/* - * Any bits that aren't in EROFS_ALL_REQUIREMENTS should be - * incompatible with this kernel version. - */ -#define EROFS_REQUIREMENT_LZ4_0PADDING 0x00000001 -#define EROFS_ALL_REQUIREMENTS EROFS_REQUIREMENT_LZ4_0PADDING - -struct erofs_super_block { -/* 0 */__le32 magic; /* in the little endian */ -/* 4 */__le32 checksum; /* crc32c(super_block) */ -/* 8 */__le32 features; /* (aka. feature_compat) */ -/* 12 */__u8 blkszbits; /* support block_size == PAGE_SIZE only */ -/* 13 */__u8 reserved; - -/* 14 */__le16 root_nid; -/* 16 */__le64 inos; /* total valid ino # (== f_files - f_favail) */ - -/* 24 */__le64 build_time; /* inode v1 time derivation */ -/* 32 */__le32 build_time_nsec; -/* 36 */__le32 blocks; /* used for statfs */ -/* 40 */__le32 meta_blkaddr; -/* 44 */__le32 xattr_blkaddr; -/* 48 */__u8 uuid[16]; /* 128-bit uuid for volume */ -/* 64 */__u8 volume_name[16]; /* volume name */ -/* 80 */__le32 requirements; /* (aka. feature_incompat) */ - -/* 84 */__u8 reserved2[44]; -} __packed; /* 128 bytes */ - -/* - * erofs inode data mapping: - * 0 - inode plain without inline data A: - * inode, [xattrs], ... | ... | no-holed data - * 1 - inode VLE compression B (legacy): - * inode, [xattrs], extents ... | ... - * 2 - inode plain with inline data C: - * inode, [xattrs], last_inline_data, ... | ... | no-holed data - * 3 - inode compression D: - * inode, [xattrs], map_header, extents ... | ... - * 4~7 - reserved - */ -enum { - EROFS_INODE_FLAT_PLAIN, - EROFS_INODE_FLAT_COMPRESSION_LEGACY, - EROFS_INODE_FLAT_INLINE, - EROFS_INODE_FLAT_COMPRESSION, - EROFS_INODE_LAYOUT_MAX -}; - -static bool erofs_inode_is_data_compressed(unsigned int datamode) -{ - if (datamode == EROFS_INODE_FLAT_COMPRESSION) - return true; - return datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY; -} - -/* bit definitions of inode i_advise */ -#define EROFS_I_VERSION_BITS 1 -#define EROFS_I_DATA_MAPPING_BITS 3 - -#define EROFS_I_VERSION_BIT 0 -#define EROFS_I_DATA_MAPPING_BIT 1 - -struct erofs_inode_v1 { -/* 0 */__le16 i_advise; - -/* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ -/* 2 */__le16 i_xattr_icount; -/* 4 */__le16 i_mode; -/* 6 */__le16 i_nlink; -/* 8 */__le32 i_size; -/* 12 */__le32 i_reserved; -/* 16 */union { - /* file total compressed blocks for data mapping 1 */ - __le32 compressed_blocks; - __le32 raw_blkaddr; - - /* for device files, used to indicate old/new device # */ - __le32 rdev; - } i_u __packed; -/* 20 */__le32 i_ino; /* only used for 32-bit stat compatibility */ -/* 24 */__le16 i_uid; -/* 26 */__le16 i_gid; -/* 28 */__le32 i_checksum; -} __packed; - -/* 32 bytes on-disk inode */ -#define EROFS_INODE_LAYOUT_V1 0 -/* 64 bytes on-disk inode */ -#define EROFS_INODE_LAYOUT_V2 1 - -struct erofs_inode_v2 { - __le16 i_advise; - - /* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ - __le16 i_xattr_icount; - __le16 i_mode; - __le16 i_reserved; /* 8 bytes */ - __le64 i_size; /* 16 bytes */ - union { - /* file total compressed blocks for data mapping 1 */ - __le32 compressed_blocks; - __le32 raw_blkaddr; - - /* for device files, used to indicate old/new device # */ - __le32 rdev; - } i_u __packed; - - /* only used for 32-bit stat compatibility */ - __le32 i_ino; /* 24 bytes */ - - __le32 i_uid; - __le32 i_gid; - __le64 i_ctime; /* 32 bytes */ - __le32 i_ctime_nsec; - __le32 i_nlink; - __u8 i_reserved2[12]; - __le32 i_checksum; /* 64 bytes */ -} __packed; - -#define EROFS_MAX_SHARED_XATTRS (128) -/* h_shared_count between 129 ... 255 are special # */ -#define EROFS_SHARED_XATTR_EXTENT (255) - -/* - * inline xattrs (n == i_xattr_icount): - * erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes - * 12 bytes / \ - * / \ - * /-----------------------\ - * | erofs_xattr_entries+ | - * +-----------------------+ - * inline xattrs must starts in erofs_xattr_ibody_header, - * for read-only fs, no need to introduce h_refcount - */ -struct erofs_xattr_ibody_header { - __le32 h_checksum; - __u8 h_shared_count; - __u8 h_reserved[7]; - __le32 h_shared_xattrs[0]; /* shared xattr id array */ -} __packed; - -/* Name indexes */ -#define EROFS_XATTR_INDEX_USER 1 -#define EROFS_XATTR_INDEX_POSIX_ACL_ACCESS 2 -#define EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 -#define EROFS_XATTR_INDEX_TRUSTED 4 -#define EROFS_XATTR_INDEX_LUSTRE 5 -#define EROFS_XATTR_INDEX_SECURITY 6 - -/* xattr entry (for both inline & shared xattrs) */ -struct erofs_xattr_entry { - __u8 e_name_len; /* length of name */ - __u8 e_name_index; /* attribute name index */ - __le16 e_value_size; /* size of attribute value */ - /* followed by e_name and e_value */ - char e_name[0]; /* attribute name */ -} __packed; - -#define ondisk_xattr_ibody_size(count) ({\ - u32 __count = le16_to_cpu(count); \ - ((__count) == 0) ? 0 : \ - sizeof(struct erofs_xattr_ibody_header) + \ - sizeof(__u32) * ((__count) - 1); }) - -#define EROFS_XATTR_ALIGN(size) round_up(size, sizeof(struct erofs_xattr_entry)) -#define EROFS_XATTR_ENTRY_SIZE(entry) EROFS_XATTR_ALIGN( \ - sizeof(struct erofs_xattr_entry) + \ - (entry)->e_name_len + le16_to_cpu((entry)->e_value_size)) - -/* available compression algorithm types */ -enum { - Z_EROFS_COMPRESSION_LZ4, - Z_EROFS_COMPRESSION_MAX -}; - -/* - * bit 0 : COMPACTED_2B indexes (0 - off; 1 - on) - * e.g. for 4k logical cluster size, 4B if compacted 2B is off; - * (4B) + 2B + (4B) if compacted 2B is on. - */ -#define Z_EROFS_ADVISE_COMPACTED_2B_BIT 0 - -#define Z_EROFS_ADVISE_COMPACTED_2B (1 << Z_EROFS_ADVISE_COMPACTED_2B_BIT) - -struct z_erofs_map_header { - __le32 h_reserved1; - __le16 h_advise; - /* - * bit 0-3 : algorithm type of head 1 (logical cluster type 01); - * bit 4-7 : algorithm type of head 2 (logical cluster type 11). - */ - __u8 h_algorithmtype; - /* - * bit 0-2 : logical cluster bits - 12, e.g. 0 for 4096; - * bit 3-4 : (physical - logical) cluster bits of head 1: - * For example, if logical clustersize = 4096, 1 for 8192. - * bit 5-7 : (physical - logical) cluster bits of head 2. - */ - __u8 h_clusterbits; -}; - -#define Z_EROFS_VLE_LEGACY_HEADER_PADDING 8 - -/* - * Z_EROFS Variable-sized Logical Extent cluster type: - * 0 - literal (uncompressed) cluster - * 1 - compressed cluster (for the head logical cluster) - * 2 - compressed cluster (for the other logical clusters) - * - * In detail, - * 0 - literal (uncompressed) cluster, - * di_advise = 0 - * di_clusterofs = the literal data offset of the cluster - * di_blkaddr = the blkaddr of the literal cluster - * - * 1 - compressed cluster (for the head logical cluster) - * di_advise = 1 - * di_clusterofs = the decompressed data offset of the cluster - * di_blkaddr = the blkaddr of the compressed cluster - * - * 2 - compressed cluster (for the other logical clusters) - * di_advise = 2 - * di_clusterofs = - * the decompressed data offset in its own head cluster - * di_u.delta[0] = distance to its corresponding head cluster - * di_u.delta[1] = distance to its corresponding tail cluster - * (di_advise could be 0, 1 or 2) - */ -enum { - Z_EROFS_VLE_CLUSTER_TYPE_PLAIN, - Z_EROFS_VLE_CLUSTER_TYPE_HEAD, - Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD, - Z_EROFS_VLE_CLUSTER_TYPE_RESERVED, - Z_EROFS_VLE_CLUSTER_TYPE_MAX -}; - -#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS 2 -#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT 0 - -struct z_erofs_vle_decompressed_index { - __le16 di_advise; - /* where to decompress in the head cluster */ - __le16 di_clusterofs; - - union { - /* for the head cluster */ - __le32 blkaddr; - /* - * for the rest clusters - * eg. for 4k page-sized cluster, maximum 4K*64k = 256M) - * [0] - pointing to the head cluster - * [1] - pointing to the tail cluster - */ - __le16 delta[2]; - } di_u __packed; /* 8 bytes */ -} __packed; - -#define Z_EROFS_VLE_LEGACY_INDEX_ALIGN(size) \ - (round_up(size, sizeof(struct z_erofs_vle_decompressed_index)) + \ - sizeof(struct z_erofs_map_header) + Z_EROFS_VLE_LEGACY_HEADER_PADDING) - -/* dirent sorts in alphabet order, thus we can do binary search */ -struct erofs_dirent { - __le64 nid; /* 0, node number */ - __le16 nameoff; /* 8, start offset of file name */ - __u8 file_type; /* 10, file type */ - __u8 reserved; /* 11, reserved */ -} __packed; - -/* file types used in inode_info->flags */ -enum { - EROFS_FT_UNKNOWN, - EROFS_FT_REG_FILE, - EROFS_FT_DIR, - EROFS_FT_CHRDEV, - EROFS_FT_BLKDEV, - EROFS_FT_FIFO, - EROFS_FT_SOCK, - EROFS_FT_SYMLINK, - EROFS_FT_MAX -}; - -#define EROFS_NAME_LEN 255 - -/* check the EROFS on-disk layout strictly at compile time */ -static inline void erofs_check_ondisk_layout_definitions(void) -{ - BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128); - BUILD_BUG_ON(sizeof(struct erofs_inode_v1) != 32); - BUILD_BUG_ON(sizeof(struct erofs_inode_v2) != 64); - BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12); - BUILD_BUG_ON(sizeof(struct erofs_xattr_entry) != 4); - BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8); - BUILD_BUG_ON(sizeof(struct z_erofs_vle_decompressed_index) != 8); - BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12); - - BUILD_BUG_ON(BIT(Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) < - Z_EROFS_VLE_CLUSTER_TYPE_MAX - 1); -} - -#endif - diff --git a/drivers/staging/erofs/include/linux/tagptr.h b/drivers/staging/erofs/include/linux/tagptr.h deleted file mode 100644 index ccd106dbd48e..000000000000 --- a/drivers/staging/erofs/include/linux/tagptr.h +++ /dev/null @@ -1,110 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Tagged pointer implementation - * - * Copyright (C) 2018 Gao Xiang <gaoxiang25@huawei.com> - */ -#ifndef _LINUX_TAGPTR_H -#define _LINUX_TAGPTR_H - -#include <linux/types.h> -#include <linux/build_bug.h> - -/* - * the name of tagged pointer types are tagptr{1, 2, 3...}_t - * avoid directly using the internal structs __tagptr{1, 2, 3...} - */ -#define __MAKE_TAGPTR(n) \ -typedef struct __tagptr##n { \ - uintptr_t v; \ -} tagptr##n##_t; - -__MAKE_TAGPTR(1) -__MAKE_TAGPTR(2) -__MAKE_TAGPTR(3) -__MAKE_TAGPTR(4) - -#undef __MAKE_TAGPTR - -extern void __compiletime_error("bad tagptr tags") - __bad_tagptr_tags(void); - -extern void __compiletime_error("bad tagptr type") - __bad_tagptr_type(void); - -/* fix the broken usage of "#define tagptr2_t tagptr3_t" by users */ -#define __tagptr_mask_1(ptr, n) \ - __builtin_types_compatible_p(typeof(ptr), struct __tagptr##n) ? \ - (1UL << (n)) - 1 : - -#define __tagptr_mask(ptr) (\ - __tagptr_mask_1(ptr, 1) ( \ - __tagptr_mask_1(ptr, 2) ( \ - __tagptr_mask_1(ptr, 3) ( \ - __tagptr_mask_1(ptr, 4) ( \ - __bad_tagptr_type(), 0))))) - -/* generate a tagged pointer from a raw value */ -#define tagptr_init(type, val) \ - ((typeof(type)){ .v = (uintptr_t)(val) }) - -/* - * directly cast a tagged pointer to the native pointer type, which - * could be used for backward compatibility of existing code. - */ -#define tagptr_cast_ptr(tptr) ((void *)(tptr).v) - -/* encode tagged pointers */ -#define tagptr_fold(type, ptr, _tags) ({ \ - const typeof(_tags) tags = (_tags); \ - if (__builtin_constant_p(tags) && (tags & ~__tagptr_mask(type))) \ - __bad_tagptr_tags(); \ -tagptr_init(type, (uintptr_t)(ptr) | tags); }) - -/* decode tagged pointers */ -#define tagptr_unfold_ptr(tptr) \ - ((void *)((tptr).v & ~__tagptr_mask(tptr))) - -#define tagptr_unfold_tags(tptr) \ - ((tptr).v & __tagptr_mask(tptr)) - -/* operations for the tagger pointer */ -#define tagptr_eq(_tptr1, _tptr2) ({ \ - typeof(_tptr1) tptr1 = (_tptr1); \ - typeof(_tptr2) tptr2 = (_tptr2); \ - (void)(&tptr1 == &tptr2); \ -(tptr1).v == (tptr2).v; }) - -/* lock-free CAS operation */ -#define tagptr_cmpxchg(_ptptr, _o, _n) ({ \ - typeof(_ptptr) ptptr = (_ptptr); \ - typeof(_o) o = (_o); \ - typeof(_n) n = (_n); \ - (void)(&o == &n); \ - (void)(&o == ptptr); \ -tagptr_init(o, cmpxchg(&ptptr->v, o.v, n.v)); }) - -/* wrap WRITE_ONCE if atomic update is needed */ -#define tagptr_replace_tags(_ptptr, tags) ({ \ - typeof(_ptptr) ptptr = (_ptptr); \ - *ptptr = tagptr_fold(*ptptr, tagptr_unfold_ptr(*ptptr), tags); \ -*ptptr; }) - -#define tagptr_set_tags(_ptptr, _tags) ({ \ - typeof(_ptptr) ptptr = (_ptptr); \ - const typeof(_tags) tags = (_tags); \ - if (__builtin_constant_p(tags) && (tags & ~__tagptr_mask(*ptptr))) \ - __bad_tagptr_tags(); \ - ptptr->v |= tags; \ -*ptptr; }) - -#define tagptr_clear_tags(_ptptr, _tags) ({ \ - typeof(_ptptr) ptptr = (_ptptr); \ - const typeof(_tags) tags = (_tags); \ - if (__builtin_constant_p(tags) && (tags & ~__tagptr_mask(*ptptr))) \ - __bad_tagptr_tags(); \ - ptptr->v &= ~tags; \ -*ptptr; }) - -#endif - diff --git a/drivers/staging/erofs/include/trace/events/erofs.h b/drivers/staging/erofs/include/trace/events/erofs.h deleted file mode 100644 index 660c92fc1803..000000000000 --- a/drivers/staging/erofs/include/trace/events/erofs.h +++ /dev/null @@ -1,256 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM erofs - -#if !defined(_TRACE_EROFS_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_EROFS_H - -#include <linux/tracepoint.h> - -#define show_dev(dev) MAJOR(dev), MINOR(dev) -#define show_dev_nid(entry) show_dev(entry->dev), entry->nid - -#define show_file_type(type) \ - __print_symbolic(type, \ - { 0, "FILE" }, \ - { 1, "DIR" }) - -#define show_map_flags(flags) __print_flags(flags, "|", \ - { EROFS_GET_BLOCKS_RAW, "RAW" }) - -#define show_mflags(flags) __print_flags(flags, "", \ - { EROFS_MAP_MAPPED, "M" }, \ - { EROFS_MAP_META, "I" }, \ - { EROFS_MAP_ZIPPED, "Z" }) - -TRACE_EVENT(erofs_lookup, - - TP_PROTO(struct inode *dir, struct dentry *dentry, unsigned int flags), - - TP_ARGS(dir, dentry, flags), - - TP_STRUCT__entry( - __field(dev_t, dev ) - __field(erofs_nid_t, nid ) - __field(const char *, name ) - __field(unsigned int, flags ) - ), - - TP_fast_assign( - __entry->dev = dir->i_sb->s_dev; - __entry->nid = EROFS_V(dir)->nid; - __entry->name = dentry->d_name.name; - __entry->flags = flags; - ), - - TP_printk("dev = (%d,%d), pnid = %llu, name:%s, flags:%x", - show_dev_nid(__entry), - __entry->name, - __entry->flags) -); - -TRACE_EVENT(erofs_fill_inode, - TP_PROTO(struct inode *inode, int isdir), - TP_ARGS(inode, isdir), - - TP_STRUCT__entry( - __field(dev_t, dev ) - __field(erofs_nid_t, nid ) - __field(erofs_blk_t, blkaddr ) - __field(unsigned int, ofs ) - __field(int, isdir ) - ), - - TP_fast_assign( - __entry->dev = inode->i_sb->s_dev; - __entry->nid = EROFS_V(inode)->nid; - __entry->blkaddr = erofs_blknr(iloc(EROFS_I_SB(inode), __entry->nid)); - __entry->ofs = erofs_blkoff(iloc(EROFS_I_SB(inode), __entry->nid)); - __entry->isdir = isdir; - ), - - TP_printk("dev = (%d,%d), nid = %llu, blkaddr %u ofs %u, isdir %d", - show_dev_nid(__entry), - __entry->blkaddr, __entry->ofs, - __entry->isdir) -); - -TRACE_EVENT(erofs_readpage, - - TP_PROTO(struct page *page, bool raw), - - TP_ARGS(page, raw), - - TP_STRUCT__entry( - __field(dev_t, dev ) - __field(erofs_nid_t, nid ) - __field(int, dir ) - __field(pgoff_t, index ) - __field(int, uptodate) - __field(bool, raw ) - ), - - TP_fast_assign( - __entry->dev = page->mapping->host->i_sb->s_dev; - __entry->nid = EROFS_V(page->mapping->host)->nid; - __entry->dir = S_ISDIR(page->mapping->host->i_mode); - __entry->index = page->index; - __entry->uptodate = PageUptodate(page); - __entry->raw = raw; - ), - - TP_printk("dev = (%d,%d), nid = %llu, %s, index = %lu, uptodate = %d " - "raw = %d", - show_dev_nid(__entry), - show_file_type(__entry->dir), - (unsigned long)__entry->index, - __entry->uptodate, - __entry->raw) -); - -TRACE_EVENT(erofs_readpages, - - TP_PROTO(struct inode *inode, struct page *page, unsigned int nrpage, - bool raw), - - TP_ARGS(inode, page, nrpage, raw), - - TP_STRUCT__entry( - __field(dev_t, dev ) - __field(erofs_nid_t, nid ) - __field(pgoff_t, start ) - __field(unsigned int, nrpage ) - __field(bool, raw ) - ), - - TP_fast_assign( - __entry->dev = inode->i_sb->s_dev; - __entry->nid = EROFS_V(inode)->nid; - __entry->start = page->index; - __entry->nrpage = nrpage; - __entry->raw = raw; - ), - - TP_printk("dev = (%d,%d), nid = %llu, start = %lu nrpage = %u raw = %d", - show_dev_nid(__entry), - (unsigned long)__entry->start, - __entry->nrpage, - __entry->raw) -); - -DECLARE_EVENT_CLASS(erofs__map_blocks_enter, - TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, - unsigned int flags), - - TP_ARGS(inode, map, flags), - - TP_STRUCT__entry( - __field( dev_t, dev ) - __field( erofs_nid_t, nid ) - __field( erofs_off_t, la ) - __field( u64, llen ) - __field( unsigned int, flags ) - ), - - TP_fast_assign( - __entry->dev = inode->i_sb->s_dev; - __entry->nid = EROFS_V(inode)->nid; - __entry->la = map->m_la; - __entry->llen = map->m_llen; - __entry->flags = flags; - ), - - TP_printk("dev = (%d,%d), nid = %llu, la %llu llen %llu flags %s", - show_dev_nid(__entry), - __entry->la, __entry->llen, - __entry->flags ? show_map_flags(__entry->flags) : "NULL") -); - -DEFINE_EVENT(erofs__map_blocks_enter, erofs_map_blocks_flatmode_enter, - TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, - unsigned flags), - - TP_ARGS(inode, map, flags) -); - -DEFINE_EVENT(erofs__map_blocks_enter, z_erofs_map_blocks_iter_enter, - TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, - unsigned int flags), - - TP_ARGS(inode, map, flags) -); - -DECLARE_EVENT_CLASS(erofs__map_blocks_exit, - TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, - unsigned int flags, int ret), - - TP_ARGS(inode, map, flags, ret), - - TP_STRUCT__entry( - __field( dev_t, dev ) - __field( erofs_nid_t, nid ) - __field( unsigned int, flags ) - __field( erofs_off_t, la ) - __field( erofs_off_t, pa ) - __field( u64, llen ) - __field( u64, plen ) - __field( unsigned int, mflags ) - __field( int, ret ) - ), - - TP_fast_assign( - __entry->dev = inode->i_sb->s_dev; - __entry->nid = EROFS_V(inode)->nid; - __entry->flags = flags; - __entry->la = map->m_la; - __entry->pa = map->m_pa; - __entry->llen = map->m_llen; - __entry->plen = map->m_plen; - __entry->mflags = map->m_flags; - __entry->ret = ret; - ), - - TP_printk("dev = (%d,%d), nid = %llu, flags %s " - "la %llu pa %llu llen %llu plen %llu mflags %s ret %d", - show_dev_nid(__entry), - __entry->flags ? show_map_flags(__entry->flags) : "NULL", - __entry->la, __entry->pa, __entry->llen, __entry->plen, - show_mflags(__entry->mflags), __entry->ret) -); - -DEFINE_EVENT(erofs__map_blocks_exit, erofs_map_blocks_flatmode_exit, - TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, - unsigned flags, int ret), - - TP_ARGS(inode, map, flags, ret) -); - -DEFINE_EVENT(erofs__map_blocks_exit, z_erofs_map_blocks_iter_exit, - TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, - unsigned int flags, int ret), - - TP_ARGS(inode, map, flags, ret) -); - -TRACE_EVENT(erofs_destroy_inode, - TP_PROTO(struct inode *inode), - - TP_ARGS(inode), - - TP_STRUCT__entry( - __field( dev_t, dev ) - __field( erofs_nid_t, nid ) - ), - - TP_fast_assign( - __entry->dev = inode->i_sb->s_dev; - __entry->nid = EROFS_V(inode)->nid; - ), - - TP_printk("dev = (%d,%d), nid = %llu", show_dev_nid(__entry)) -); - -#endif /* _TRACE_EROFS_H */ - - /* This part must be outside protection */ -#include <trace/define_trace.h> diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c deleted file mode 100644 index 4c3d8bf8d249..000000000000 --- a/drivers/staging/erofs/inode.c +++ /dev/null @@ -1,332 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/inode.c - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#include "xattr.h" - -#include <trace/events/erofs.h> - -/* no locking */ -static int read_inode(struct inode *inode, void *data) -{ - struct erofs_vnode *vi = EROFS_V(inode); - struct erofs_inode_v1 *v1 = data; - const unsigned int advise = le16_to_cpu(v1->i_advise); - erofs_blk_t nblks = 0; - - vi->datamode = __inode_data_mapping(advise); - - if (unlikely(vi->datamode >= EROFS_INODE_LAYOUT_MAX)) { - errln("unsupported data mapping %u of nid %llu", - vi->datamode, vi->nid); - DBG_BUGON(1); - return -EIO; - } - - if (__inode_version(advise) == EROFS_INODE_LAYOUT_V2) { - struct erofs_inode_v2 *v2 = data; - - vi->inode_isize = sizeof(struct erofs_inode_v2); - vi->xattr_isize = ondisk_xattr_ibody_size(v2->i_xattr_icount); - - inode->i_mode = le16_to_cpu(v2->i_mode); - if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode)) { - vi->raw_blkaddr = le32_to_cpu(v2->i_u.raw_blkaddr); - } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - inode->i_rdev = - new_decode_dev(le32_to_cpu(v2->i_u.rdev)); - } else if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { - inode->i_rdev = 0; - } else { - return -EIO; - } - - i_uid_write(inode, le32_to_cpu(v2->i_uid)); - i_gid_write(inode, le32_to_cpu(v2->i_gid)); - set_nlink(inode, le32_to_cpu(v2->i_nlink)); - - /* ns timestamp */ - inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = - le64_to_cpu(v2->i_ctime); - inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = - le32_to_cpu(v2->i_ctime_nsec); - - inode->i_size = le64_to_cpu(v2->i_size); - - /* total blocks for compressed files */ - if (is_inode_layout_compression(inode)) - nblks = le32_to_cpu(v2->i_u.compressed_blocks); - } else if (__inode_version(advise) == EROFS_INODE_LAYOUT_V1) { - struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); - - vi->inode_isize = sizeof(struct erofs_inode_v1); - vi->xattr_isize = ondisk_xattr_ibody_size(v1->i_xattr_icount); - - inode->i_mode = le16_to_cpu(v1->i_mode); - if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode)) { - vi->raw_blkaddr = le32_to_cpu(v1->i_u.raw_blkaddr); - } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - inode->i_rdev = - new_decode_dev(le32_to_cpu(v1->i_u.rdev)); - } else if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { - inode->i_rdev = 0; - } else { - return -EIO; - } - - i_uid_write(inode, le16_to_cpu(v1->i_uid)); - i_gid_write(inode, le16_to_cpu(v1->i_gid)); - set_nlink(inode, le16_to_cpu(v1->i_nlink)); - - /* use build time to derive all file time */ - inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = - sbi->build_time; - inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = - sbi->build_time_nsec; - - inode->i_size = le32_to_cpu(v1->i_size); - if (is_inode_layout_compression(inode)) - nblks = le32_to_cpu(v1->i_u.compressed_blocks); - } else { - errln("unsupported on-disk inode version %u of nid %llu", - __inode_version(advise), vi->nid); - DBG_BUGON(1); - return -EIO; - } - - if (!nblks) - /* measure inode.i_blocks as generic filesystems */ - inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9; - else - inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK; - return 0; -} - -/* - * try_lock can be required since locking order is: - * file data(fs_inode) - * meta(bd_inode) - * but the majority of the callers is "iget", - * in that case we are pretty sure no deadlock since - * no data operations exist. However I tend to - * try_lock since it takes no much overhead and - * will success immediately. - */ -static int fill_inline_data(struct inode *inode, void *data, - unsigned int m_pofs) -{ - struct erofs_vnode *vi = EROFS_V(inode); - struct erofs_sb_info *sbi = EROFS_I_SB(inode); - - /* should be inode inline C */ - if (!is_inode_flat_inline(inode)) - return 0; - - /* fast symlink (following ext4) */ - if (S_ISLNK(inode->i_mode) && inode->i_size < PAGE_SIZE) { - char *lnk = erofs_kmalloc(sbi, inode->i_size + 1, GFP_KERNEL); - - if (unlikely(!lnk)) - return -ENOMEM; - - m_pofs += vi->inode_isize + vi->xattr_isize; - - /* inline symlink data shouldn't across page boundary as well */ - if (unlikely(m_pofs + inode->i_size > PAGE_SIZE)) { - DBG_BUGON(1); - kfree(lnk); - return -EIO; - } - - /* get in-page inline data */ - memcpy(lnk, data + m_pofs, inode->i_size); - lnk[inode->i_size] = '\0'; - - inode->i_link = lnk; - set_inode_fast_symlink(inode); - } - return 0; -} - -static int fill_inode(struct inode *inode, int isdir) -{ - struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); - struct erofs_vnode *vi = EROFS_V(inode); - struct page *page; - void *data; - int err; - erofs_blk_t blkaddr; - unsigned int ofs; - - trace_erofs_fill_inode(inode, isdir); - - blkaddr = erofs_blknr(iloc(sbi, vi->nid)); - ofs = erofs_blkoff(iloc(sbi, vi->nid)); - - debugln("%s, reading inode nid %llu at %u of blkaddr %u", - __func__, vi->nid, ofs, blkaddr); - - page = erofs_get_meta_page(inode->i_sb, blkaddr, isdir); - - if (IS_ERR(page)) { - errln("failed to get inode (nid: %llu) page, err %ld", - vi->nid, PTR_ERR(page)); - return PTR_ERR(page); - } - - DBG_BUGON(!PageUptodate(page)); - data = page_address(page); - - err = read_inode(inode, data + ofs); - if (!err) { - /* setup the new inode */ - if (S_ISREG(inode->i_mode)) { - inode->i_op = &erofs_generic_iops; - inode->i_fop = &generic_ro_fops; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &erofs_dir_iops; - inode->i_fop = &erofs_dir_fops; - } else if (S_ISLNK(inode->i_mode)) { - /* by default, page_get_link is used for symlink */ - inode->i_op = &erofs_symlink_iops; - inode_nohighmem(inode); - } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || - S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { - inode->i_op = &erofs_generic_iops; - init_special_inode(inode, inode->i_mode, inode->i_rdev); - goto out_unlock; - } else { - err = -EIO; - goto out_unlock; - } - - if (is_inode_layout_compression(inode)) { - err = z_erofs_fill_inode(inode); - goto out_unlock; - } - - inode->i_mapping->a_ops = &erofs_raw_access_aops; - - /* fill last page if inline data is available */ - err = fill_inline_data(inode, data, ofs); - } - -out_unlock: - unlock_page(page); - put_page(page); - return err; -} - -/* - * erofs nid is 64bits, but i_ino is 'unsigned long', therefore - * we should do more for 32-bit platform to find the right inode. - */ -#if BITS_PER_LONG == 32 -static int erofs_ilookup_test_actor(struct inode *inode, void *opaque) -{ - const erofs_nid_t nid = *(erofs_nid_t *)opaque; - - return EROFS_V(inode)->nid == nid; -} - -static int erofs_iget_set_actor(struct inode *inode, void *opaque) -{ - const erofs_nid_t nid = *(erofs_nid_t *)opaque; - - inode->i_ino = erofs_inode_hash(nid); - return 0; -} -#endif - -static inline struct inode *erofs_iget_locked(struct super_block *sb, - erofs_nid_t nid) -{ - const unsigned long hashval = erofs_inode_hash(nid); - -#if BITS_PER_LONG >= 64 - /* it is safe to use iget_locked for >= 64-bit platform */ - return iget_locked(sb, hashval); -#else - return iget5_locked(sb, hashval, erofs_ilookup_test_actor, - erofs_iget_set_actor, &nid); -#endif -} - -struct inode *erofs_iget(struct super_block *sb, - erofs_nid_t nid, - bool isdir) -{ - struct inode *inode = erofs_iget_locked(sb, nid); - - if (unlikely(!inode)) - return ERR_PTR(-ENOMEM); - - if (inode->i_state & I_NEW) { - int err; - struct erofs_vnode *vi = EROFS_V(inode); - - vi->nid = nid; - - err = fill_inode(inode, isdir); - if (likely(!err)) - unlock_new_inode(inode); - else { - iget_failed(inode); - inode = ERR_PTR(err); - } - } - return inode; -} - -int erofs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags) -{ - struct inode *const inode = d_inode(path->dentry); - - if (is_inode_layout_compression(inode)) - stat->attributes |= STATX_ATTR_COMPRESSED; - - stat->attributes |= STATX_ATTR_IMMUTABLE; - stat->attributes_mask |= (STATX_ATTR_COMPRESSED | - STATX_ATTR_IMMUTABLE); - - generic_fillattr(inode, stat); - return 0; -} - -const struct inode_operations erofs_generic_iops = { - .getattr = erofs_getattr, -#ifdef CONFIG_EROFS_FS_XATTR - .listxattr = erofs_listxattr, -#endif - .get_acl = erofs_get_acl, -}; - -const struct inode_operations erofs_symlink_iops = { - .get_link = page_get_link, - .getattr = erofs_getattr, -#ifdef CONFIG_EROFS_FS_XATTR - .listxattr = erofs_listxattr, -#endif - .get_acl = erofs_get_acl, -}; - -const struct inode_operations erofs_fast_symlink_iops = { - .get_link = simple_get_link, - .getattr = erofs_getattr, -#ifdef CONFIG_EROFS_FS_XATTR - .listxattr = erofs_listxattr, -#endif - .get_acl = erofs_get_acl, -}; - diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h deleted file mode 100644 index 963cc1b8b896..000000000000 --- a/drivers/staging/erofs/internal.h +++ /dev/null @@ -1,642 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * linux/drivers/staging/erofs/internal.h - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#ifndef __INTERNAL_H -#define __INTERNAL_H - -#include <linux/fs.h> -#include <linux/dcache.h> -#include <linux/mm.h> -#include <linux/pagemap.h> -#include <linux/bio.h> -#include <linux/buffer_head.h> -#include <linux/cleancache.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include "erofs_fs.h" - -/* redefine pr_fmt "erofs: " */ -#undef pr_fmt -#define pr_fmt(fmt) "erofs: " fmt - -#define errln(x, ...) pr_err(x "\n", ##__VA_ARGS__) -#define infoln(x, ...) pr_info(x "\n", ##__VA_ARGS__) -#ifdef CONFIG_EROFS_FS_DEBUG -#define debugln(x, ...) pr_debug(x "\n", ##__VA_ARGS__) - -#define dbg_might_sleep might_sleep -#define DBG_BUGON BUG_ON -#else -#define debugln(x, ...) ((void)0) - -#define dbg_might_sleep() ((void)0) -#define DBG_BUGON(x) ((void)(x)) -#endif - -enum { - FAULT_KMALLOC, - FAULT_READ_IO, - FAULT_MAX, -}; - -#ifdef CONFIG_EROFS_FAULT_INJECTION -extern const char *erofs_fault_name[FAULT_MAX]; -#define IS_FAULT_SET(fi, type) ((fi)->inject_type & (1 << (type))) - -struct erofs_fault_info { - atomic_t inject_ops; - unsigned int inject_rate; - unsigned int inject_type; -}; -#endif - -#ifdef CONFIG_EROFS_FS_ZIP_CACHE_BIPOLAR -#define EROFS_FS_ZIP_CACHE_LVL (2) -#elif defined(EROFS_FS_ZIP_CACHE_UNIPOLAR) -#define EROFS_FS_ZIP_CACHE_LVL (1) -#else -#define EROFS_FS_ZIP_CACHE_LVL (0) -#endif - -#if (!defined(EROFS_FS_HAS_MANAGED_CACHE) && (EROFS_FS_ZIP_CACHE_LVL > 0)) -#define EROFS_FS_HAS_MANAGED_CACHE -#endif - -/* EROFS_SUPER_MAGIC_V1 to represent the whole file system */ -#define EROFS_SUPER_MAGIC EROFS_SUPER_MAGIC_V1 - -typedef u64 erofs_nid_t; - -struct erofs_sb_info { - /* list for all registered superblocks, mainly for shrinker */ - struct list_head list; - struct mutex umount_mutex; - - u32 blocks; - u32 meta_blkaddr; -#ifdef CONFIG_EROFS_FS_XATTR - u32 xattr_blkaddr; -#endif - - /* inode slot unit size in bit shift */ - unsigned char islotbits; -#ifdef CONFIG_EROFS_FS_ZIP - /* cluster size in bit shift */ - unsigned char clusterbits; - - /* the dedicated workstation for compression */ - struct radix_tree_root workstn_tree; - - /* threshold for decompression synchronously */ - unsigned int max_sync_decompress_pages; - -#ifdef EROFS_FS_HAS_MANAGED_CACHE - struct inode *managed_cache; -#endif - -#endif - - u32 build_time_nsec; - u64 build_time; - - /* what we really care is nid, rather than ino.. */ - erofs_nid_t root_nid; - /* used for statfs, f_files - f_favail */ - u64 inos; - - u8 uuid[16]; /* 128-bit uuid for volume */ - u8 volume_name[16]; /* volume name */ - u32 requirements; - - char *dev_name; - - unsigned int mount_opt; - unsigned int shrinker_run_no; - -#ifdef CONFIG_EROFS_FAULT_INJECTION - struct erofs_fault_info fault_info; /* For fault injection */ -#endif -}; - -#ifdef CONFIG_EROFS_FAULT_INJECTION -#define erofs_show_injection_info(type) \ - infoln("inject %s in %s of %pS", erofs_fault_name[type], \ - __func__, __builtin_return_address(0)) - -static inline bool time_to_inject(struct erofs_sb_info *sbi, int type) -{ - struct erofs_fault_info *ffi = &sbi->fault_info; - - if (!ffi->inject_rate) - return false; - - if (!IS_FAULT_SET(ffi, type)) - return false; - - atomic_inc(&ffi->inject_ops); - if (atomic_read(&ffi->inject_ops) >= ffi->inject_rate) { - atomic_set(&ffi->inject_ops, 0); - return true; - } - return false; -} -#else -static inline bool time_to_inject(struct erofs_sb_info *sbi, int type) -{ - return false; -} - -static inline void erofs_show_injection_info(int type) -{ -} -#endif - -static inline void *erofs_kmalloc(struct erofs_sb_info *sbi, - size_t size, gfp_t flags) -{ - if (time_to_inject(sbi, FAULT_KMALLOC)) { - erofs_show_injection_info(FAULT_KMALLOC); - return NULL; - } - return kmalloc(size, flags); -} - -#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info) -#define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info) - -/* Mount flags set via mount options or defaults */ -#define EROFS_MOUNT_XATTR_USER 0x00000010 -#define EROFS_MOUNT_POSIX_ACL 0x00000020 -#define EROFS_MOUNT_FAULT_INJECTION 0x00000040 - -#define clear_opt(sbi, option) ((sbi)->mount_opt &= ~EROFS_MOUNT_##option) -#define set_opt(sbi, option) ((sbi)->mount_opt |= EROFS_MOUNT_##option) -#define test_opt(sbi, option) ((sbi)->mount_opt & EROFS_MOUNT_##option) - -#ifdef CONFIG_EROFS_FS_ZIP -#define erofs_workstn_lock(sbi) xa_lock(&(sbi)->workstn_tree) -#define erofs_workstn_unlock(sbi) xa_unlock(&(sbi)->workstn_tree) - -/* basic unit of the workstation of a super_block */ -struct erofs_workgroup { - /* the workgroup index in the workstation */ - pgoff_t index; - - /* overall workgroup reference count */ - atomic_t refcount; -}; - -#define EROFS_LOCKED_MAGIC (INT_MIN | 0xE0F510CCL) - -#if defined(CONFIG_SMP) -static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp, - int val) -{ - preempt_disable(); - if (val != atomic_cmpxchg(&grp->refcount, val, EROFS_LOCKED_MAGIC)) { - preempt_enable(); - return false; - } - return true; -} - -static inline void erofs_workgroup_unfreeze(struct erofs_workgroup *grp, - int orig_val) -{ - /* - * other observers should notice all modifications - * in the freezing period. - */ - smp_mb(); - atomic_set(&grp->refcount, orig_val); - preempt_enable(); -} - -static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) -{ - return atomic_cond_read_relaxed(&grp->refcount, - VAL != EROFS_LOCKED_MAGIC); -} -#else -static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp, - int val) -{ - preempt_disable(); - /* no need to spin on UP platforms, let's just disable preemption. */ - if (val != atomic_read(&grp->refcount)) { - preempt_enable(); - return false; - } - return true; -} - -static inline void erofs_workgroup_unfreeze(struct erofs_workgroup *grp, - int orig_val) -{ - preempt_enable(); -} - -static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) -{ - int v = atomic_read(&grp->refcount); - - /* workgroup is never freezed on uniprocessor systems */ - DBG_BUGON(v == EROFS_LOCKED_MAGIC); - return v; -} -#endif - -int erofs_workgroup_put(struct erofs_workgroup *grp); -struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, - pgoff_t index, bool *tag); -int erofs_register_workgroup(struct super_block *sb, - struct erofs_workgroup *grp, bool tag); -unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, - unsigned long nr_shrink, bool cleanup); -void erofs_workgroup_free_rcu(struct erofs_workgroup *grp); - -#ifdef EROFS_FS_HAS_MANAGED_CACHE -int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, - struct erofs_workgroup *egrp); -int erofs_try_to_free_cached_page(struct address_space *mapping, - struct page *page); - -#define MNGD_MAPPING(sbi) ((sbi)->managed_cache->i_mapping) -static inline bool erofs_page_is_managed(const struct erofs_sb_info *sbi, - struct page *page) -{ - return page->mapping == MNGD_MAPPING(sbi); -} -#else -#define MNGD_MAPPING(sbi) (NULL) -static inline bool erofs_page_is_managed(const struct erofs_sb_info *sbi, - struct page *page) { return false; } -#endif - -#define DEFAULT_MAX_SYNC_DECOMPRESS_PAGES 3 - -static inline bool __should_decompress_synchronously(struct erofs_sb_info *sbi, - unsigned int nr) -{ - return nr <= sbi->max_sync_decompress_pages; -} - -int __init z_erofs_init_zip_subsystem(void); -void z_erofs_exit_zip_subsystem(void); -#else -/* dummy initializer/finalizer for the decompression subsystem */ -static inline int z_erofs_init_zip_subsystem(void) { return 0; } -static inline void z_erofs_exit_zip_subsystem(void) {} -#endif - -/* we strictly follow PAGE_SIZE and no buffer head yet */ -#define LOG_BLOCK_SIZE PAGE_SHIFT - -#undef LOG_SECTORS_PER_BLOCK -#define LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) - -#undef SECTORS_PER_BLOCK -#define SECTORS_PER_BLOCK (1 << SECTORS_PER_BLOCK) - -#define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE) - -#if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ) -#error erofs cannot be used in this platform -#endif - -#define ROOT_NID(sb) ((sb)->root_nid) - -#ifdef CONFIG_EROFS_FS_ZIP -/* hard limit of pages per compressed cluster */ -#define Z_EROFS_CLUSTER_MAX_PAGES (CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT) - -/* page count of a compressed cluster */ -#define erofs_clusterpages(sbi) ((1 << (sbi)->clusterbits) / PAGE_SIZE) - -#define EROFS_PCPUBUF_NR_PAGES Z_EROFS_CLUSTER_MAX_PAGES -#else -#define EROFS_PCPUBUF_NR_PAGES 0 -#endif - -typedef u64 erofs_off_t; - -/* data type for filesystem-wide blocks number */ -typedef u32 erofs_blk_t; - -#define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ) -#define erofs_blkoff(addr) ((addr) % EROFS_BLKSIZ) -#define blknr_to_addr(nr) ((erofs_off_t)(nr) * EROFS_BLKSIZ) - -static inline erofs_off_t iloc(struct erofs_sb_info *sbi, erofs_nid_t nid) -{ - return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits); -} - -/* atomic flag definitions */ -#define EROFS_V_EA_INITED_BIT 0 -#define EROFS_V_Z_INITED_BIT 1 - -/* bitlock definitions (arranged in reverse order) */ -#define EROFS_V_BL_XATTR_BIT (BITS_PER_LONG - 1) -#define EROFS_V_BL_Z_BIT (BITS_PER_LONG - 2) - -struct erofs_vnode { - erofs_nid_t nid; - - /* atomic flags (including bitlocks) */ - unsigned long flags; - - unsigned char datamode; - unsigned char inode_isize; - unsigned short xattr_isize; - - unsigned xattr_shared_count; - unsigned *xattr_shared_xattrs; - - union { - erofs_blk_t raw_blkaddr; -#ifdef CONFIG_EROFS_FS_ZIP - struct { - unsigned short z_advise; - unsigned char z_algorithmtype[2]; - unsigned char z_logical_clusterbits; - unsigned char z_physical_clusterbits[2]; - }; -#endif - }; - /* the corresponding vfs inode */ - struct inode vfs_inode; -}; - -#define EROFS_V(ptr) \ - container_of(ptr, struct erofs_vnode, vfs_inode) - -#define __inode_advise(x, bit, bits) \ - (((x) >> (bit)) & ((1 << (bits)) - 1)) - -#define __inode_version(advise) \ - __inode_advise(advise, EROFS_I_VERSION_BIT, \ - EROFS_I_VERSION_BITS) - -#define __inode_data_mapping(advise) \ - __inode_advise(advise, EROFS_I_DATA_MAPPING_BIT,\ - EROFS_I_DATA_MAPPING_BITS) - -static inline unsigned long inode_datablocks(struct inode *inode) -{ - /* since i_size cannot be changed */ - return DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); -} - -static inline bool is_inode_layout_compression(struct inode *inode) -{ - return erofs_inode_is_data_compressed(EROFS_V(inode)->datamode); -} - -static inline bool is_inode_flat_inline(struct inode *inode) -{ - return EROFS_V(inode)->datamode == EROFS_INODE_FLAT_INLINE; -} - -extern const struct super_operations erofs_sops; - -extern const struct address_space_operations erofs_raw_access_aops; -#ifdef CONFIG_EROFS_FS_ZIP -extern const struct address_space_operations z_erofs_vle_normalaccess_aops; -#endif - -/* - * Logical to physical block mapping, used by erofs_map_blocks() - * - * Different with other file systems, it is used for 2 access modes: - * - * 1) RAW access mode: - * - * Users pass a valid (m_lblk, m_lofs -- usually 0) pair, - * and get the valid m_pblk, m_pofs and the longest m_len(in bytes). - * - * Note that m_lblk in the RAW access mode refers to the number of - * the compressed ondisk block rather than the uncompressed - * in-memory block for the compressed file. - * - * m_pofs equals to m_lofs except for the inline data page. - * - * 2) Normal access mode: - * - * If the inode is not compressed, it has no difference with - * the RAW access mode. However, if the inode is compressed, - * users should pass a valid (m_lblk, m_lofs) pair, and get - * the needed m_pblk, m_pofs, m_len to get the compressed data - * and the updated m_lblk, m_lofs which indicates the start - * of the corresponding uncompressed data in the file. - */ -enum { - BH_Zipped = BH_PrivateStart, - BH_FullMapped, -}; - -/* Has a disk mapping */ -#define EROFS_MAP_MAPPED (1 << BH_Mapped) -/* Located in metadata (could be copied from bd_inode) */ -#define EROFS_MAP_META (1 << BH_Meta) -/* The extent has been compressed */ -#define EROFS_MAP_ZIPPED (1 << BH_Zipped) -/* The length of extent is full */ -#define EROFS_MAP_FULL_MAPPED (1 << BH_FullMapped) - -struct erofs_map_blocks { - erofs_off_t m_pa, m_la; - u64 m_plen, m_llen; - - unsigned int m_flags; - - struct page *mpage; -}; - -/* Flags used by erofs_map_blocks() */ -#define EROFS_GET_BLOCKS_RAW 0x0001 - -/* zmap.c */ -#ifdef CONFIG_EROFS_FS_ZIP -int z_erofs_fill_inode(struct inode *inode); -int z_erofs_map_blocks_iter(struct inode *inode, - struct erofs_map_blocks *map, - int flags); -#else -static inline int z_erofs_fill_inode(struct inode *inode) { return -ENOTSUPP; } -static inline int z_erofs_map_blocks_iter(struct inode *inode, - struct erofs_map_blocks *map, - int flags) -{ - return -ENOTSUPP; -} -#endif - -/* data.c */ -static inline struct bio * -erofs_grab_bio(struct super_block *sb, - erofs_blk_t blkaddr, unsigned int nr_pages, void *bi_private, - bio_end_io_t endio, bool nofail) -{ - const gfp_t gfp = GFP_NOIO; - struct bio *bio; - - do { - if (nr_pages == 1) { - bio = bio_alloc(gfp | (nofail ? __GFP_NOFAIL : 0), 1); - if (unlikely(!bio)) { - DBG_BUGON(nofail); - return ERR_PTR(-ENOMEM); - } - break; - } - bio = bio_alloc(gfp, nr_pages); - nr_pages /= 2; - } while (unlikely(!bio)); - - bio->bi_end_io = endio; - bio_set_dev(bio, sb->s_bdev); - bio->bi_iter.bi_sector = (sector_t)blkaddr << LOG_SECTORS_PER_BLOCK; - bio->bi_private = bi_private; - return bio; -} - -static inline void __submit_bio(struct bio *bio, unsigned op, unsigned op_flags) -{ - bio_set_op_attrs(bio, op, op_flags); - submit_bio(bio); -} - -#ifndef CONFIG_EROFS_FS_IO_MAX_RETRIES -#define EROFS_IO_MAX_RETRIES_NOFAIL 0 -#else -#define EROFS_IO_MAX_RETRIES_NOFAIL CONFIG_EROFS_FS_IO_MAX_RETRIES -#endif - -struct page *__erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr, - bool prio, bool nofail); - -static inline struct page *erofs_get_meta_page(struct super_block *sb, - erofs_blk_t blkaddr, bool prio) -{ - return __erofs_get_meta_page(sb, blkaddr, prio, false); -} - -static inline struct page *erofs_get_meta_page_nofail(struct super_block *sb, - erofs_blk_t blkaddr, bool prio) -{ - return __erofs_get_meta_page(sb, blkaddr, prio, true); -} - -int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int); - -static inline struct page * -erofs_get_inline_page(struct inode *inode, - erofs_blk_t blkaddr) -{ - return erofs_get_meta_page(inode->i_sb, - blkaddr, S_ISDIR(inode->i_mode)); -} - -/* inode.c */ -static inline unsigned long erofs_inode_hash(erofs_nid_t nid) -{ -#if BITS_PER_LONG == 32 - return (nid >> 32) ^ (nid & 0xffffffff); -#else - return nid; -#endif -} - -extern const struct inode_operations erofs_generic_iops; -extern const struct inode_operations erofs_symlink_iops; -extern const struct inode_operations erofs_fast_symlink_iops; - -static inline void set_inode_fast_symlink(struct inode *inode) -{ - inode->i_op = &erofs_fast_symlink_iops; -} - -static inline bool is_inode_fast_symlink(struct inode *inode) -{ - return inode->i_op == &erofs_fast_symlink_iops; -} - -struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir); -int erofs_getattr(const struct path *path, struct kstat *stat, - u32 request_mask, unsigned int query_flags); - -/* namei.c */ -extern const struct inode_operations erofs_dir_iops; - -int erofs_namei(struct inode *dir, struct qstr *name, - erofs_nid_t *nid, unsigned int *d_type); - -/* dir.c */ -extern const struct file_operations erofs_dir_fops; - -static inline void *erofs_vmap(struct page **pages, unsigned int count) -{ -#ifdef CONFIG_EROFS_FS_USE_VM_MAP_RAM - int i = 0; - - while (1) { - void *addr = vm_map_ram(pages, count, -1, PAGE_KERNEL); - /* retry two more times (totally 3 times) */ - if (addr || ++i >= 3) - return addr; - vm_unmap_aliases(); - } - return NULL; -#else - return vmap(pages, count, VM_MAP, PAGE_KERNEL); -#endif -} - -static inline void erofs_vunmap(const void *mem, unsigned int count) -{ -#ifdef CONFIG_EROFS_FS_USE_VM_MAP_RAM - vm_unmap_ram(mem, count); -#else - vunmap(mem); -#endif -} - -/* utils.c */ -extern struct shrinker erofs_shrinker_info; - -struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp); - -#if (EROFS_PCPUBUF_NR_PAGES > 0) -void *erofs_get_pcpubuf(unsigned int pagenr); -#define erofs_put_pcpubuf(buf) do { \ - (void)&(buf); \ - preempt_enable(); \ -} while (0) -#else -static inline void *erofs_get_pcpubuf(unsigned int pagenr) -{ - return ERR_PTR(-ENOTSUPP); -} - -#define erofs_put_pcpubuf(buf) do {} while (0) -#endif - -void erofs_register_super(struct super_block *sb); -void erofs_unregister_super(struct super_block *sb); - -#ifndef lru_to_page -#define lru_to_page(head) (list_entry((head)->prev, struct page, lru)) -#endif - -#endif - diff --git a/drivers/staging/erofs/namei.c b/drivers/staging/erofs/namei.c deleted file mode 100644 index fd3ae78d0ba5..000000000000 --- a/drivers/staging/erofs/namei.c +++ /dev/null @@ -1,256 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/namei.c - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#include "internal.h" -#include "xattr.h" - -#include <trace/events/erofs.h> - -struct erofs_qstr { - const unsigned char *name; - const unsigned char *end; -}; - -/* based on the end of qn is accurate and it must have the trailing '\0' */ -static inline int dirnamecmp(const struct erofs_qstr *qn, - const struct erofs_qstr *qd, - unsigned int *matched) -{ - unsigned int i = *matched; - - /* - * on-disk error, let's only BUG_ON in the debugging mode. - * otherwise, it will return 1 to just skip the invalid name - * and go on (in consideration of the lookup performance). - */ - DBG_BUGON(qd->name > qd->end); - - /* qd could not have trailing '\0' */ - /* However it is absolutely safe if < qd->end */ - while (qd->name + i < qd->end && qd->name[i] != '\0') { - if (qn->name[i] != qd->name[i]) { - *matched = i; - return qn->name[i] > qd->name[i] ? 1 : -1; - } - ++i; - } - *matched = i; - /* See comments in __d_alloc on the terminating NUL character */ - return qn->name[i] == '\0' ? 0 : 1; -} - -#define nameoff_from_disk(off, sz) (le16_to_cpu(off) & ((sz) - 1)) - -static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name, - u8 *data, - unsigned int dirblksize, - const int ndirents) -{ - int head, back; - unsigned int startprfx, endprfx; - struct erofs_dirent *const de = (struct erofs_dirent *)data; - - /* since the 1st dirent has been evaluated previously */ - head = 1; - back = ndirents - 1; - startprfx = endprfx = 0; - - while (head <= back) { - const int mid = head + (back - head) / 2; - const int nameoff = nameoff_from_disk(de[mid].nameoff, - dirblksize); - unsigned int matched = min(startprfx, endprfx); - struct erofs_qstr dname = { - .name = data + nameoff, - .end = unlikely(mid >= ndirents - 1) ? - data + dirblksize : - data + nameoff_from_disk(de[mid + 1].nameoff, - dirblksize) - }; - - /* string comparison without already matched prefix */ - int ret = dirnamecmp(name, &dname, &matched); - - if (unlikely(!ret)) { - return de + mid; - } else if (ret > 0) { - head = mid + 1; - startprfx = matched; - } else { - back = mid - 1; - endprfx = matched; - } - } - - return ERR_PTR(-ENOENT); -} - -static struct page *find_target_block_classic(struct inode *dir, - struct erofs_qstr *name, - int *_ndirents) -{ - unsigned int startprfx, endprfx; - int head, back; - struct address_space *const mapping = dir->i_mapping; - struct page *candidate = ERR_PTR(-ENOENT); - - startprfx = endprfx = 0; - head = 0; - back = inode_datablocks(dir) - 1; - - while (head <= back) { - const int mid = head + (back - head) / 2; - struct page *page = read_mapping_page(mapping, mid, NULL); - - if (!IS_ERR(page)) { - struct erofs_dirent *de = kmap_atomic(page); - const int nameoff = nameoff_from_disk(de->nameoff, - EROFS_BLKSIZ); - const int ndirents = nameoff / sizeof(*de); - int diff; - unsigned int matched; - struct erofs_qstr dname; - - if (unlikely(!ndirents)) { - DBG_BUGON(1); - kunmap_atomic(de); - put_page(page); - page = ERR_PTR(-EIO); - goto out; - } - - matched = min(startprfx, endprfx); - - dname.name = (u8 *)de + nameoff; - if (ndirents == 1) - dname.end = (u8 *)de + EROFS_BLKSIZ; - else - dname.end = (u8 *)de + - nameoff_from_disk(de[1].nameoff, - EROFS_BLKSIZ); - - /* string comparison without already matched prefix */ - diff = dirnamecmp(name, &dname, &matched); - kunmap_atomic(de); - - if (unlikely(!diff)) { - *_ndirents = 0; - goto out; - } else if (diff > 0) { - head = mid + 1; - startprfx = matched; - - if (!IS_ERR(candidate)) - put_page(candidate); - candidate = page; - *_ndirents = ndirents; - } else { - put_page(page); - - back = mid - 1; - endprfx = matched; - } - continue; - } -out: /* free if the candidate is valid */ - if (!IS_ERR(candidate)) - put_page(candidate); - return page; - } - return candidate; -} - -int erofs_namei(struct inode *dir, - struct qstr *name, - erofs_nid_t *nid, unsigned int *d_type) -{ - int ndirents; - struct page *page; - void *data; - struct erofs_dirent *de; - struct erofs_qstr qn; - - if (unlikely(!dir->i_size)) - return -ENOENT; - - qn.name = name->name; - qn.end = name->name + name->len; - - ndirents = 0; - page = find_target_block_classic(dir, &qn, &ndirents); - - if (IS_ERR(page)) - return PTR_ERR(page); - - data = kmap_atomic(page); - /* the target page has been mapped */ - if (ndirents) - de = find_target_dirent(&qn, data, EROFS_BLKSIZ, ndirents); - else - de = (struct erofs_dirent *)data; - - if (!IS_ERR(de)) { - *nid = le64_to_cpu(de->nid); - *d_type = de->file_type; - } - - kunmap_atomic(data); - put_page(page); - - return PTR_ERR_OR_ZERO(de); -} - -/* NOTE: i_mutex is already held by vfs */ -static struct dentry *erofs_lookup(struct inode *dir, - struct dentry *dentry, - unsigned int flags) -{ - int err; - erofs_nid_t nid; - unsigned int d_type; - struct inode *inode; - - DBG_BUGON(!d_really_is_negative(dentry)); - /* dentry must be unhashed in lookup, no need to worry about */ - DBG_BUGON(!d_unhashed(dentry)); - - trace_erofs_lookup(dir, dentry, flags); - - /* file name exceeds fs limit */ - if (unlikely(dentry->d_name.len > EROFS_NAME_LEN)) - return ERR_PTR(-ENAMETOOLONG); - - /* false uninitialized warnings on gcc 4.8.x */ - err = erofs_namei(dir, &dentry->d_name, &nid, &d_type); - - if (err == -ENOENT) { - /* negative dentry */ - inode = NULL; - } else if (unlikely(err)) { - inode = ERR_PTR(err); - } else { - debugln("%s, %s (nid %llu) found, d_type %u", __func__, - dentry->d_name.name, nid, d_type); - inode = erofs_iget(dir->i_sb, nid, d_type == EROFS_FT_DIR); - } - return d_splice_alias(inode, dentry); -} - -const struct inode_operations erofs_dir_iops = { - .lookup = erofs_lookup, - .getattr = erofs_getattr, -#ifdef CONFIG_EROFS_FS_XATTR - .listxattr = erofs_listxattr, -#endif - .get_acl = erofs_get_acl, -}; - diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c deleted file mode 100644 index 54494412eba4..000000000000 --- a/drivers/staging/erofs/super.c +++ /dev/null @@ -1,701 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/super.c - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#include <linux/module.h> -#include <linux/buffer_head.h> -#include <linux/statfs.h> -#include <linux/parser.h> -#include <linux/seq_file.h> -#include "internal.h" -#include "xattr.h" - -#define CREATE_TRACE_POINTS -#include <trace/events/erofs.h> - -static struct kmem_cache *erofs_inode_cachep __read_mostly; - -static void init_once(void *ptr) -{ - struct erofs_vnode *vi = ptr; - - inode_init_once(&vi->vfs_inode); -} - -static int __init erofs_init_inode_cache(void) -{ - erofs_inode_cachep = kmem_cache_create("erofs_inode", - sizeof(struct erofs_vnode), 0, - SLAB_RECLAIM_ACCOUNT, - init_once); - - return erofs_inode_cachep ? 0 : -ENOMEM; -} - -static void erofs_exit_inode_cache(void) -{ - kmem_cache_destroy(erofs_inode_cachep); -} - -static struct inode *alloc_inode(struct super_block *sb) -{ - struct erofs_vnode *vi = - kmem_cache_alloc(erofs_inode_cachep, GFP_KERNEL); - - if (!vi) - return NULL; - - /* zero out everything except vfs_inode */ - memset(vi, 0, offsetof(struct erofs_vnode, vfs_inode)); - return &vi->vfs_inode; -} - -static void free_inode(struct inode *inode) -{ - struct erofs_vnode *vi = EROFS_V(inode); - - /* be careful RCU symlink path (see ext4_inode_info->i_data)! */ - if (is_inode_fast_symlink(inode)) - kfree(inode->i_link); - - kfree(vi->xattr_shared_xattrs); - - kmem_cache_free(erofs_inode_cachep, vi); -} - -static bool check_layout_compatibility(struct super_block *sb, - struct erofs_super_block *layout) -{ - const unsigned int requirements = le32_to_cpu(layout->requirements); - - EROFS_SB(sb)->requirements = requirements; - - /* check if current kernel meets all mandatory requirements */ - if (requirements & (~EROFS_ALL_REQUIREMENTS)) { - errln("unidentified requirements %x, please upgrade kernel version", - requirements & ~EROFS_ALL_REQUIREMENTS); - return false; - } - return true; -} - -static int superblock_read(struct super_block *sb) -{ - struct erofs_sb_info *sbi; - struct buffer_head *bh; - struct erofs_super_block *layout; - unsigned int blkszbits; - int ret; - - bh = sb_bread(sb, 0); - - if (!bh) { - errln("cannot read erofs superblock"); - return -EIO; - } - - sbi = EROFS_SB(sb); - layout = (struct erofs_super_block *)((u8 *)bh->b_data - + EROFS_SUPER_OFFSET); - - ret = -EINVAL; - if (le32_to_cpu(layout->magic) != EROFS_SUPER_MAGIC_V1) { - errln("cannot find valid erofs superblock"); - goto out; - } - - blkszbits = layout->blkszbits; - /* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */ - if (unlikely(blkszbits != LOG_BLOCK_SIZE)) { - errln("blksize %u isn't supported on this platform", - 1 << blkszbits); - goto out; - } - - if (!check_layout_compatibility(sb, layout)) - goto out; - - sbi->blocks = le32_to_cpu(layout->blocks); - sbi->meta_blkaddr = le32_to_cpu(layout->meta_blkaddr); -#ifdef CONFIG_EROFS_FS_XATTR - sbi->xattr_blkaddr = le32_to_cpu(layout->xattr_blkaddr); -#endif - sbi->islotbits = ffs(sizeof(struct erofs_inode_v1)) - 1; -#ifdef CONFIG_EROFS_FS_ZIP - /* TODO: clusterbits should be related to inode */ - sbi->clusterbits = blkszbits; - - if (1 << (sbi->clusterbits - PAGE_SHIFT) > Z_EROFS_CLUSTER_MAX_PAGES) - errln("clusterbits %u is not supported on this kernel", - sbi->clusterbits); -#endif - - sbi->root_nid = le16_to_cpu(layout->root_nid); - sbi->inos = le64_to_cpu(layout->inos); - - sbi->build_time = le64_to_cpu(layout->build_time); - sbi->build_time_nsec = le32_to_cpu(layout->build_time_nsec); - - memcpy(&sb->s_uuid, layout->uuid, sizeof(layout->uuid)); - memcpy(sbi->volume_name, layout->volume_name, - sizeof(layout->volume_name)); - - ret = 0; -out: - brelse(bh); - return ret; -} - -#ifdef CONFIG_EROFS_FAULT_INJECTION -const char *erofs_fault_name[FAULT_MAX] = { - [FAULT_KMALLOC] = "kmalloc", - [FAULT_READ_IO] = "read IO error", -}; - -static void __erofs_build_fault_attr(struct erofs_sb_info *sbi, - unsigned int rate) -{ - struct erofs_fault_info *ffi = &sbi->fault_info; - - if (rate) { - atomic_set(&ffi->inject_ops, 0); - ffi->inject_rate = rate; - ffi->inject_type = (1 << FAULT_MAX) - 1; - } else { - memset(ffi, 0, sizeof(struct erofs_fault_info)); - } - - set_opt(sbi, FAULT_INJECTION); -} - -static int erofs_build_fault_attr(struct erofs_sb_info *sbi, - substring_t *args) -{ - int rate = 0; - - if (args->from && match_int(args, &rate)) - return -EINVAL; - - __erofs_build_fault_attr(sbi, rate); - return 0; -} - -static unsigned int erofs_get_fault_rate(struct erofs_sb_info *sbi) -{ - return sbi->fault_info.inject_rate; -} -#else -static void __erofs_build_fault_attr(struct erofs_sb_info *sbi, - unsigned int rate) -{ -} - -static int erofs_build_fault_attr(struct erofs_sb_info *sbi, - substring_t *args) -{ - infoln("fault_injection options not supported"); - return 0; -} - -static unsigned int erofs_get_fault_rate(struct erofs_sb_info *sbi) -{ - return 0; -} -#endif - -static void default_options(struct erofs_sb_info *sbi) -{ - /* set up some FS parameters */ -#ifdef CONFIG_EROFS_FS_ZIP - sbi->max_sync_decompress_pages = DEFAULT_MAX_SYNC_DECOMPRESS_PAGES; -#endif - -#ifdef CONFIG_EROFS_FS_XATTR - set_opt(sbi, XATTR_USER); -#endif - -#ifdef CONFIG_EROFS_FS_POSIX_ACL - set_opt(sbi, POSIX_ACL); -#endif -} - -enum { - Opt_user_xattr, - Opt_nouser_xattr, - Opt_acl, - Opt_noacl, - Opt_fault_injection, - Opt_err -}; - -static match_table_t erofs_tokens = { - {Opt_user_xattr, "user_xattr"}, - {Opt_nouser_xattr, "nouser_xattr"}, - {Opt_acl, "acl"}, - {Opt_noacl, "noacl"}, - {Opt_fault_injection, "fault_injection=%u"}, - {Opt_err, NULL} -}; - -static int parse_options(struct super_block *sb, char *options) -{ - substring_t args[MAX_OPT_ARGS]; - char *p; - int err; - - if (!options) - return 0; - - while ((p = strsep(&options, ","))) { - int token; - - if (!*p) - continue; - - args[0].to = args[0].from = NULL; - token = match_token(p, erofs_tokens, args); - - switch (token) { -#ifdef CONFIG_EROFS_FS_XATTR - case Opt_user_xattr: - set_opt(EROFS_SB(sb), XATTR_USER); - break; - case Opt_nouser_xattr: - clear_opt(EROFS_SB(sb), XATTR_USER); - break; -#else - case Opt_user_xattr: - infoln("user_xattr options not supported"); - break; - case Opt_nouser_xattr: - infoln("nouser_xattr options not supported"); - break; -#endif -#ifdef CONFIG_EROFS_FS_POSIX_ACL - case Opt_acl: - set_opt(EROFS_SB(sb), POSIX_ACL); - break; - case Opt_noacl: - clear_opt(EROFS_SB(sb), POSIX_ACL); - break; -#else - case Opt_acl: - infoln("acl options not supported"); - break; - case Opt_noacl: - infoln("noacl options not supported"); - break; -#endif - case Opt_fault_injection: - err = erofs_build_fault_attr(EROFS_SB(sb), args); - if (err) - return err; - break; - - default: - errln("Unrecognized mount option \"%s\" " - "or missing value", p); - return -EINVAL; - } - } - return 0; -} - -#ifdef EROFS_FS_HAS_MANAGED_CACHE - -static const struct address_space_operations managed_cache_aops; - -static int managed_cache_releasepage(struct page *page, gfp_t gfp_mask) -{ - int ret = 1; /* 0 - busy */ - struct address_space *const mapping = page->mapping; - - DBG_BUGON(!PageLocked(page)); - DBG_BUGON(mapping->a_ops != &managed_cache_aops); - - if (PagePrivate(page)) - ret = erofs_try_to_free_cached_page(mapping, page); - - return ret; -} - -static void managed_cache_invalidatepage(struct page *page, - unsigned int offset, - unsigned int length) -{ - const unsigned int stop = length + offset; - - DBG_BUGON(!PageLocked(page)); - - /* Check for potential overflow in debug mode */ - DBG_BUGON(stop > PAGE_SIZE || stop < length); - - if (offset == 0 && stop == PAGE_SIZE) - while (!managed_cache_releasepage(page, GFP_NOFS)) - cond_resched(); -} - -static const struct address_space_operations managed_cache_aops = { - .releasepage = managed_cache_releasepage, - .invalidatepage = managed_cache_invalidatepage, -}; - -static struct inode *erofs_init_managed_cache(struct super_block *sb) -{ - struct inode *inode = new_inode(sb); - - if (unlikely(!inode)) - return ERR_PTR(-ENOMEM); - - set_nlink(inode, 1); - inode->i_size = OFFSET_MAX; - - inode->i_mapping->a_ops = &managed_cache_aops; - mapping_set_gfp_mask(inode->i_mapping, - GFP_NOFS | __GFP_HIGHMEM | - __GFP_MOVABLE | __GFP_NOFAIL); - return inode; -} - -#endif - -static int erofs_read_super(struct super_block *sb, - const char *dev_name, - void *data, int silent) -{ - struct inode *inode; - struct erofs_sb_info *sbi; - int err = -EINVAL; - - infoln("read_super, device -> %s", dev_name); - infoln("options -> %s", (char *)data); - - if (unlikely(!sb_set_blocksize(sb, EROFS_BLKSIZ))) { - errln("failed to set erofs blksize"); - goto err; - } - - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); - if (unlikely(!sbi)) { - err = -ENOMEM; - goto err; - } - sb->s_fs_info = sbi; - - err = superblock_read(sb); - if (err) - goto err_sbread; - - sb->s_magic = EROFS_SUPER_MAGIC; - sb->s_flags |= SB_RDONLY | SB_NOATIME; - sb->s_maxbytes = MAX_LFS_FILESIZE; - sb->s_time_gran = 1; - - sb->s_op = &erofs_sops; - -#ifdef CONFIG_EROFS_FS_XATTR - sb->s_xattr = erofs_xattr_handlers; -#endif - - /* set erofs default mount options */ - default_options(sbi); - - err = parse_options(sb, data); - if (err) - goto err_parseopt; - - if (!silent) - infoln("root inode @ nid %llu", ROOT_NID(sbi)); - - if (test_opt(sbi, POSIX_ACL)) - sb->s_flags |= SB_POSIXACL; - else - sb->s_flags &= ~SB_POSIXACL; - -#ifdef CONFIG_EROFS_FS_ZIP - INIT_RADIX_TREE(&sbi->workstn_tree, GFP_ATOMIC); -#endif - -#ifdef EROFS_FS_HAS_MANAGED_CACHE - sbi->managed_cache = erofs_init_managed_cache(sb); - if (IS_ERR(sbi->managed_cache)) { - err = PTR_ERR(sbi->managed_cache); - goto err_init_managed_cache; - } -#endif - - /* get the root inode */ - inode = erofs_iget(sb, ROOT_NID(sbi), true); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - goto err_iget; - } - - if (!S_ISDIR(inode->i_mode)) { - errln("rootino(nid %llu) is not a directory(i_mode %o)", - ROOT_NID(sbi), inode->i_mode); - err = -EINVAL; - iput(inode); - goto err_iget; - } - - sb->s_root = d_make_root(inode); - if (!sb->s_root) { - err = -ENOMEM; - goto err_iget; - } - - /* save the device name to sbi */ - sbi->dev_name = __getname(); - if (!sbi->dev_name) { - err = -ENOMEM; - goto err_devname; - } - - snprintf(sbi->dev_name, PATH_MAX, "%s", dev_name); - sbi->dev_name[PATH_MAX - 1] = '\0'; - - erofs_register_super(sb); - - if (!silent) - infoln("mounted on %s with opts: %s.", dev_name, - (char *)data); - return 0; - /* - * please add a label for each exit point and use - * the following name convention, thus new features - * can be integrated easily without renaming labels. - */ -err_devname: - dput(sb->s_root); - sb->s_root = NULL; -err_iget: -#ifdef EROFS_FS_HAS_MANAGED_CACHE - iput(sbi->managed_cache); -err_init_managed_cache: -#endif -err_parseopt: -err_sbread: - sb->s_fs_info = NULL; - kfree(sbi); -err: - return err; -} - -/* - * could be triggered after deactivate_locked_super() - * is called, thus including umount and failed to initialize. - */ -static void erofs_put_super(struct super_block *sb) -{ - struct erofs_sb_info *sbi = EROFS_SB(sb); - - /* for cases which are failed in "read_super" */ - if (!sbi) - return; - - WARN_ON(sb->s_magic != EROFS_SUPER_MAGIC); - - infoln("unmounted for %s", sbi->dev_name); - __putname(sbi->dev_name); - -#ifdef EROFS_FS_HAS_MANAGED_CACHE - iput(sbi->managed_cache); -#endif - - mutex_lock(&sbi->umount_mutex); - -#ifdef CONFIG_EROFS_FS_ZIP - /* clean up the compression space of this sb */ - erofs_shrink_workstation(EROFS_SB(sb), ~0UL, true); -#endif - - erofs_unregister_super(sb); - mutex_unlock(&sbi->umount_mutex); - - kfree(sbi); - sb->s_fs_info = NULL; -} - - -struct erofs_mount_private { - const char *dev_name; - char *options; -}; - -/* support mount_bdev() with options */ -static int erofs_fill_super(struct super_block *sb, - void *_priv, int silent) -{ - struct erofs_mount_private *priv = _priv; - - return erofs_read_super(sb, priv->dev_name, - priv->options, silent); -} - -static struct dentry *erofs_mount( - struct file_system_type *fs_type, int flags, - const char *dev_name, void *data) -{ - struct erofs_mount_private priv = { - .dev_name = dev_name, - .options = data - }; - - return mount_bdev(fs_type, flags, dev_name, - &priv, erofs_fill_super); -} - -static void erofs_kill_sb(struct super_block *sb) -{ - kill_block_super(sb); -} - -static struct file_system_type erofs_fs_type = { - .owner = THIS_MODULE, - .name = "erofs", - .mount = erofs_mount, - .kill_sb = erofs_kill_sb, - .fs_flags = FS_REQUIRES_DEV, -}; -MODULE_ALIAS_FS("erofs"); - -static int __init erofs_module_init(void) -{ - int err; - - erofs_check_ondisk_layout_definitions(); - infoln("initializing erofs " EROFS_VERSION); - - err = erofs_init_inode_cache(); - if (err) - goto icache_err; - - err = register_shrinker(&erofs_shrinker_info); - if (err) - goto shrinker_err; - - err = z_erofs_init_zip_subsystem(); - if (err) - goto zip_err; - - err = register_filesystem(&erofs_fs_type); - if (err) - goto fs_err; - - infoln("successfully to initialize erofs"); - return 0; - -fs_err: - z_erofs_exit_zip_subsystem(); -zip_err: - unregister_shrinker(&erofs_shrinker_info); -shrinker_err: - erofs_exit_inode_cache(); -icache_err: - return err; -} - -static void __exit erofs_module_exit(void) -{ - unregister_filesystem(&erofs_fs_type); - z_erofs_exit_zip_subsystem(); - unregister_shrinker(&erofs_shrinker_info); - erofs_exit_inode_cache(); - infoln("successfully finalize erofs"); -} - -/* get filesystem statistics */ -static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf) -{ - struct super_block *sb = dentry->d_sb; - struct erofs_sb_info *sbi = EROFS_SB(sb); - u64 id = huge_encode_dev(sb->s_bdev->bd_dev); - - buf->f_type = sb->s_magic; - buf->f_bsize = EROFS_BLKSIZ; - buf->f_blocks = sbi->blocks; - buf->f_bfree = buf->f_bavail = 0; - - buf->f_files = ULLONG_MAX; - buf->f_ffree = ULLONG_MAX - sbi->inos; - - buf->f_namelen = EROFS_NAME_LEN; - - buf->f_fsid.val[0] = (u32)id; - buf->f_fsid.val[1] = (u32)(id >> 32); - return 0; -} - -static int erofs_show_options(struct seq_file *seq, struct dentry *root) -{ - struct erofs_sb_info *sbi __maybe_unused = EROFS_SB(root->d_sb); - -#ifdef CONFIG_EROFS_FS_XATTR - if (test_opt(sbi, XATTR_USER)) - seq_puts(seq, ",user_xattr"); - else - seq_puts(seq, ",nouser_xattr"); -#endif -#ifdef CONFIG_EROFS_FS_POSIX_ACL - if (test_opt(sbi, POSIX_ACL)) - seq_puts(seq, ",acl"); - else - seq_puts(seq, ",noacl"); -#endif - if (test_opt(sbi, FAULT_INJECTION)) - seq_printf(seq, ",fault_injection=%u", - erofs_get_fault_rate(sbi)); - return 0; -} - -static int erofs_remount(struct super_block *sb, int *flags, char *data) -{ - struct erofs_sb_info *sbi = EROFS_SB(sb); - unsigned int org_mnt_opt = sbi->mount_opt; - unsigned int org_inject_rate = erofs_get_fault_rate(sbi); - int err; - - DBG_BUGON(!sb_rdonly(sb)); - err = parse_options(sb, data); - if (err) - goto out; - - if (test_opt(sbi, POSIX_ACL)) - sb->s_flags |= SB_POSIXACL; - else - sb->s_flags &= ~SB_POSIXACL; - - *flags |= SB_RDONLY; - return 0; -out: - __erofs_build_fault_attr(sbi, org_inject_rate); - sbi->mount_opt = org_mnt_opt; - - return err; -} - -const struct super_operations erofs_sops = { - .put_super = erofs_put_super, - .alloc_inode = alloc_inode, - .free_inode = free_inode, - .statfs = erofs_statfs, - .show_options = erofs_show_options, - .remount_fs = erofs_remount, -}; - -module_init(erofs_module_init); -module_exit(erofs_module_exit); - -MODULE_DESCRIPTION("Enhanced ROM File System"); -MODULE_AUTHOR("Gao Xiang, Yu Chao, Miao Xie, CONSUMER BG, HUAWEI Inc."); -MODULE_LICENSE("GPL"); - diff --git a/drivers/staging/erofs/unzip_pagevec.h b/drivers/staging/erofs/unzip_pagevec.h deleted file mode 100644 index 7af0ba8d8495..000000000000 --- a/drivers/staging/erofs/unzip_pagevec.h +++ /dev/null @@ -1,169 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * linux/drivers/staging/erofs/unzip_pagevec.h - * - * Copyright (C) 2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#ifndef __EROFS_UNZIP_PAGEVEC_H -#define __EROFS_UNZIP_PAGEVEC_H - -#include <linux/tagptr.h> - -/* page type in pagevec for unzip subsystem */ -enum z_erofs_page_type { - /* including Z_EROFS_VLE_PAGE_TAIL_EXCLUSIVE */ - Z_EROFS_PAGE_TYPE_EXCLUSIVE, - - Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED, - - Z_EROFS_VLE_PAGE_TYPE_HEAD, - Z_EROFS_VLE_PAGE_TYPE_MAX -}; - -extern void __compiletime_error("Z_EROFS_PAGE_TYPE_EXCLUSIVE != 0") - __bad_page_type_exclusive(void); - -/* pagevec tagged pointer */ -typedef tagptr2_t erofs_vtptr_t; - -/* pagevec collector */ -struct z_erofs_pagevec_ctor { - struct page *curr, *next; - erofs_vtptr_t *pages; - - unsigned int nr, index; -}; - -static inline void z_erofs_pagevec_ctor_exit(struct z_erofs_pagevec_ctor *ctor, - bool atomic) -{ - if (!ctor->curr) - return; - - if (atomic) - kunmap_atomic(ctor->pages); - else - kunmap(ctor->curr); -} - -static inline struct page * -z_erofs_pagevec_ctor_next_page(struct z_erofs_pagevec_ctor *ctor, - unsigned nr) -{ - unsigned index; - - /* keep away from occupied pages */ - if (ctor->next) - return ctor->next; - - for (index = 0; index < nr; ++index) { - const erofs_vtptr_t t = ctor->pages[index]; - const unsigned tags = tagptr_unfold_tags(t); - - if (tags == Z_EROFS_PAGE_TYPE_EXCLUSIVE) - return tagptr_unfold_ptr(t); - } - DBG_BUGON(nr >= ctor->nr); - return NULL; -} - -static inline void -z_erofs_pagevec_ctor_pagedown(struct z_erofs_pagevec_ctor *ctor, - bool atomic) -{ - struct page *next = z_erofs_pagevec_ctor_next_page(ctor, ctor->nr); - - z_erofs_pagevec_ctor_exit(ctor, atomic); - - ctor->curr = next; - ctor->next = NULL; - ctor->pages = atomic ? - kmap_atomic(ctor->curr) : kmap(ctor->curr); - - ctor->nr = PAGE_SIZE / sizeof(struct page *); - ctor->index = 0; -} - -static inline void z_erofs_pagevec_ctor_init(struct z_erofs_pagevec_ctor *ctor, - unsigned nr, - erofs_vtptr_t *pages, unsigned i) -{ - ctor->nr = nr; - ctor->curr = ctor->next = NULL; - ctor->pages = pages; - - if (i >= nr) { - i -= nr; - z_erofs_pagevec_ctor_pagedown(ctor, false); - while (i > ctor->nr) { - i -= ctor->nr; - z_erofs_pagevec_ctor_pagedown(ctor, false); - } - } - - ctor->next = z_erofs_pagevec_ctor_next_page(ctor, i); - ctor->index = i; -} - -static inline bool -z_erofs_pagevec_ctor_enqueue(struct z_erofs_pagevec_ctor *ctor, - struct page *page, - enum z_erofs_page_type type, - bool *occupied) -{ - *occupied = false; - if (unlikely(!ctor->next && type)) - if (ctor->index + 1 == ctor->nr) - return false; - - if (unlikely(ctor->index >= ctor->nr)) - z_erofs_pagevec_ctor_pagedown(ctor, false); - - /* exclusive page type must be 0 */ - if (Z_EROFS_PAGE_TYPE_EXCLUSIVE != (uintptr_t)NULL) - __bad_page_type_exclusive(); - - /* should remind that collector->next never equal to 1, 2 */ - if (type == (uintptr_t)ctor->next) { - ctor->next = page; - *occupied = true; - } - - ctor->pages[ctor->index++] = - tagptr_fold(erofs_vtptr_t, page, type); - return true; -} - -static inline struct page * -z_erofs_pagevec_ctor_dequeue(struct z_erofs_pagevec_ctor *ctor, - enum z_erofs_page_type *type) -{ - erofs_vtptr_t t; - - if (unlikely(ctor->index >= ctor->nr)) { - DBG_BUGON(!ctor->next); - z_erofs_pagevec_ctor_pagedown(ctor, true); - } - - t = ctor->pages[ctor->index]; - - *type = tagptr_unfold_tags(t); - - /* should remind that collector->next never equal to 1, 2 */ - if (*type == (uintptr_t)ctor->next) - ctor->next = tagptr_unfold_ptr(t); - - ctor->pages[ctor->index++] = - tagptr_fold(erofs_vtptr_t, NULL, 0); - - return tagptr_unfold_ptr(t); -} - -#endif - diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c deleted file mode 100644 index f0dab81ff816..000000000000 --- a/drivers/staging/erofs/unzip_vle.c +++ /dev/null @@ -1,1591 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/unzip_vle.c - * - * Copyright (C) 2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#include "unzip_vle.h" -#include "compress.h" -#include <linux/prefetch.h> - -#include <trace/events/erofs.h> - -/* - * a compressed_pages[] placeholder in order to avoid - * being filled with file pages for in-place decompression. - */ -#define PAGE_UNALLOCATED ((void *)0x5F0E4B1D) - -/* how to allocate cached pages for a workgroup */ -enum z_erofs_cache_alloctype { - DONTALLOC, /* don't allocate any cached pages */ - DELAYEDALLOC, /* delayed allocation (at the time of submitting io) */ -}; - -/* - * tagged pointer with 1-bit tag for all compressed pages - * tag 0 - the page is just found with an extra page reference - */ -typedef tagptr1_t compressed_page_t; - -#define tag_compressed_page_justfound(page) \ - tagptr_fold(compressed_page_t, page, 1) - -static struct workqueue_struct *z_erofs_workqueue __read_mostly; -static struct kmem_cache *z_erofs_workgroup_cachep __read_mostly; - -void z_erofs_exit_zip_subsystem(void) -{ - destroy_workqueue(z_erofs_workqueue); - kmem_cache_destroy(z_erofs_workgroup_cachep); -} - -static inline int init_unzip_workqueue(void) -{ - const unsigned int onlinecpus = num_possible_cpus(); - - /* - * we don't need too many threads, limiting threads - * could improve scheduling performance. - */ - z_erofs_workqueue = - alloc_workqueue("erofs_unzipd", - WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, - onlinecpus + onlinecpus / 4); - - return z_erofs_workqueue ? 0 : -ENOMEM; -} - -static void init_once(void *ptr) -{ - struct z_erofs_vle_workgroup *grp = ptr; - struct z_erofs_vle_work *const work = - z_erofs_vle_grab_primary_work(grp); - unsigned int i; - - mutex_init(&work->lock); - work->nr_pages = 0; - work->vcnt = 0; - for (i = 0; i < Z_EROFS_CLUSTER_MAX_PAGES; ++i) - grp->compressed_pages[i] = NULL; -} - -static void init_always(struct z_erofs_vle_workgroup *grp) -{ - struct z_erofs_vle_work *const work = - z_erofs_vle_grab_primary_work(grp); - - atomic_set(&grp->obj.refcount, 1); - grp->flags = 0; - - DBG_BUGON(work->nr_pages); - DBG_BUGON(work->vcnt); -} - -int __init z_erofs_init_zip_subsystem(void) -{ - z_erofs_workgroup_cachep = - kmem_cache_create("erofs_compress", - Z_EROFS_WORKGROUP_SIZE, 0, - SLAB_RECLAIM_ACCOUNT, init_once); - - if (z_erofs_workgroup_cachep) { - if (!init_unzip_workqueue()) - return 0; - - kmem_cache_destroy(z_erofs_workgroup_cachep); - } - return -ENOMEM; -} - -enum z_erofs_vle_work_role { - Z_EROFS_VLE_WORK_SECONDARY, - Z_EROFS_VLE_WORK_PRIMARY, - /* - * The current work was the tail of an exist chain, and the previous - * processed chained works are all decided to be hooked up to it. - * A new chain should be created for the remaining unprocessed works, - * therefore different from Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED, - * the next work cannot reuse the whole page in the following scenario: - * ________________________________________________________________ - * | tail (partial) page | head (partial) page | - * | (belongs to the next work) | (belongs to the current work) | - * |_______PRIMARY_FOLLOWED_______|________PRIMARY_HOOKED___________| - */ - Z_EROFS_VLE_WORK_PRIMARY_HOOKED, - /* - * The current work has been linked with the processed chained works, - * and could be also linked with the potential remaining works, which - * means if the processing page is the tail partial page of the work, - * the current work can safely use the whole page (since the next work - * is under control) for in-place decompression, as illustrated below: - * ________________________________________________________________ - * | tail (partial) page | head (partial) page | - * | (of the current work) | (of the previous work) | - * | PRIMARY_FOLLOWED or | | - * |_____PRIMARY_HOOKED____|____________PRIMARY_FOLLOWED____________| - * - * [ (*) the above page can be used for the current work itself. ] - */ - Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED, - Z_EROFS_VLE_WORK_MAX -}; - -struct z_erofs_vle_work_builder { - enum z_erofs_vle_work_role role; - /* - * 'hosted = false' means that the current workgroup doesn't belong to - * the owned chained workgroups. In the other words, it is none of our - * business to submit this workgroup. - */ - bool hosted; - - struct z_erofs_vle_workgroup *grp; - struct z_erofs_vle_work *work; - struct z_erofs_pagevec_ctor vector; - - /* pages used for reading the compressed data */ - struct page **compressed_pages; - unsigned int compressed_deficit; -}; - -#define VLE_WORK_BUILDER_INIT() \ - { .work = NULL, .role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED } - -#ifdef EROFS_FS_HAS_MANAGED_CACHE -static void preload_compressed_pages(struct z_erofs_vle_work_builder *bl, - struct address_space *mc, - pgoff_t index, - unsigned int clusterpages, - enum z_erofs_cache_alloctype type, - struct list_head *pagepool, - gfp_t gfp) -{ - struct page **const pages = bl->compressed_pages; - const unsigned int remaining = bl->compressed_deficit; - bool standalone = true; - unsigned int i, j = 0; - - if (bl->role < Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED) - return; - - gfp = mapping_gfp_constraint(mc, gfp) & ~__GFP_RECLAIM; - - index += clusterpages - remaining; - - for (i = 0; i < remaining; ++i) { - struct page *page; - compressed_page_t t; - - /* the compressed page was loaded before */ - if (READ_ONCE(pages[i])) - continue; - - page = find_get_page(mc, index + i); - - if (page) { - t = tag_compressed_page_justfound(page); - } else if (type == DELAYEDALLOC) { - t = tagptr_init(compressed_page_t, PAGE_UNALLOCATED); - } else { /* DONTALLOC */ - if (standalone) - j = i; - standalone = false; - continue; - } - - if (!cmpxchg_relaxed(&pages[i], NULL, tagptr_cast_ptr(t))) - continue; - - if (page) - put_page(page); - } - bl->compressed_pages += j; - bl->compressed_deficit = remaining - j; - - if (standalone) - bl->role = Z_EROFS_VLE_WORK_PRIMARY; -} - -/* called by erofs_shrinker to get rid of all compressed_pages */ -int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, - struct erofs_workgroup *egrp) -{ - struct z_erofs_vle_workgroup *const grp = - container_of(egrp, struct z_erofs_vle_workgroup, obj); - struct address_space *const mapping = MNGD_MAPPING(sbi); - const int clusterpages = erofs_clusterpages(sbi); - int i; - - /* - * refcount of workgroup is now freezed as 1, - * therefore no need to worry about available decompression users. - */ - for (i = 0; i < clusterpages; ++i) { - struct page *page = grp->compressed_pages[i]; - - if (!page || page->mapping != mapping) - continue; - - /* block other users from reclaiming or migrating the page */ - if (!trylock_page(page)) - return -EBUSY; - - /* barrier is implied in the following 'unlock_page' */ - WRITE_ONCE(grp->compressed_pages[i], NULL); - - set_page_private(page, 0); - ClearPagePrivate(page); - - unlock_page(page); - put_page(page); - } - return 0; -} - -int erofs_try_to_free_cached_page(struct address_space *mapping, - struct page *page) -{ - struct erofs_sb_info *const sbi = EROFS_SB(mapping->host->i_sb); - const unsigned int clusterpages = erofs_clusterpages(sbi); - struct z_erofs_vle_workgroup *const grp = (void *)page_private(page); - int ret = 0; /* 0 - busy */ - - if (erofs_workgroup_try_to_freeze(&grp->obj, 1)) { - unsigned int i; - - for (i = 0; i < clusterpages; ++i) { - if (grp->compressed_pages[i] == page) { - WRITE_ONCE(grp->compressed_pages[i], NULL); - ret = 1; - break; - } - } - erofs_workgroup_unfreeze(&grp->obj, 1); - - if (ret) { - ClearPagePrivate(page); - put_page(page); - } - } - return ret; -} -#else -static void preload_compressed_pages(struct z_erofs_vle_work_builder *bl, - struct address_space *mc, - pgoff_t index, - unsigned int clusterpages, - enum z_erofs_cache_alloctype type, - struct list_head *pagepool, - gfp_t gfp) -{ - /* nowhere to load compressed pages from */ -} -#endif - -/* page_type must be Z_EROFS_PAGE_TYPE_EXCLUSIVE */ -static inline bool try_to_reuse_as_compressed_page( - struct z_erofs_vle_work_builder *b, - struct page *page) -{ - while (b->compressed_deficit) { - --b->compressed_deficit; - if (!cmpxchg(b->compressed_pages++, NULL, page)) - return true; - } - - return false; -} - -/* callers must be with work->lock held */ -static int z_erofs_vle_work_add_page( - struct z_erofs_vle_work_builder *builder, - struct page *page, - enum z_erofs_page_type type) -{ - int ret; - bool occupied; - - /* give priority for the compressed data storage */ - if (builder->role >= Z_EROFS_VLE_WORK_PRIMARY && - type == Z_EROFS_PAGE_TYPE_EXCLUSIVE && - try_to_reuse_as_compressed_page(builder, page)) - return 0; - - ret = z_erofs_pagevec_ctor_enqueue(&builder->vector, - page, type, &occupied); - builder->work->vcnt += (unsigned int)ret; - - return ret ? 0 : -EAGAIN; -} - -static enum z_erofs_vle_work_role -try_to_claim_workgroup(struct z_erofs_vle_workgroup *grp, - z_erofs_vle_owned_workgrp_t *owned_head, - bool *hosted) -{ - DBG_BUGON(*hosted); - - /* let's claim these following types of workgroup */ -retry: - if (grp->next == Z_EROFS_VLE_WORKGRP_NIL) { - /* type 1, nil workgroup */ - if (cmpxchg(&grp->next, Z_EROFS_VLE_WORKGRP_NIL, - *owned_head) != Z_EROFS_VLE_WORKGRP_NIL) - goto retry; - - *owned_head = &grp->next; - *hosted = true; - /* lucky, I am the followee :) */ - return Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED; - - } else if (grp->next == Z_EROFS_VLE_WORKGRP_TAIL) { - /* - * type 2, link to the end of a existing open chain, - * be careful that its submission itself is governed - * by the original owned chain. - */ - if (cmpxchg(&grp->next, Z_EROFS_VLE_WORKGRP_TAIL, - *owned_head) != Z_EROFS_VLE_WORKGRP_TAIL) - goto retry; - *owned_head = Z_EROFS_VLE_WORKGRP_TAIL; - return Z_EROFS_VLE_WORK_PRIMARY_HOOKED; - } - - return Z_EROFS_VLE_WORK_PRIMARY; /* :( better luck next time */ -} - -struct z_erofs_vle_work_finder { - struct super_block *sb; - pgoff_t idx; - unsigned int pageofs; - - struct z_erofs_vle_workgroup **grp_ret; - enum z_erofs_vle_work_role *role; - z_erofs_vle_owned_workgrp_t *owned_head; - bool *hosted; -}; - -static struct z_erofs_vle_work * -z_erofs_vle_work_lookup(const struct z_erofs_vle_work_finder *f) -{ - bool tag, primary; - struct erofs_workgroup *egrp; - struct z_erofs_vle_workgroup *grp; - struct z_erofs_vle_work *work; - - egrp = erofs_find_workgroup(f->sb, f->idx, &tag); - if (!egrp) { - *f->grp_ret = NULL; - return NULL; - } - - grp = container_of(egrp, struct z_erofs_vle_workgroup, obj); - *f->grp_ret = grp; - - work = z_erofs_vle_grab_work(grp, f->pageofs); - /* if multiref is disabled, `primary' is always true */ - primary = true; - - DBG_BUGON(work->pageofs != f->pageofs); - - /* - * lock must be taken first to avoid grp->next == NIL between - * claiming workgroup and adding pages: - * grp->next != NIL - * grp->next = NIL - * mutex_unlock_all - * mutex_lock(&work->lock) - * add all pages to pagevec - * - * [correct locking case 1]: - * mutex_lock(grp->work[a]) - * ... - * mutex_lock(grp->work[b]) mutex_lock(grp->work[c]) - * ... *role = SECONDARY - * add all pages to pagevec - * ... - * mutex_unlock(grp->work[c]) - * mutex_lock(grp->work[c]) - * ... - * grp->next = NIL - * mutex_unlock_all - * - * [correct locking case 2]: - * mutex_lock(grp->work[b]) - * ... - * mutex_lock(grp->work[a]) - * ... - * mutex_lock(grp->work[c]) - * ... - * grp->next = NIL - * mutex_unlock_all - * mutex_lock(grp->work[a]) - * *role = PRIMARY_OWNER - * add all pages to pagevec - * ... - */ - mutex_lock(&work->lock); - - *f->hosted = false; - if (!primary) - *f->role = Z_EROFS_VLE_WORK_SECONDARY; - else /* claim the workgroup if possible */ - *f->role = try_to_claim_workgroup(grp, f->owned_head, - f->hosted); - return work; -} - -static struct z_erofs_vle_work * -z_erofs_vle_work_register(const struct z_erofs_vle_work_finder *f, - struct erofs_map_blocks *map) -{ - bool gnew = false; - struct z_erofs_vle_workgroup *grp = *f->grp_ret; - struct z_erofs_vle_work *work; - - /* if multiref is disabled, grp should never be nullptr */ - if (unlikely(grp)) { - DBG_BUGON(1); - return ERR_PTR(-EINVAL); - } - - /* no available workgroup, let's allocate one */ - grp = kmem_cache_alloc(z_erofs_workgroup_cachep, GFP_NOFS); - if (unlikely(!grp)) - return ERR_PTR(-ENOMEM); - - init_always(grp); - grp->obj.index = f->idx; - grp->llen = map->m_llen; - - z_erofs_vle_set_workgrp_fmt(grp, (map->m_flags & EROFS_MAP_ZIPPED) ? - Z_EROFS_VLE_WORKGRP_FMT_LZ4 : - Z_EROFS_VLE_WORKGRP_FMT_PLAIN); - - if (map->m_flags & EROFS_MAP_FULL_MAPPED) - grp->flags |= Z_EROFS_VLE_WORKGRP_FULL_LENGTH; - - /* new workgrps have been claimed as type 1 */ - WRITE_ONCE(grp->next, *f->owned_head); - /* primary and followed work for all new workgrps */ - *f->role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED; - /* it should be submitted by ourselves */ - *f->hosted = true; - - gnew = true; - work = z_erofs_vle_grab_primary_work(grp); - work->pageofs = f->pageofs; - - /* - * lock all primary followed works before visible to others - * and mutex_trylock *never* fails for a new workgroup. - */ - mutex_trylock(&work->lock); - - if (gnew) { - int err = erofs_register_workgroup(f->sb, &grp->obj, 0); - - if (err) { - mutex_unlock(&work->lock); - kmem_cache_free(z_erofs_workgroup_cachep, grp); - return ERR_PTR(-EAGAIN); - } - } - - *f->owned_head = &grp->next; - *f->grp_ret = grp; - return work; -} - -#define builder_is_hooked(builder) \ - ((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_HOOKED) - -#define builder_is_followed(builder) \ - ((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED) - -static int z_erofs_vle_work_iter_begin(struct z_erofs_vle_work_builder *builder, - struct super_block *sb, - struct erofs_map_blocks *map, - z_erofs_vle_owned_workgrp_t *owned_head) -{ - const unsigned int clusterpages = erofs_clusterpages(EROFS_SB(sb)); - struct z_erofs_vle_workgroup *grp; - const struct z_erofs_vle_work_finder finder = { - .sb = sb, - .idx = erofs_blknr(map->m_pa), - .pageofs = map->m_la & ~PAGE_MASK, - .grp_ret = &grp, - .role = &builder->role, - .owned_head = owned_head, - .hosted = &builder->hosted - }; - struct z_erofs_vle_work *work; - - DBG_BUGON(builder->work); - - /* must be Z_EROFS_WORK_TAIL or the next chained work */ - DBG_BUGON(*owned_head == Z_EROFS_VLE_WORKGRP_NIL); - DBG_BUGON(*owned_head == Z_EROFS_VLE_WORKGRP_TAIL_CLOSED); - - DBG_BUGON(erofs_blkoff(map->m_pa)); - -repeat: - work = z_erofs_vle_work_lookup(&finder); - if (work) { - unsigned int orig_llen; - - /* increase workgroup `llen' if needed */ - while ((orig_llen = READ_ONCE(grp->llen)) < map->m_llen && - orig_llen != cmpxchg_relaxed(&grp->llen, - orig_llen, map->m_llen)) - cpu_relax(); - goto got_it; - } - - work = z_erofs_vle_work_register(&finder, map); - if (unlikely(work == ERR_PTR(-EAGAIN))) - goto repeat; - - if (IS_ERR(work)) - return PTR_ERR(work); -got_it: - z_erofs_pagevec_ctor_init(&builder->vector, Z_EROFS_NR_INLINE_PAGEVECS, - work->pagevec, work->vcnt); - - if (builder->role >= Z_EROFS_VLE_WORK_PRIMARY) { - /* enable possibly in-place decompression */ - builder->compressed_pages = grp->compressed_pages; - builder->compressed_deficit = clusterpages; - } else { - builder->compressed_pages = NULL; - builder->compressed_deficit = 0; - } - - builder->grp = grp; - builder->work = work; - return 0; -} - -/* - * keep in mind that no referenced workgroups will be freed - * only after a RCU grace period, so rcu_read_lock() could - * prevent a workgroup from being freed. - */ -static void z_erofs_rcu_callback(struct rcu_head *head) -{ - struct z_erofs_vle_work *work = container_of(head, - struct z_erofs_vle_work, rcu); - struct z_erofs_vle_workgroup *grp = - z_erofs_vle_work_workgroup(work, true); - - kmem_cache_free(z_erofs_workgroup_cachep, grp); -} - -void erofs_workgroup_free_rcu(struct erofs_workgroup *grp) -{ - struct z_erofs_vle_workgroup *const vgrp = container_of(grp, - struct z_erofs_vle_workgroup, obj); - struct z_erofs_vle_work *const work = &vgrp->work; - - call_rcu(&work->rcu, z_erofs_rcu_callback); -} - -static void -__z_erofs_vle_work_release(struct z_erofs_vle_workgroup *grp, - struct z_erofs_vle_work *work __maybe_unused) -{ - erofs_workgroup_put(&grp->obj); -} - -static void z_erofs_vle_work_release(struct z_erofs_vle_work *work) -{ - struct z_erofs_vle_workgroup *grp = - z_erofs_vle_work_workgroup(work, true); - - __z_erofs_vle_work_release(grp, work); -} - -static inline bool -z_erofs_vle_work_iter_end(struct z_erofs_vle_work_builder *builder) -{ - struct z_erofs_vle_work *work = builder->work; - - if (!work) - return false; - - z_erofs_pagevec_ctor_exit(&builder->vector, false); - mutex_unlock(&work->lock); - - /* - * if all pending pages are added, don't hold work reference - * any longer if the current work isn't hosted by ourselves. - */ - if (!builder->hosted) - __z_erofs_vle_work_release(builder->grp, work); - - builder->work = NULL; - builder->grp = NULL; - return true; -} - -static inline struct page *__stagingpage_alloc(struct list_head *pagepool, - gfp_t gfp) -{ - struct page *page = erofs_allocpage(pagepool, gfp); - - if (unlikely(!page)) - return NULL; - - page->mapping = Z_EROFS_MAPPING_STAGING; - return page; -} - -struct z_erofs_vle_frontend { - struct inode *const inode; - - struct z_erofs_vle_work_builder builder; - struct erofs_map_blocks map; - - z_erofs_vle_owned_workgrp_t owned_head; - - /* used for applying cache strategy on the fly */ - bool backmost; - erofs_off_t headoffset; -}; - -#define VLE_FRONTEND_INIT(__i) { \ - .inode = __i, \ - .map = { \ - .m_llen = 0, \ - .m_plen = 0, \ - .mpage = NULL \ - }, \ - .builder = VLE_WORK_BUILDER_INIT(), \ - .owned_head = Z_EROFS_VLE_WORKGRP_TAIL, \ - .backmost = true, } - -#ifdef EROFS_FS_HAS_MANAGED_CACHE -static inline bool -should_alloc_managed_pages(struct z_erofs_vle_frontend *fe, erofs_off_t la) -{ - if (fe->backmost) - return true; - - if (EROFS_FS_ZIP_CACHE_LVL >= 2) - return la < fe->headoffset; - - return false; -} -#else -static inline bool -should_alloc_managed_pages(struct z_erofs_vle_frontend *fe, erofs_off_t la) -{ - return false; -} -#endif - -static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, - struct page *page, - struct list_head *page_pool) -{ - struct super_block *const sb = fe->inode->i_sb; - struct erofs_sb_info *const sbi __maybe_unused = EROFS_SB(sb); - struct erofs_map_blocks *const map = &fe->map; - struct z_erofs_vle_work_builder *const builder = &fe->builder; - const loff_t offset = page_offset(page); - - bool tight = builder_is_hooked(builder); - struct z_erofs_vle_work *work = builder->work; - - enum z_erofs_cache_alloctype cache_strategy; - enum z_erofs_page_type page_type; - unsigned int cur, end, spiltted, index; - int err = 0; - - /* register locked file pages as online pages in pack */ - z_erofs_onlinepage_init(page); - - spiltted = 0; - end = PAGE_SIZE; -repeat: - cur = end - 1; - - /* lucky, within the range of the current map_blocks */ - if (offset + cur >= map->m_la && - offset + cur < map->m_la + map->m_llen) { - /* didn't get a valid unzip work previously (very rare) */ - if (!builder->work) - goto restart_now; - goto hitted; - } - - /* go ahead the next map_blocks */ - debugln("%s: [out-of-range] pos %llu", __func__, offset + cur); - - if (z_erofs_vle_work_iter_end(builder)) - fe->backmost = false; - - map->m_la = offset + cur; - map->m_llen = 0; - err = z_erofs_map_blocks_iter(fe->inode, map, 0); - if (unlikely(err)) - goto err_out; - -restart_now: - if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED))) - goto hitted; - - DBG_BUGON(map->m_plen != 1 << sbi->clusterbits); - DBG_BUGON(erofs_blkoff(map->m_pa)); - - err = z_erofs_vle_work_iter_begin(builder, sb, map, &fe->owned_head); - if (unlikely(err)) - goto err_out; - - /* preload all compressed pages (maybe downgrade role if necessary) */ - if (should_alloc_managed_pages(fe, map->m_la)) - cache_strategy = DELAYEDALLOC; - else - cache_strategy = DONTALLOC; - - preload_compressed_pages(builder, MNGD_MAPPING(sbi), - map->m_pa / PAGE_SIZE, - map->m_plen / PAGE_SIZE, - cache_strategy, page_pool, GFP_KERNEL); - - tight &= builder_is_hooked(builder); - work = builder->work; -hitted: - cur = end - min_t(unsigned int, offset + end - map->m_la, end); - if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED))) { - zero_user_segment(page, cur, end); - goto next_part; - } - - /* let's derive page type */ - page_type = cur ? Z_EROFS_VLE_PAGE_TYPE_HEAD : - (!spiltted ? Z_EROFS_PAGE_TYPE_EXCLUSIVE : - (tight ? Z_EROFS_PAGE_TYPE_EXCLUSIVE : - Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED)); - - if (cur) - tight &= builder_is_followed(builder); - -retry: - err = z_erofs_vle_work_add_page(builder, page, page_type); - /* should allocate an additional staging page for pagevec */ - if (err == -EAGAIN) { - struct page *const newpage = - __stagingpage_alloc(page_pool, GFP_NOFS); - - err = z_erofs_vle_work_add_page(builder, newpage, - Z_EROFS_PAGE_TYPE_EXCLUSIVE); - if (likely(!err)) - goto retry; - } - - if (unlikely(err)) - goto err_out; - - index = page->index - map->m_la / PAGE_SIZE; - - /* FIXME! avoid the last relundant fixup & endio */ - z_erofs_onlinepage_fixup(page, index, true); - - /* bump up the number of spiltted parts of a page */ - ++spiltted; - /* also update nr_pages */ - work->nr_pages = max_t(pgoff_t, work->nr_pages, index + 1); -next_part: - /* can be used for verification */ - map->m_llen = offset + cur - map->m_la; - - end = cur; - if (end > 0) - goto repeat; - -out: - /* FIXME! avoid the last relundant fixup & endio */ - z_erofs_onlinepage_endio(page); - - debugln("%s, finish page: %pK spiltted: %u map->m_llen %llu", - __func__, page, spiltted, map->m_llen); - return err; - - /* if some error occurred while processing this page */ -err_out: - SetPageError(page); - goto out; -} - -static void z_erofs_vle_unzip_kickoff(void *ptr, int bios) -{ - tagptr1_t t = tagptr_init(tagptr1_t, ptr); - struct z_erofs_vle_unzip_io *io = tagptr_unfold_ptr(t); - bool background = tagptr_unfold_tags(t); - - if (!background) { - unsigned long flags; - - spin_lock_irqsave(&io->u.wait.lock, flags); - if (!atomic_add_return(bios, &io->pending_bios)) - wake_up_locked(&io->u.wait); - spin_unlock_irqrestore(&io->u.wait.lock, flags); - return; - } - - if (!atomic_add_return(bios, &io->pending_bios)) - queue_work(z_erofs_workqueue, &io->u.work); -} - -static inline void z_erofs_vle_read_endio(struct bio *bio) -{ - struct erofs_sb_info *sbi = NULL; - blk_status_t err = bio->bi_status; - struct bio_vec *bvec; - struct bvec_iter_all iter_all; - - bio_for_each_segment_all(bvec, bio, iter_all) { - struct page *page = bvec->bv_page; - bool cachemngd = false; - - DBG_BUGON(PageUptodate(page)); - DBG_BUGON(!page->mapping); - - if (unlikely(!sbi && !z_erofs_page_is_staging(page))) { - sbi = EROFS_SB(page->mapping->host->i_sb); - - if (time_to_inject(sbi, FAULT_READ_IO)) { - erofs_show_injection_info(FAULT_READ_IO); - err = BLK_STS_IOERR; - } - } - - /* sbi should already be gotten if the page is managed */ - if (sbi) - cachemngd = erofs_page_is_managed(sbi, page); - - if (unlikely(err)) - SetPageError(page); - else if (cachemngd) - SetPageUptodate(page); - - if (cachemngd) - unlock_page(page); - } - - z_erofs_vle_unzip_kickoff(bio->bi_private, -1); - bio_put(bio); -} - -static struct page *z_pagemap_global[Z_EROFS_VLE_VMAP_GLOBAL_PAGES]; -static DEFINE_MUTEX(z_pagemap_global_lock); - -static int z_erofs_vle_unzip(struct super_block *sb, - struct z_erofs_vle_workgroup *grp, - struct list_head *page_pool) -{ - struct erofs_sb_info *const sbi = EROFS_SB(sb); - const unsigned int clusterpages = erofs_clusterpages(sbi); - - struct z_erofs_pagevec_ctor ctor; - unsigned int nr_pages; - unsigned int sparsemem_pages = 0; - struct page *pages_onstack[Z_EROFS_VLE_VMAP_ONSTACK_PAGES]; - struct page **pages, **compressed_pages, *page; - unsigned int algorithm; - unsigned int i, outputsize; - - enum z_erofs_page_type page_type; - bool overlapped, partial; - struct z_erofs_vle_work *work; - int err; - - might_sleep(); - work = z_erofs_vle_grab_primary_work(grp); - DBG_BUGON(!READ_ONCE(work->nr_pages)); - - mutex_lock(&work->lock); - nr_pages = work->nr_pages; - - if (likely(nr_pages <= Z_EROFS_VLE_VMAP_ONSTACK_PAGES)) - pages = pages_onstack; - else if (nr_pages <= Z_EROFS_VLE_VMAP_GLOBAL_PAGES && - mutex_trylock(&z_pagemap_global_lock)) - pages = z_pagemap_global; - else { -repeat: - pages = kvmalloc_array(nr_pages, sizeof(struct page *), - GFP_KERNEL); - - /* fallback to global pagemap for the lowmem scenario */ - if (unlikely(!pages)) { - if (nr_pages > Z_EROFS_VLE_VMAP_GLOBAL_PAGES) - goto repeat; - else { - mutex_lock(&z_pagemap_global_lock); - pages = z_pagemap_global; - } - } - } - - for (i = 0; i < nr_pages; ++i) - pages[i] = NULL; - - z_erofs_pagevec_ctor_init(&ctor, Z_EROFS_NR_INLINE_PAGEVECS, - work->pagevec, 0); - - for (i = 0; i < work->vcnt; ++i) { - unsigned int pagenr; - - page = z_erofs_pagevec_ctor_dequeue(&ctor, &page_type); - - /* all pages in pagevec ought to be valid */ - DBG_BUGON(!page); - DBG_BUGON(!page->mapping); - - if (z_erofs_put_stagingpage(page_pool, page)) - continue; - - if (page_type == Z_EROFS_VLE_PAGE_TYPE_HEAD) - pagenr = 0; - else - pagenr = z_erofs_onlinepage_index(page); - - DBG_BUGON(pagenr >= nr_pages); - DBG_BUGON(pages[pagenr]); - - pages[pagenr] = page; - } - sparsemem_pages = i; - - z_erofs_pagevec_ctor_exit(&ctor, true); - - overlapped = false; - compressed_pages = grp->compressed_pages; - - err = 0; - for (i = 0; i < clusterpages; ++i) { - unsigned int pagenr; - - page = compressed_pages[i]; - - /* all compressed pages ought to be valid */ - DBG_BUGON(!page); - DBG_BUGON(!page->mapping); - - if (!z_erofs_page_is_staging(page)) { - if (erofs_page_is_managed(sbi, page)) { - if (unlikely(!PageUptodate(page))) - err = -EIO; - continue; - } - - /* - * only if non-head page can be selected - * for inplace decompression - */ - pagenr = z_erofs_onlinepage_index(page); - - DBG_BUGON(pagenr >= nr_pages); - DBG_BUGON(pages[pagenr]); - ++sparsemem_pages; - pages[pagenr] = page; - - overlapped = true; - } - - /* PG_error needs checking for inplaced and staging pages */ - if (unlikely(PageError(page))) { - DBG_BUGON(PageUptodate(page)); - err = -EIO; - } - } - - if (unlikely(err)) - goto out; - - if (nr_pages << PAGE_SHIFT >= work->pageofs + grp->llen) { - outputsize = grp->llen; - partial = !(grp->flags & Z_EROFS_VLE_WORKGRP_FULL_LENGTH); - } else { - outputsize = (nr_pages << PAGE_SHIFT) - work->pageofs; - partial = true; - } - - if (z_erofs_vle_workgrp_fmt(grp) == Z_EROFS_VLE_WORKGRP_FMT_PLAIN) - algorithm = Z_EROFS_COMPRESSION_SHIFTED; - else - algorithm = Z_EROFS_COMPRESSION_LZ4; - - err = z_erofs_decompress(&(struct z_erofs_decompress_req) { - .sb = sb, - .in = compressed_pages, - .out = pages, - .pageofs_out = work->pageofs, - .inputsize = PAGE_SIZE, - .outputsize = outputsize, - .alg = algorithm, - .inplace_io = overlapped, - .partial_decoding = partial - }, page_pool); - -out: - /* must handle all compressed pages before endding pages */ - for (i = 0; i < clusterpages; ++i) { - page = compressed_pages[i]; - - if (erofs_page_is_managed(sbi, page)) - continue; - - /* recycle all individual staging pages */ - (void)z_erofs_put_stagingpage(page_pool, page); - - WRITE_ONCE(compressed_pages[i], NULL); - } - - for (i = 0; i < nr_pages; ++i) { - page = pages[i]; - if (!page) - continue; - - DBG_BUGON(!page->mapping); - - /* recycle all individual staging pages */ - if (z_erofs_put_stagingpage(page_pool, page)) - continue; - - if (unlikely(err < 0)) - SetPageError(page); - - z_erofs_onlinepage_endio(page); - } - - if (pages == z_pagemap_global) - mutex_unlock(&z_pagemap_global_lock); - else if (unlikely(pages != pages_onstack)) - kvfree(pages); - - work->nr_pages = 0; - work->vcnt = 0; - - /* all work locks MUST be taken before the following line */ - - WRITE_ONCE(grp->next, Z_EROFS_VLE_WORKGRP_NIL); - - /* all work locks SHOULD be released right now */ - mutex_unlock(&work->lock); - - z_erofs_vle_work_release(work); - return err; -} - -static void z_erofs_vle_unzip_all(struct super_block *sb, - struct z_erofs_vle_unzip_io *io, - struct list_head *page_pool) -{ - z_erofs_vle_owned_workgrp_t owned = io->head; - - while (owned != Z_EROFS_VLE_WORKGRP_TAIL_CLOSED) { - struct z_erofs_vle_workgroup *grp; - - /* no possible that 'owned' equals Z_EROFS_WORK_TPTR_TAIL */ - DBG_BUGON(owned == Z_EROFS_VLE_WORKGRP_TAIL); - - /* no possible that 'owned' equals NULL */ - DBG_BUGON(owned == Z_EROFS_VLE_WORKGRP_NIL); - - grp = container_of(owned, struct z_erofs_vle_workgroup, next); - owned = READ_ONCE(grp->next); - - z_erofs_vle_unzip(sb, grp, page_pool); - } -} - -static void z_erofs_vle_unzip_wq(struct work_struct *work) -{ - struct z_erofs_vle_unzip_io_sb *iosb = container_of(work, - struct z_erofs_vle_unzip_io_sb, io.u.work); - LIST_HEAD(page_pool); - - DBG_BUGON(iosb->io.head == Z_EROFS_VLE_WORKGRP_TAIL_CLOSED); - z_erofs_vle_unzip_all(iosb->sb, &iosb->io, &page_pool); - - put_pages_list(&page_pool); - kvfree(iosb); -} - -static struct page * -pickup_page_for_submission(struct z_erofs_vle_workgroup *grp, - unsigned int nr, - struct list_head *pagepool, - struct address_space *mc, - gfp_t gfp) -{ - /* determined at compile time to avoid too many #ifdefs */ - const bool nocache = __builtin_constant_p(mc) ? !mc : false; - const pgoff_t index = grp->obj.index; - bool tocache = false; - - struct address_space *mapping; - struct page *oldpage, *page; - - compressed_page_t t; - int justfound; - -repeat: - page = READ_ONCE(grp->compressed_pages[nr]); - oldpage = page; - - if (!page) - goto out_allocpage; - - /* - * the cached page has not been allocated and - * an placeholder is out there, prepare it now. - */ - if (!nocache && page == PAGE_UNALLOCATED) { - tocache = true; - goto out_allocpage; - } - - /* process the target tagged pointer */ - t = tagptr_init(compressed_page_t, page); - justfound = tagptr_unfold_tags(t); - page = tagptr_unfold_ptr(t); - - mapping = READ_ONCE(page->mapping); - - /* - * if managed cache is disabled, it's no way to - * get such a cached-like page. - */ - if (nocache) { - /* if managed cache is disabled, it is impossible `justfound' */ - DBG_BUGON(justfound); - - /* and it should be locked, not uptodate, and not truncated */ - DBG_BUGON(!PageLocked(page)); - DBG_BUGON(PageUptodate(page)); - DBG_BUGON(!mapping); - goto out; - } - - /* - * unmanaged (file) pages are all locked solidly, - * therefore it is impossible for `mapping' to be NULL. - */ - if (mapping && mapping != mc) - /* ought to be unmanaged pages */ - goto out; - - lock_page(page); - - /* only true if page reclaim goes wrong, should never happen */ - DBG_BUGON(justfound && PagePrivate(page)); - - /* the page is still in manage cache */ - if (page->mapping == mc) { - WRITE_ONCE(grp->compressed_pages[nr], page); - - ClearPageError(page); - if (!PagePrivate(page)) { - /* - * impossible to be !PagePrivate(page) for - * the current restriction as well if - * the page is already in compressed_pages[]. - */ - DBG_BUGON(!justfound); - - justfound = 0; - set_page_private(page, (unsigned long)grp); - SetPagePrivate(page); - } - - /* no need to submit io if it is already up-to-date */ - if (PageUptodate(page)) { - unlock_page(page); - page = NULL; - } - goto out; - } - - /* - * the managed page has been truncated, it's unsafe to - * reuse this one, let's allocate a new cache-managed page. - */ - DBG_BUGON(page->mapping); - DBG_BUGON(!justfound); - - tocache = true; - unlock_page(page); - put_page(page); -out_allocpage: - page = __stagingpage_alloc(pagepool, gfp); - if (oldpage != cmpxchg(&grp->compressed_pages[nr], oldpage, page)) { - list_add(&page->lru, pagepool); - cpu_relax(); - goto repeat; - } - if (nocache || !tocache) - goto out; - if (add_to_page_cache_lru(page, mc, index + nr, gfp)) { - page->mapping = Z_EROFS_MAPPING_STAGING; - goto out; - } - - set_page_private(page, (unsigned long)grp); - SetPagePrivate(page); -out: /* the only exit (for tracing and debugging) */ - return page; -} - -static struct z_erofs_vle_unzip_io * -jobqueue_init(struct super_block *sb, - struct z_erofs_vle_unzip_io *io, - bool foreground) -{ - struct z_erofs_vle_unzip_io_sb *iosb; - - if (foreground) { - /* waitqueue available for foreground io */ - DBG_BUGON(!io); - - init_waitqueue_head(&io->u.wait); - atomic_set(&io->pending_bios, 0); - goto out; - } - - iosb = kvzalloc(sizeof(*iosb), GFP_KERNEL | __GFP_NOFAIL); - DBG_BUGON(!iosb); - - /* initialize fields in the allocated descriptor */ - io = &iosb->io; - iosb->sb = sb; - INIT_WORK(&io->u.work, z_erofs_vle_unzip_wq); -out: - io->head = Z_EROFS_VLE_WORKGRP_TAIL_CLOSED; - return io; -} - -/* define workgroup jobqueue types */ -enum { -#ifdef EROFS_FS_HAS_MANAGED_CACHE - JQ_BYPASS, -#endif - JQ_SUBMIT, - NR_JOBQUEUES, -}; - -static void *jobqueueset_init(struct super_block *sb, - z_erofs_vle_owned_workgrp_t qtail[], - struct z_erofs_vle_unzip_io *q[], - struct z_erofs_vle_unzip_io *fgq, - bool forcefg) -{ -#ifdef EROFS_FS_HAS_MANAGED_CACHE - /* - * if managed cache is enabled, bypass jobqueue is needed, - * no need to read from device for all workgroups in this queue. - */ - q[JQ_BYPASS] = jobqueue_init(sb, fgq + JQ_BYPASS, true); - qtail[JQ_BYPASS] = &q[JQ_BYPASS]->head; -#endif - - q[JQ_SUBMIT] = jobqueue_init(sb, fgq + JQ_SUBMIT, forcefg); - qtail[JQ_SUBMIT] = &q[JQ_SUBMIT]->head; - - return tagptr_cast_ptr(tagptr_fold(tagptr1_t, q[JQ_SUBMIT], !forcefg)); -} - -#ifdef EROFS_FS_HAS_MANAGED_CACHE -static void move_to_bypass_jobqueue(struct z_erofs_vle_workgroup *grp, - z_erofs_vle_owned_workgrp_t qtail[], - z_erofs_vle_owned_workgrp_t owned_head) -{ - z_erofs_vle_owned_workgrp_t *const submit_qtail = qtail[JQ_SUBMIT]; - z_erofs_vle_owned_workgrp_t *const bypass_qtail = qtail[JQ_BYPASS]; - - DBG_BUGON(owned_head == Z_EROFS_VLE_WORKGRP_TAIL_CLOSED); - if (owned_head == Z_EROFS_VLE_WORKGRP_TAIL) - owned_head = Z_EROFS_VLE_WORKGRP_TAIL_CLOSED; - - WRITE_ONCE(grp->next, Z_EROFS_VLE_WORKGRP_TAIL_CLOSED); - - WRITE_ONCE(*submit_qtail, owned_head); - WRITE_ONCE(*bypass_qtail, &grp->next); - - qtail[JQ_BYPASS] = &grp->next; -} - -static bool postsubmit_is_all_bypassed(struct z_erofs_vle_unzip_io *q[], - unsigned int nr_bios, - bool force_fg) -{ - /* - * although background is preferred, no one is pending for submission. - * don't issue workqueue for decompression but drop it directly instead. - */ - if (force_fg || nr_bios) - return false; - - kvfree(container_of(q[JQ_SUBMIT], - struct z_erofs_vle_unzip_io_sb, - io)); - return true; -} -#else -static void move_to_bypass_jobqueue(struct z_erofs_vle_workgroup *grp, - z_erofs_vle_owned_workgrp_t qtail[], - z_erofs_vle_owned_workgrp_t owned_head) -{ - /* impossible to bypass submission for managed cache disabled */ - DBG_BUGON(1); -} - -static bool postsubmit_is_all_bypassed(struct z_erofs_vle_unzip_io *q[], - unsigned int nr_bios, - bool force_fg) -{ - /* bios should be >0 if managed cache is disabled */ - DBG_BUGON(!nr_bios); - return false; -} -#endif - -static bool z_erofs_vle_submit_all(struct super_block *sb, - z_erofs_vle_owned_workgrp_t owned_head, - struct list_head *pagepool, - struct z_erofs_vle_unzip_io *fgq, - bool force_fg) -{ - struct erofs_sb_info *const sbi = EROFS_SB(sb); - const unsigned int clusterpages = erofs_clusterpages(sbi); - const gfp_t gfp = GFP_NOFS; - - z_erofs_vle_owned_workgrp_t qtail[NR_JOBQUEUES]; - struct z_erofs_vle_unzip_io *q[NR_JOBQUEUES]; - struct bio *bio; - void *bi_private; - /* since bio will be NULL, no need to initialize last_index */ - pgoff_t uninitialized_var(last_index); - bool force_submit = false; - unsigned int nr_bios; - - if (unlikely(owned_head == Z_EROFS_VLE_WORKGRP_TAIL)) - return false; - - force_submit = false; - bio = NULL; - nr_bios = 0; - bi_private = jobqueueset_init(sb, qtail, q, fgq, force_fg); - - /* by default, all need io submission */ - q[JQ_SUBMIT]->head = owned_head; - - do { - struct z_erofs_vle_workgroup *grp; - pgoff_t first_index; - struct page *page; - unsigned int i = 0, bypass = 0; - int err; - - /* no possible 'owned_head' equals the following */ - DBG_BUGON(owned_head == Z_EROFS_VLE_WORKGRP_TAIL_CLOSED); - DBG_BUGON(owned_head == Z_EROFS_VLE_WORKGRP_NIL); - - grp = container_of(owned_head, - struct z_erofs_vle_workgroup, next); - - /* close the main owned chain at first */ - owned_head = cmpxchg(&grp->next, Z_EROFS_VLE_WORKGRP_TAIL, - Z_EROFS_VLE_WORKGRP_TAIL_CLOSED); - - first_index = grp->obj.index; - force_submit |= (first_index != last_index + 1); - -repeat: - page = pickup_page_for_submission(grp, i, pagepool, - MNGD_MAPPING(sbi), gfp); - if (!page) { - force_submit = true; - ++bypass; - goto skippage; - } - - if (bio && force_submit) { -submit_bio_retry: - __submit_bio(bio, REQ_OP_READ, 0); - bio = NULL; - } - - if (!bio) { - bio = erofs_grab_bio(sb, first_index + i, - BIO_MAX_PAGES, bi_private, - z_erofs_vle_read_endio, true); - ++nr_bios; - } - - err = bio_add_page(bio, page, PAGE_SIZE, 0); - if (err < PAGE_SIZE) - goto submit_bio_retry; - - force_submit = false; - last_index = first_index + i; -skippage: - if (++i < clusterpages) - goto repeat; - - if (bypass < clusterpages) - qtail[JQ_SUBMIT] = &grp->next; - else - move_to_bypass_jobqueue(grp, qtail, owned_head); - } while (owned_head != Z_EROFS_VLE_WORKGRP_TAIL); - - if (bio) - __submit_bio(bio, REQ_OP_READ, 0); - - if (postsubmit_is_all_bypassed(q, nr_bios, force_fg)) - return true; - - z_erofs_vle_unzip_kickoff(bi_private, nr_bios); - return true; -} - -static void z_erofs_submit_and_unzip(struct z_erofs_vle_frontend *f, - struct list_head *pagepool, - bool force_fg) -{ - struct super_block *sb = f->inode->i_sb; - struct z_erofs_vle_unzip_io io[NR_JOBQUEUES]; - - if (!z_erofs_vle_submit_all(sb, f->owned_head, pagepool, io, force_fg)) - return; - -#ifdef EROFS_FS_HAS_MANAGED_CACHE - z_erofs_vle_unzip_all(sb, &io[JQ_BYPASS], pagepool); -#endif - if (!force_fg) - return; - - /* wait until all bios are completed */ - wait_event(io[JQ_SUBMIT].u.wait, - !atomic_read(&io[JQ_SUBMIT].pending_bios)); - - /* let's synchronous decompression */ - z_erofs_vle_unzip_all(sb, &io[JQ_SUBMIT], pagepool); -} - -static int z_erofs_vle_normalaccess_readpage(struct file *file, - struct page *page) -{ - struct inode *const inode = page->mapping->host; - struct z_erofs_vle_frontend f = VLE_FRONTEND_INIT(inode); - int err; - LIST_HEAD(pagepool); - - trace_erofs_readpage(page, false); - - f.headoffset = (erofs_off_t)page->index << PAGE_SHIFT; - - err = z_erofs_do_read_page(&f, page, &pagepool); - (void)z_erofs_vle_work_iter_end(&f.builder); - - if (err) { - errln("%s, failed to read, err [%d]", __func__, err); - goto out; - } - - z_erofs_submit_and_unzip(&f, &pagepool, true); -out: - if (f.map.mpage) - put_page(f.map.mpage); - - /* clean up the remaining free pages */ - put_pages_list(&pagepool); - return 0; -} - -static int z_erofs_vle_normalaccess_readpages(struct file *filp, - struct address_space *mapping, - struct list_head *pages, - unsigned int nr_pages) -{ - struct inode *const inode = mapping->host; - struct erofs_sb_info *const sbi = EROFS_I_SB(inode); - - bool sync = __should_decompress_synchronously(sbi, nr_pages); - struct z_erofs_vle_frontend f = VLE_FRONTEND_INIT(inode); - gfp_t gfp = mapping_gfp_constraint(mapping, GFP_KERNEL); - struct page *head = NULL; - LIST_HEAD(pagepool); - - trace_erofs_readpages(mapping->host, lru_to_page(pages), - nr_pages, false); - - f.headoffset = (erofs_off_t)lru_to_page(pages)->index << PAGE_SHIFT; - - for (; nr_pages; --nr_pages) { - struct page *page = lru_to_page(pages); - - prefetchw(&page->flags); - list_del(&page->lru); - - /* - * A pure asynchronous readahead is indicated if - * a PG_readahead marked page is hitted at first. - * Let's also do asynchronous decompression for this case. - */ - sync &= !(PageReadahead(page) && !head); - - if (add_to_page_cache_lru(page, mapping, page->index, gfp)) { - list_add(&page->lru, &pagepool); - continue; - } - - set_page_private(page, (unsigned long)head); - head = page; - } - - while (head) { - struct page *page = head; - int err; - - /* traversal in reverse order */ - head = (void *)page_private(page); - - err = z_erofs_do_read_page(&f, page, &pagepool); - if (err) { - struct erofs_vnode *vi = EROFS_V(inode); - - errln("%s, readahead error at page %lu of nid %llu", - __func__, page->index, vi->nid); - } - - put_page(page); - } - - (void)z_erofs_vle_work_iter_end(&f.builder); - - z_erofs_submit_and_unzip(&f, &pagepool, sync); - - if (f.map.mpage) - put_page(f.map.mpage); - - /* clean up the remaining free pages */ - put_pages_list(&pagepool); - return 0; -} - -const struct address_space_operations z_erofs_vle_normalaccess_aops = { - .readpage = z_erofs_vle_normalaccess_readpage, - .readpages = z_erofs_vle_normalaccess_readpages, -}; - diff --git a/drivers/staging/erofs/unzip_vle.h b/drivers/staging/erofs/unzip_vle.h deleted file mode 100644 index ab509d75aefd..000000000000 --- a/drivers/staging/erofs/unzip_vle.h +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * linux/drivers/staging/erofs/unzip_vle.h - * - * Copyright (C) 2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#ifndef __EROFS_FS_UNZIP_VLE_H -#define __EROFS_FS_UNZIP_VLE_H - -#include "internal.h" -#include "unzip_pagevec.h" - -#define Z_EROFS_NR_INLINE_PAGEVECS 3 - -/* - * Structure fields follow one of the following exclusion rules. - * - * I: Modifiable by initialization/destruction paths and read-only - * for everyone else. - * - */ - -struct z_erofs_vle_work { - struct mutex lock; - - /* I: decompression offset in page */ - unsigned short pageofs; - unsigned short nr_pages; - - /* L: queued pages in pagevec[] */ - unsigned vcnt; - - union { - /* L: pagevec */ - erofs_vtptr_t pagevec[Z_EROFS_NR_INLINE_PAGEVECS]; - struct rcu_head rcu; - }; -}; - -#define Z_EROFS_VLE_WORKGRP_FMT_PLAIN 0 -#define Z_EROFS_VLE_WORKGRP_FMT_LZ4 1 -#define Z_EROFS_VLE_WORKGRP_FMT_MASK 1 -#define Z_EROFS_VLE_WORKGRP_FULL_LENGTH 2 - -typedef void *z_erofs_vle_owned_workgrp_t; - -struct z_erofs_vle_workgroup { - struct erofs_workgroup obj; - struct z_erofs_vle_work work; - - /* point to next owned_workgrp_t */ - z_erofs_vle_owned_workgrp_t next; - - /* compressed pages (including multi-usage pages) */ - struct page *compressed_pages[Z_EROFS_CLUSTER_MAX_PAGES]; - unsigned int llen, flags; -}; - -/* let's avoid the valid 32-bit kernel addresses */ - -/* the chained workgroup has't submitted io (still open) */ -#define Z_EROFS_VLE_WORKGRP_TAIL ((void *)0x5F0ECAFE) -/* the chained workgroup has already submitted io */ -#define Z_EROFS_VLE_WORKGRP_TAIL_CLOSED ((void *)0x5F0EDEAD) - -#define Z_EROFS_VLE_WORKGRP_NIL (NULL) - -#define z_erofs_vle_workgrp_fmt(grp) \ - ((grp)->flags & Z_EROFS_VLE_WORKGRP_FMT_MASK) - -static inline void z_erofs_vle_set_workgrp_fmt( - struct z_erofs_vle_workgroup *grp, - unsigned int fmt) -{ - grp->flags = fmt | (grp->flags & ~Z_EROFS_VLE_WORKGRP_FMT_MASK); -} - - -/* definitions if multiref is disabled */ -#define z_erofs_vle_grab_primary_work(grp) (&(grp)->work) -#define z_erofs_vle_grab_work(grp, pageofs) (&(grp)->work) -#define z_erofs_vle_work_workgroup(wrk, primary) \ - ((primary) ? container_of(wrk, \ - struct z_erofs_vle_workgroup, work) : \ - ({ BUG(); (void *)NULL; })) - - -#define Z_EROFS_WORKGROUP_SIZE sizeof(struct z_erofs_vle_workgroup) - -struct z_erofs_vle_unzip_io { - atomic_t pending_bios; - z_erofs_vle_owned_workgrp_t head; - - union { - wait_queue_head_t wait; - struct work_struct work; - } u; -}; - -struct z_erofs_vle_unzip_io_sb { - struct z_erofs_vle_unzip_io io; - struct super_block *sb; -}; - -#define Z_EROFS_ONLINEPAGE_COUNT_BITS 2 -#define Z_EROFS_ONLINEPAGE_COUNT_MASK ((1 << Z_EROFS_ONLINEPAGE_COUNT_BITS) - 1) -#define Z_EROFS_ONLINEPAGE_INDEX_SHIFT (Z_EROFS_ONLINEPAGE_COUNT_BITS) - -/* - * waiters (aka. ongoing_packs): # to unlock the page - * sub-index: 0 - for partial page, >= 1 full page sub-index - */ -typedef atomic_t z_erofs_onlinepage_t; - -/* type punning */ -union z_erofs_onlinepage_converter { - z_erofs_onlinepage_t *o; - unsigned long *v; -}; - -static inline unsigned z_erofs_onlinepage_index(struct page *page) -{ - union z_erofs_onlinepage_converter u; - - DBG_BUGON(!PagePrivate(page)); - u.v = &page_private(page); - - return atomic_read(u.o) >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT; -} - -static inline void z_erofs_onlinepage_init(struct page *page) -{ - union { - z_erofs_onlinepage_t o; - unsigned long v; - /* keep from being unlocked in advance */ - } u = { .o = ATOMIC_INIT(1) }; - - set_page_private(page, u.v); - smp_wmb(); - SetPagePrivate(page); -} - -static inline void z_erofs_onlinepage_fixup(struct page *page, - uintptr_t index, bool down) -{ - unsigned long *p, o, v, id; -repeat: - p = &page_private(page); - o = READ_ONCE(*p); - - id = o >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT; - if (id) { - if (!index) - return; - - DBG_BUGON(id != index); - } - - v = (index << Z_EROFS_ONLINEPAGE_INDEX_SHIFT) | - ((o & Z_EROFS_ONLINEPAGE_COUNT_MASK) + (unsigned)down); - if (cmpxchg(p, o, v) != o) - goto repeat; -} - -static inline void z_erofs_onlinepage_endio(struct page *page) -{ - union z_erofs_onlinepage_converter u; - unsigned v; - - DBG_BUGON(!PagePrivate(page)); - u.v = &page_private(page); - - v = atomic_dec_return(u.o); - if (!(v & Z_EROFS_ONLINEPAGE_COUNT_MASK)) { - ClearPagePrivate(page); - if (!PageError(page)) - SetPageUptodate(page); - unlock_page(page); - } - - debugln("%s, page %p value %x", __func__, page, atomic_read(u.o)); -} - -#define Z_EROFS_VLE_VMAP_ONSTACK_PAGES \ - min_t(unsigned int, THREAD_SIZE / 8 / sizeof(struct page *), 96U) -#define Z_EROFS_VLE_VMAP_GLOBAL_PAGES 2048 - -#endif - diff --git a/drivers/staging/erofs/utils.c b/drivers/staging/erofs/utils.c deleted file mode 100644 index 4bbd3bf34acd..000000000000 --- a/drivers/staging/erofs/utils.c +++ /dev/null @@ -1,353 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/utils.c - * - * Copyright (C) 2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ - -#include "internal.h" -#include <linux/pagevec.h> - -struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp) -{ - struct page *page; - - if (!list_empty(pool)) { - page = lru_to_page(pool); - list_del(&page->lru); - } else { - page = alloc_pages(gfp | __GFP_NOFAIL, 0); - } - return page; -} - -#if (EROFS_PCPUBUF_NR_PAGES > 0) -static struct { - u8 data[PAGE_SIZE * EROFS_PCPUBUF_NR_PAGES]; -} ____cacheline_aligned_in_smp erofs_pcpubuf[NR_CPUS]; - -void *erofs_get_pcpubuf(unsigned int pagenr) -{ - preempt_disable(); - return &erofs_pcpubuf[smp_processor_id()].data[pagenr * PAGE_SIZE]; -} -#endif - -/* global shrink count (for all mounted EROFS instances) */ -static atomic_long_t erofs_global_shrink_cnt; - -#ifdef CONFIG_EROFS_FS_ZIP -#define __erofs_workgroup_get(grp) atomic_inc(&(grp)->refcount) -#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount) - -static int erofs_workgroup_get(struct erofs_workgroup *grp) -{ - int o; - -repeat: - o = erofs_wait_on_workgroup_freezed(grp); - if (unlikely(o <= 0)) - return -1; - - if (unlikely(atomic_cmpxchg(&grp->refcount, o, o + 1) != o)) - goto repeat; - - /* decrease refcount paired by erofs_workgroup_put */ - if (unlikely(o == 1)) - atomic_long_dec(&erofs_global_shrink_cnt); - return 0; -} - -struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, - pgoff_t index, bool *tag) -{ - struct erofs_sb_info *sbi = EROFS_SB(sb); - struct erofs_workgroup *grp; - -repeat: - rcu_read_lock(); - grp = radix_tree_lookup(&sbi->workstn_tree, index); - if (grp) { - *tag = xa_pointer_tag(grp); - grp = xa_untag_pointer(grp); - - if (erofs_workgroup_get(grp)) { - /* prefer to relax rcu read side */ - rcu_read_unlock(); - goto repeat; - } - - DBG_BUGON(index != grp->index); - } - rcu_read_unlock(); - return grp; -} - -int erofs_register_workgroup(struct super_block *sb, - struct erofs_workgroup *grp, - bool tag) -{ - struct erofs_sb_info *sbi; - int err; - - /* grp shouldn't be broken or used before */ - if (unlikely(atomic_read(&grp->refcount) != 1)) { - DBG_BUGON(1); - return -EINVAL; - } - - err = radix_tree_preload(GFP_NOFS); - if (err) - return err; - - sbi = EROFS_SB(sb); - erofs_workstn_lock(sbi); - - grp = xa_tag_pointer(grp, tag); - - /* - * Bump up reference count before making this workgroup - * visible to other users in order to avoid potential UAF - * without serialized by erofs_workstn_lock. - */ - __erofs_workgroup_get(grp); - - err = radix_tree_insert(&sbi->workstn_tree, - grp->index, grp); - if (unlikely(err)) - /* - * it's safe to decrease since the workgroup isn't visible - * and refcount >= 2 (cannot be freezed). - */ - __erofs_workgroup_put(grp); - - erofs_workstn_unlock(sbi); - radix_tree_preload_end(); - return err; -} - -static void __erofs_workgroup_free(struct erofs_workgroup *grp) -{ - atomic_long_dec(&erofs_global_shrink_cnt); - erofs_workgroup_free_rcu(grp); -} - -int erofs_workgroup_put(struct erofs_workgroup *grp) -{ - int count = atomic_dec_return(&grp->refcount); - - if (count == 1) - atomic_long_inc(&erofs_global_shrink_cnt); - else if (!count) - __erofs_workgroup_free(grp); - return count; -} - -#ifdef EROFS_FS_HAS_MANAGED_CACHE -/* for cache-managed case, customized reclaim paths exist */ -static void erofs_workgroup_unfreeze_final(struct erofs_workgroup *grp) -{ - erofs_workgroup_unfreeze(grp, 0); - __erofs_workgroup_free(grp); -} - -static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, - struct erofs_workgroup *grp, - bool cleanup) -{ - /* - * for managed cache enabled, the refcount of workgroups - * themselves could be < 0 (freezed). So there is no guarantee - * that all refcount > 0 if managed cache is enabled. - */ - if (!erofs_workgroup_try_to_freeze(grp, 1)) - return false; - - /* - * note that all cached pages should be unlinked - * before delete it from the radix tree. - * Otherwise some cached pages of an orphan old workgroup - * could be still linked after the new one is available. - */ - if (erofs_try_to_free_all_cached_pages(sbi, grp)) { - erofs_workgroup_unfreeze(grp, 1); - return false; - } - - /* - * it is impossible to fail after the workgroup is freezed, - * however in order to avoid some race conditions, add a - * DBG_BUGON to observe this in advance. - */ - DBG_BUGON(xa_untag_pointer(radix_tree_delete(&sbi->workstn_tree, - grp->index)) != grp); - - /* - * if managed cache is enable, the last refcount - * should indicate the related workstation. - */ - erofs_workgroup_unfreeze_final(grp); - return true; -} - -#else -/* for nocache case, no customized reclaim path at all */ -static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, - struct erofs_workgroup *grp, - bool cleanup) -{ - int cnt = atomic_read(&grp->refcount); - - DBG_BUGON(cnt <= 0); - DBG_BUGON(cleanup && cnt != 1); - - if (cnt > 1) - return false; - - DBG_BUGON(xa_untag_pointer(radix_tree_delete(&sbi->workstn_tree, - grp->index)) != grp); - - /* (rarely) could be grabbed again when freeing */ - erofs_workgroup_put(grp); - return true; -} - -#endif - -unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, - unsigned long nr_shrink, - bool cleanup) -{ - pgoff_t first_index = 0; - void *batch[PAGEVEC_SIZE]; - unsigned int freed = 0; - - int i, found; -repeat: - erofs_workstn_lock(sbi); - - found = radix_tree_gang_lookup(&sbi->workstn_tree, - batch, first_index, PAGEVEC_SIZE); - - for (i = 0; i < found; ++i) { - struct erofs_workgroup *grp = xa_untag_pointer(batch[i]); - - first_index = grp->index + 1; - - /* try to shrink each valid workgroup */ - if (!erofs_try_to_release_workgroup(sbi, grp, cleanup)) - continue; - - ++freed; - if (unlikely(!--nr_shrink)) - break; - } - erofs_workstn_unlock(sbi); - - if (i && nr_shrink) - goto repeat; - return freed; -} - -#endif - -/* protected by 'erofs_sb_list_lock' */ -static unsigned int shrinker_run_no; - -/* protects the mounted 'erofs_sb_list' */ -static DEFINE_SPINLOCK(erofs_sb_list_lock); -static LIST_HEAD(erofs_sb_list); - -void erofs_register_super(struct super_block *sb) -{ - struct erofs_sb_info *sbi = EROFS_SB(sb); - - mutex_init(&sbi->umount_mutex); - - spin_lock(&erofs_sb_list_lock); - list_add(&sbi->list, &erofs_sb_list); - spin_unlock(&erofs_sb_list_lock); -} - -void erofs_unregister_super(struct super_block *sb) -{ - spin_lock(&erofs_sb_list_lock); - list_del(&EROFS_SB(sb)->list); - spin_unlock(&erofs_sb_list_lock); -} - -static unsigned long erofs_shrink_count(struct shrinker *shrink, - struct shrink_control *sc) -{ - return atomic_long_read(&erofs_global_shrink_cnt); -} - -static unsigned long erofs_shrink_scan(struct shrinker *shrink, - struct shrink_control *sc) -{ - struct erofs_sb_info *sbi; - struct list_head *p; - - unsigned long nr = sc->nr_to_scan; - unsigned int run_no; - unsigned long freed = 0; - - spin_lock(&erofs_sb_list_lock); - do - run_no = ++shrinker_run_no; - while (run_no == 0); - - /* Iterate over all mounted superblocks and try to shrink them */ - p = erofs_sb_list.next; - while (p != &erofs_sb_list) { - sbi = list_entry(p, struct erofs_sb_info, list); - - /* - * We move the ones we do to the end of the list, so we stop - * when we see one we have already done. - */ - if (sbi->shrinker_run_no == run_no) - break; - - if (!mutex_trylock(&sbi->umount_mutex)) { - p = p->next; - continue; - } - - spin_unlock(&erofs_sb_list_lock); - sbi->shrinker_run_no = run_no; - -#ifdef CONFIG_EROFS_FS_ZIP - freed += erofs_shrink_workstation(sbi, nr, false); -#endif - - spin_lock(&erofs_sb_list_lock); - /* Get the next list element before we move this one */ - p = p->next; - - /* - * Move this one to the end of the list to provide some - * fairness. - */ - list_move_tail(&sbi->list, &erofs_sb_list); - mutex_unlock(&sbi->umount_mutex); - - if (freed >= nr) - break; - } - spin_unlock(&erofs_sb_list_lock); - return freed; -} - -struct shrinker erofs_shrinker_info = { - .scan_objects = erofs_shrink_scan, - .count_objects = erofs_shrink_count, - .seeks = DEFAULT_SEEKS, -}; - diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c deleted file mode 100644 index df40654b9fbb..000000000000 --- a/drivers/staging/erofs/xattr.c +++ /dev/null @@ -1,704 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/xattr.c - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#include <linux/security.h> -#include "xattr.h" - -struct xattr_iter { - struct super_block *sb; - struct page *page; - void *kaddr; - - erofs_blk_t blkaddr; - unsigned int ofs; -}; - -static inline void xattr_iter_end(struct xattr_iter *it, bool atomic) -{ - /* the only user of kunmap() is 'init_inode_xattrs' */ - if (unlikely(!atomic)) - kunmap(it->page); - else - kunmap_atomic(it->kaddr); - - unlock_page(it->page); - put_page(it->page); -} - -static inline void xattr_iter_end_final(struct xattr_iter *it) -{ - if (!it->page) - return; - - xattr_iter_end(it, true); -} - -static int init_inode_xattrs(struct inode *inode) -{ - struct erofs_vnode *const vi = EROFS_V(inode); - struct xattr_iter it; - unsigned int i; - struct erofs_xattr_ibody_header *ih; - struct super_block *sb; - struct erofs_sb_info *sbi; - bool atomic_map; - int ret = 0; - - /* the most case is that xattrs of this inode are initialized. */ - if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) - return 0; - - if (wait_on_bit_lock(&vi->flags, EROFS_V_BL_XATTR_BIT, TASK_KILLABLE)) - return -ERESTARTSYS; - - /* someone has initialized xattrs for us? */ - if (test_bit(EROFS_V_EA_INITED_BIT, &vi->flags)) - goto out_unlock; - - /* - * bypass all xattr operations if ->xattr_isize is not greater than - * sizeof(struct erofs_xattr_ibody_header), in detail: - * 1) it is not enough to contain erofs_xattr_ibody_header then - * ->xattr_isize should be 0 (it means no xattr); - * 2) it is just to contain erofs_xattr_ibody_header, which is on-disk - * undefined right now (maybe use later with some new sb feature). - */ - if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) { - errln("xattr_isize %d of nid %llu is not supported yet", - vi->xattr_isize, vi->nid); - ret = -ENOTSUPP; - goto out_unlock; - } else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) { - if (unlikely(vi->xattr_isize)) { - DBG_BUGON(1); - ret = -EIO; - goto out_unlock; /* xattr ondisk layout error */ - } - ret = -ENOATTR; - goto out_unlock; - } - - sb = inode->i_sb; - sbi = EROFS_SB(sb); - it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize); - it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize); - - it.page = erofs_get_inline_page(inode, it.blkaddr); - if (IS_ERR(it.page)) { - ret = PTR_ERR(it.page); - goto out_unlock; - } - - /* read in shared xattr array (non-atomic, see kmalloc below) */ - it.kaddr = kmap(it.page); - atomic_map = false; - - ih = (struct erofs_xattr_ibody_header *)(it.kaddr + it.ofs); - - vi->xattr_shared_count = ih->h_shared_count; - vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count, - sizeof(uint), GFP_KERNEL); - if (!vi->xattr_shared_xattrs) { - xattr_iter_end(&it, atomic_map); - ret = -ENOMEM; - goto out_unlock; - } - - /* let's skip ibody header */ - it.ofs += sizeof(struct erofs_xattr_ibody_header); - - for (i = 0; i < vi->xattr_shared_count; ++i) { - if (unlikely(it.ofs >= EROFS_BLKSIZ)) { - /* cannot be unaligned */ - BUG_ON(it.ofs != EROFS_BLKSIZ); - xattr_iter_end(&it, atomic_map); - - it.page = erofs_get_meta_page(sb, ++it.blkaddr, - S_ISDIR(inode->i_mode)); - if (IS_ERR(it.page)) { - kfree(vi->xattr_shared_xattrs); - vi->xattr_shared_xattrs = NULL; - ret = PTR_ERR(it.page); - goto out_unlock; - } - - it.kaddr = kmap_atomic(it.page); - atomic_map = true; - it.ofs = 0; - } - vi->xattr_shared_xattrs[i] = - le32_to_cpu(*(__le32 *)(it.kaddr + it.ofs)); - it.ofs += sizeof(__le32); - } - xattr_iter_end(&it, atomic_map); - - set_bit(EROFS_V_EA_INITED_BIT, &vi->flags); - -out_unlock: - clear_and_wake_up_bit(EROFS_V_BL_XATTR_BIT, &vi->flags); - return ret; -} - -/* - * the general idea for these return values is - * if 0 is returned, go on processing the current xattr; - * 1 (> 0) is returned, skip this round to process the next xattr; - * -err (< 0) is returned, an error (maybe ENOXATTR) occurred - * and need to be handled - */ -struct xattr_iter_handlers { - int (*entry)(struct xattr_iter *_it, struct erofs_xattr_entry *entry); - int (*name)(struct xattr_iter *_it, unsigned int processed, char *buf, - unsigned int len); - int (*alloc_buffer)(struct xattr_iter *_it, unsigned int value_sz); - void (*value)(struct xattr_iter *_it, unsigned int processed, char *buf, - unsigned int len); -}; - -static inline int xattr_iter_fixup(struct xattr_iter *it) -{ - if (it->ofs < EROFS_BLKSIZ) - return 0; - - xattr_iter_end(it, true); - - it->blkaddr += erofs_blknr(it->ofs); - - it->page = erofs_get_meta_page(it->sb, it->blkaddr, false); - if (IS_ERR(it->page)) { - int err = PTR_ERR(it->page); - - it->page = NULL; - return err; - } - - it->kaddr = kmap_atomic(it->page); - it->ofs = erofs_blkoff(it->ofs); - return 0; -} - -static int inline_xattr_iter_begin(struct xattr_iter *it, - struct inode *inode) -{ - struct erofs_vnode *const vi = EROFS_V(inode); - struct erofs_sb_info *const sbi = EROFS_SB(inode->i_sb); - unsigned int xattr_header_sz, inline_xattr_ofs; - - xattr_header_sz = inlinexattr_header_size(inode); - if (unlikely(xattr_header_sz >= vi->xattr_isize)) { - BUG_ON(xattr_header_sz > vi->xattr_isize); - return -ENOATTR; - } - - inline_xattr_ofs = vi->inode_isize + xattr_header_sz; - - it->blkaddr = erofs_blknr(iloc(sbi, vi->nid) + inline_xattr_ofs); - it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs); - - it->page = erofs_get_inline_page(inode, it->blkaddr); - if (IS_ERR(it->page)) - return PTR_ERR(it->page); - - it->kaddr = kmap_atomic(it->page); - return vi->xattr_isize - xattr_header_sz; -} - -/* - * Regardless of success or failure, `xattr_foreach' will end up with - * `ofs' pointing to the next xattr item rather than an arbitrary position. - */ -static int xattr_foreach(struct xattr_iter *it, - const struct xattr_iter_handlers *op, - unsigned int *tlimit) -{ - struct erofs_xattr_entry entry; - unsigned int value_sz, processed, slice; - int err; - - /* 0. fixup blkaddr, ofs, ipage */ - err = xattr_iter_fixup(it); - if (err) - return err; - - /* - * 1. read xattr entry to the memory, - * since we do EROFS_XATTR_ALIGN - * therefore entry should be in the page - */ - entry = *(struct erofs_xattr_entry *)(it->kaddr + it->ofs); - if (tlimit) { - unsigned int entry_sz = EROFS_XATTR_ENTRY_SIZE(&entry); - - BUG_ON(*tlimit < entry_sz); - *tlimit -= entry_sz; - } - - it->ofs += sizeof(struct erofs_xattr_entry); - value_sz = le16_to_cpu(entry.e_value_size); - - /* handle entry */ - err = op->entry(it, &entry); - if (err) { - it->ofs += entry.e_name_len + value_sz; - goto out; - } - - /* 2. handle xattr name (ofs will finally be at the end of name) */ - processed = 0; - - while (processed < entry.e_name_len) { - if (it->ofs >= EROFS_BLKSIZ) { - BUG_ON(it->ofs > EROFS_BLKSIZ); - - err = xattr_iter_fixup(it); - if (err) - goto out; - it->ofs = 0; - } - - slice = min_t(unsigned int, PAGE_SIZE - it->ofs, - entry.e_name_len - processed); - - /* handle name */ - err = op->name(it, processed, it->kaddr + it->ofs, slice); - if (err) { - it->ofs += entry.e_name_len - processed + value_sz; - goto out; - } - - it->ofs += slice; - processed += slice; - } - - /* 3. handle xattr value */ - processed = 0; - - if (op->alloc_buffer) { - err = op->alloc_buffer(it, value_sz); - if (err) { - it->ofs += value_sz; - goto out; - } - } - - while (processed < value_sz) { - if (it->ofs >= EROFS_BLKSIZ) { - BUG_ON(it->ofs > EROFS_BLKSIZ); - - err = xattr_iter_fixup(it); - if (err) - goto out; - it->ofs = 0; - } - - slice = min_t(unsigned int, PAGE_SIZE - it->ofs, - value_sz - processed); - op->value(it, processed, it->kaddr + it->ofs, slice); - it->ofs += slice; - processed += slice; - } - -out: - /* xattrs should be 4-byte aligned (on-disk constraint) */ - it->ofs = EROFS_XATTR_ALIGN(it->ofs); - return err < 0 ? err : 0; -} - -struct getxattr_iter { - struct xattr_iter it; - - char *buffer; - int buffer_size, index; - struct qstr name; -}; - -static int xattr_entrymatch(struct xattr_iter *_it, - struct erofs_xattr_entry *entry) -{ - struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it); - - return (it->index != entry->e_name_index || - it->name.len != entry->e_name_len) ? -ENOATTR : 0; -} - -static int xattr_namematch(struct xattr_iter *_it, - unsigned int processed, char *buf, unsigned int len) -{ - struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it); - - return memcmp(buf, it->name.name + processed, len) ? -ENOATTR : 0; -} - -static int xattr_checkbuffer(struct xattr_iter *_it, - unsigned int value_sz) -{ - struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it); - int err = it->buffer_size < value_sz ? -ERANGE : 0; - - it->buffer_size = value_sz; - return !it->buffer ? 1 : err; -} - -static void xattr_copyvalue(struct xattr_iter *_it, - unsigned int processed, - char *buf, unsigned int len) -{ - struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it); - - memcpy(it->buffer + processed, buf, len); -} - -static const struct xattr_iter_handlers find_xattr_handlers = { - .entry = xattr_entrymatch, - .name = xattr_namematch, - .alloc_buffer = xattr_checkbuffer, - .value = xattr_copyvalue -}; - -static int inline_getxattr(struct inode *inode, struct getxattr_iter *it) -{ - int ret; - unsigned int remaining; - - ret = inline_xattr_iter_begin(&it->it, inode); - if (ret < 0) - return ret; - - remaining = ret; - while (remaining) { - ret = xattr_foreach(&it->it, &find_xattr_handlers, &remaining); - if (ret != -ENOATTR) - break; - } - xattr_iter_end_final(&it->it); - - return ret ? ret : it->buffer_size; -} - -static int shared_getxattr(struct inode *inode, struct getxattr_iter *it) -{ - struct erofs_vnode *const vi = EROFS_V(inode); - struct super_block *const sb = inode->i_sb; - struct erofs_sb_info *const sbi = EROFS_SB(sb); - unsigned int i; - int ret = -ENOATTR; - - for (i = 0; i < vi->xattr_shared_count; ++i) { - erofs_blk_t blkaddr = - xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]); - - it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]); - - if (!i || blkaddr != it->it.blkaddr) { - if (i) - xattr_iter_end(&it->it, true); - - it->it.page = erofs_get_meta_page(sb, blkaddr, false); - if (IS_ERR(it->it.page)) - return PTR_ERR(it->it.page); - - it->it.kaddr = kmap_atomic(it->it.page); - it->it.blkaddr = blkaddr; - } - - ret = xattr_foreach(&it->it, &find_xattr_handlers, NULL); - if (ret != -ENOATTR) - break; - } - if (vi->xattr_shared_count) - xattr_iter_end_final(&it->it); - - return ret ? ret : it->buffer_size; -} - -static bool erofs_xattr_user_list(struct dentry *dentry) -{ - return test_opt(EROFS_SB(dentry->d_sb), XATTR_USER); -} - -static bool erofs_xattr_trusted_list(struct dentry *dentry) -{ - return capable(CAP_SYS_ADMIN); -} - -int erofs_getxattr(struct inode *inode, int index, - const char *name, - void *buffer, size_t buffer_size) -{ - int ret; - struct getxattr_iter it; - - if (unlikely(!name)) - return -EINVAL; - - ret = init_inode_xattrs(inode); - if (ret) - return ret; - - it.index = index; - - it.name.len = strlen(name); - if (it.name.len > EROFS_NAME_LEN) - return -ERANGE; - it.name.name = name; - - it.buffer = buffer; - it.buffer_size = buffer_size; - - it.it.sb = inode->i_sb; - ret = inline_getxattr(inode, &it); - if (ret == -ENOATTR) - ret = shared_getxattr(inode, &it); - return ret; -} - -static int erofs_xattr_generic_get(const struct xattr_handler *handler, - struct dentry *unused, struct inode *inode, - const char *name, void *buffer, size_t size) -{ - struct erofs_sb_info *const sbi = EROFS_I_SB(inode); - - switch (handler->flags) { - case EROFS_XATTR_INDEX_USER: - if (!test_opt(sbi, XATTR_USER)) - return -EOPNOTSUPP; - break; - case EROFS_XATTR_INDEX_TRUSTED: - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - break; - case EROFS_XATTR_INDEX_SECURITY: - break; - default: - return -EINVAL; - } - - return erofs_getxattr(inode, handler->flags, name, buffer, size); -} - -const struct xattr_handler erofs_xattr_user_handler = { - .prefix = XATTR_USER_PREFIX, - .flags = EROFS_XATTR_INDEX_USER, - .list = erofs_xattr_user_list, - .get = erofs_xattr_generic_get, -}; - -const struct xattr_handler erofs_xattr_trusted_handler = { - .prefix = XATTR_TRUSTED_PREFIX, - .flags = EROFS_XATTR_INDEX_TRUSTED, - .list = erofs_xattr_trusted_list, - .get = erofs_xattr_generic_get, -}; - -#ifdef CONFIG_EROFS_FS_SECURITY -const struct xattr_handler __maybe_unused erofs_xattr_security_handler = { - .prefix = XATTR_SECURITY_PREFIX, - .flags = EROFS_XATTR_INDEX_SECURITY, - .get = erofs_xattr_generic_get, -}; -#endif - -const struct xattr_handler *erofs_xattr_handlers[] = { - &erofs_xattr_user_handler, -#ifdef CONFIG_EROFS_FS_POSIX_ACL - &posix_acl_access_xattr_handler, - &posix_acl_default_xattr_handler, -#endif - &erofs_xattr_trusted_handler, -#ifdef CONFIG_EROFS_FS_SECURITY - &erofs_xattr_security_handler, -#endif - NULL, -}; - -struct listxattr_iter { - struct xattr_iter it; - - struct dentry *dentry; - char *buffer; - int buffer_size, buffer_ofs; -}; - -static int xattr_entrylist(struct xattr_iter *_it, - struct erofs_xattr_entry *entry) -{ - struct listxattr_iter *it = - container_of(_it, struct listxattr_iter, it); - unsigned int prefix_len; - const char *prefix; - - const struct xattr_handler *h = - erofs_xattr_handler(entry->e_name_index); - - if (!h || (h->list && !h->list(it->dentry))) - return 1; - - prefix = xattr_prefix(h); - prefix_len = strlen(prefix); - - if (!it->buffer) { - it->buffer_ofs += prefix_len + entry->e_name_len + 1; - return 1; - } - - if (it->buffer_ofs + prefix_len - + entry->e_name_len + 1 > it->buffer_size) - return -ERANGE; - - memcpy(it->buffer + it->buffer_ofs, prefix, prefix_len); - it->buffer_ofs += prefix_len; - return 0; -} - -static int xattr_namelist(struct xattr_iter *_it, - unsigned int processed, char *buf, unsigned int len) -{ - struct listxattr_iter *it = - container_of(_it, struct listxattr_iter, it); - - memcpy(it->buffer + it->buffer_ofs, buf, len); - it->buffer_ofs += len; - return 0; -} - -static int xattr_skipvalue(struct xattr_iter *_it, - unsigned int value_sz) -{ - struct listxattr_iter *it = - container_of(_it, struct listxattr_iter, it); - - it->buffer[it->buffer_ofs++] = '\0'; - return 1; -} - -static const struct xattr_iter_handlers list_xattr_handlers = { - .entry = xattr_entrylist, - .name = xattr_namelist, - .alloc_buffer = xattr_skipvalue, - .value = NULL -}; - -static int inline_listxattr(struct listxattr_iter *it) -{ - int ret; - unsigned int remaining; - - ret = inline_xattr_iter_begin(&it->it, d_inode(it->dentry)); - if (ret < 0) - return ret; - - remaining = ret; - while (remaining) { - ret = xattr_foreach(&it->it, &list_xattr_handlers, &remaining); - if (ret) - break; - } - xattr_iter_end_final(&it->it); - return ret ? ret : it->buffer_ofs; -} - -static int shared_listxattr(struct listxattr_iter *it) -{ - struct inode *const inode = d_inode(it->dentry); - struct erofs_vnode *const vi = EROFS_V(inode); - struct super_block *const sb = inode->i_sb; - struct erofs_sb_info *const sbi = EROFS_SB(sb); - unsigned int i; - int ret = 0; - - for (i = 0; i < vi->xattr_shared_count; ++i) { - erofs_blk_t blkaddr = - xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]); - - it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]); - if (!i || blkaddr != it->it.blkaddr) { - if (i) - xattr_iter_end(&it->it, true); - - it->it.page = erofs_get_meta_page(sb, blkaddr, false); - if (IS_ERR(it->it.page)) - return PTR_ERR(it->it.page); - - it->it.kaddr = kmap_atomic(it->it.page); - it->it.blkaddr = blkaddr; - } - - ret = xattr_foreach(&it->it, &list_xattr_handlers, NULL); - if (ret) - break; - } - if (vi->xattr_shared_count) - xattr_iter_end_final(&it->it); - - return ret ? ret : it->buffer_ofs; -} - -ssize_t erofs_listxattr(struct dentry *dentry, - char *buffer, size_t buffer_size) -{ - int ret; - struct listxattr_iter it; - - ret = init_inode_xattrs(d_inode(dentry)); - if (ret) - return ret; - - it.dentry = dentry; - it.buffer = buffer; - it.buffer_size = buffer_size; - it.buffer_ofs = 0; - - it.it.sb = dentry->d_sb; - - ret = inline_listxattr(&it); - if (ret < 0 && ret != -ENOATTR) - return ret; - return shared_listxattr(&it); -} - -#ifdef CONFIG_EROFS_FS_POSIX_ACL -struct posix_acl *erofs_get_acl(struct inode *inode, int type) -{ - struct posix_acl *acl; - int prefix, rc; - char *value = NULL; - - switch (type) { - case ACL_TYPE_ACCESS: - prefix = EROFS_XATTR_INDEX_POSIX_ACL_ACCESS; - break; - case ACL_TYPE_DEFAULT: - prefix = EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT; - break; - default: - return ERR_PTR(-EINVAL); - } - - rc = erofs_getxattr(inode, prefix, "", NULL, 0); - if (rc > 0) { - value = kmalloc(rc, GFP_KERNEL); - if (!value) - return ERR_PTR(-ENOMEM); - rc = erofs_getxattr(inode, prefix, "", value, rc); - } - - if (rc == -ENOATTR) - acl = NULL; - else if (rc < 0) - acl = ERR_PTR(rc); - else - acl = posix_acl_from_xattr(&init_user_ns, value, rc); - kfree(value); - return acl; -} -#endif - diff --git a/drivers/staging/erofs/xattr.h b/drivers/staging/erofs/xattr.h deleted file mode 100644 index 35ba5ac2139a..000000000000 --- a/drivers/staging/erofs/xattr.h +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * linux/drivers/staging/erofs/xattr.h - * - * Copyright (C) 2017-2018 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ -#ifndef __EROFS_XATTR_H -#define __EROFS_XATTR_H - -#include "internal.h" -#include <linux/posix_acl_xattr.h> -#include <linux/xattr.h> - -/* Attribute not found */ -#define ENOATTR ENODATA - -static inline unsigned inlinexattr_header_size(struct inode *inode) -{ - return sizeof(struct erofs_xattr_ibody_header) - + sizeof(u32) * EROFS_V(inode)->xattr_shared_count; -} - -static inline erofs_blk_t -xattrblock_addr(struct erofs_sb_info *sbi, unsigned xattr_id) -{ -#ifdef CONFIG_EROFS_FS_XATTR - return sbi->xattr_blkaddr + - xattr_id * sizeof(__u32) / EROFS_BLKSIZ; -#else - return 0; -#endif -} - -static inline unsigned -xattrblock_offset(struct erofs_sb_info *sbi, unsigned xattr_id) -{ - return (xattr_id * sizeof(__u32)) % EROFS_BLKSIZ; -} - -extern const struct xattr_handler erofs_xattr_user_handler; -extern const struct xattr_handler erofs_xattr_trusted_handler; -#ifdef CONFIG_EROFS_FS_SECURITY -extern const struct xattr_handler erofs_xattr_security_handler; -#endif - -static inline const struct xattr_handler *erofs_xattr_handler(unsigned index) -{ -static const struct xattr_handler *xattr_handler_map[] = { - [EROFS_XATTR_INDEX_USER] = &erofs_xattr_user_handler, -#ifdef CONFIG_EROFS_FS_POSIX_ACL - [EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler, - [EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT] = - &posix_acl_default_xattr_handler, -#endif - [EROFS_XATTR_INDEX_TRUSTED] = &erofs_xattr_trusted_handler, -#ifdef CONFIG_EROFS_FS_SECURITY - [EROFS_XATTR_INDEX_SECURITY] = &erofs_xattr_security_handler, -#endif -}; - return index && index < ARRAY_SIZE(xattr_handler_map) ? - xattr_handler_map[index] : NULL; -} - -#ifdef CONFIG_EROFS_FS_XATTR -extern const struct xattr_handler *erofs_xattr_handlers[]; - -int erofs_getxattr(struct inode *, int, const char *, void *, size_t); -ssize_t erofs_listxattr(struct dentry *, char *, size_t); -#else -static int __maybe_unused erofs_getxattr(struct inode *inode, int index, - const char *name, - void *buffer, size_t buffer_size) -{ - return -ENOTSUPP; -} - -static ssize_t __maybe_unused erofs_listxattr(struct dentry *dentry, - char *buffer, size_t buffer_size) -{ - return -ENOTSUPP; -} -#endif - -#ifdef CONFIG_EROFS_FS_POSIX_ACL -struct posix_acl *erofs_get_acl(struct inode *inode, int type); -#else -#define erofs_get_acl (NULL) -#endif - -#endif - diff --git a/drivers/staging/erofs/zmap.c b/drivers/staging/erofs/zmap.c deleted file mode 100644 index 9c0bd65c46bf..000000000000 --- a/drivers/staging/erofs/zmap.c +++ /dev/null @@ -1,463 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/drivers/staging/erofs/zmap.c - * - * Copyright (C) 2018-2019 HUAWEI, Inc. - * http://www.huawei.com/ - * Created by Gao Xiang <gaoxiang25@huawei.com> - */ -#include "internal.h" -#include <asm/unaligned.h> -#include <trace/events/erofs.h> - -int z_erofs_fill_inode(struct inode *inode) -{ - struct erofs_vnode *const vi = EROFS_V(inode); - struct super_block *const sb = inode->i_sb; - - if (vi->datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { - vi->z_advise = 0; - vi->z_algorithmtype[0] = 0; - vi->z_algorithmtype[1] = 0; - vi->z_logical_clusterbits = EROFS_SB(sb)->clusterbits; - vi->z_physical_clusterbits[0] = vi->z_logical_clusterbits; - vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits; - set_bit(EROFS_V_Z_INITED_BIT, &vi->flags); - } - - inode->i_mapping->a_ops = &z_erofs_vle_normalaccess_aops; - return 0; -} - -static int fill_inode_lazy(struct inode *inode) -{ - struct erofs_vnode *const vi = EROFS_V(inode); - struct super_block *const sb = inode->i_sb; - int err; - erofs_off_t pos; - struct page *page; - void *kaddr; - struct z_erofs_map_header *h; - - if (test_bit(EROFS_V_Z_INITED_BIT, &vi->flags)) - return 0; - - if (wait_on_bit_lock(&vi->flags, EROFS_V_BL_Z_BIT, TASK_KILLABLE)) - return -ERESTARTSYS; - - err = 0; - if (test_bit(EROFS_V_Z_INITED_BIT, &vi->flags)) - goto out_unlock; - - DBG_BUGON(vi->datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY); - - pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + - vi->xattr_isize, 8); - page = erofs_get_meta_page(sb, erofs_blknr(pos), false); - if (IS_ERR(page)) { - err = PTR_ERR(page); - goto out_unlock; - } - - kaddr = kmap_atomic(page); - - h = kaddr + erofs_blkoff(pos); - vi->z_advise = le16_to_cpu(h->h_advise); - vi->z_algorithmtype[0] = h->h_algorithmtype & 15; - vi->z_algorithmtype[1] = h->h_algorithmtype >> 4; - - if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX) { - errln("unknown compression format %u for nid %llu, please upgrade kernel", - vi->z_algorithmtype[0], vi->nid); - err = -ENOTSUPP; - goto unmap_done; - } - - vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); - vi->z_physical_clusterbits[0] = vi->z_logical_clusterbits + - ((h->h_clusterbits >> 3) & 3); - - if (vi->z_physical_clusterbits[0] != LOG_BLOCK_SIZE) { - errln("unsupported physical clusterbits %u for nid %llu, please upgrade kernel", - vi->z_physical_clusterbits[0], vi->nid); - err = -ENOTSUPP; - goto unmap_done; - } - - vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits + - ((h->h_clusterbits >> 5) & 7); -unmap_done: - kunmap_atomic(kaddr); - unlock_page(page); - put_page(page); - - set_bit(EROFS_V_Z_INITED_BIT, &vi->flags); -out_unlock: - clear_and_wake_up_bit(EROFS_V_BL_Z_BIT, &vi->flags); - return err; -} - -struct z_erofs_maprecorder { - struct inode *inode; - struct erofs_map_blocks *map; - void *kaddr; - - unsigned long lcn; - /* compression extent information gathered */ - u8 type; - u16 clusterofs; - u16 delta[2]; - erofs_blk_t pblk; -}; - -static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m, - erofs_blk_t eblk) -{ - struct super_block *const sb = m->inode->i_sb; - struct erofs_map_blocks *const map = m->map; - struct page *mpage = map->mpage; - - if (mpage) { - if (mpage->index == eblk) { - if (!m->kaddr) - m->kaddr = kmap_atomic(mpage); - return 0; - } - - if (m->kaddr) { - kunmap_atomic(m->kaddr); - m->kaddr = NULL; - } - put_page(mpage); - } - - mpage = erofs_get_meta_page(sb, eblk, false); - if (IS_ERR(mpage)) { - map->mpage = NULL; - return PTR_ERR(mpage); - } - m->kaddr = kmap_atomic(mpage); - unlock_page(mpage); - map->mpage = mpage; - return 0; -} - -static int vle_legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m, - unsigned long lcn) -{ - struct inode *const inode = m->inode; - struct erofs_vnode *const vi = EROFS_V(inode); - const erofs_off_t ibase = iloc(EROFS_I_SB(inode), vi->nid); - const erofs_off_t pos = - Z_EROFS_VLE_LEGACY_INDEX_ALIGN(ibase + vi->inode_isize + - vi->xattr_isize) + - lcn * sizeof(struct z_erofs_vle_decompressed_index); - struct z_erofs_vle_decompressed_index *di; - unsigned int advise, type; - int err; - - err = z_erofs_reload_indexes(m, erofs_blknr(pos)); - if (err) - return err; - - m->lcn = lcn; - di = m->kaddr + erofs_blkoff(pos); - - advise = le16_to_cpu(di->di_advise); - type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) & - ((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1); - switch (type) { - case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: - m->clusterofs = 1 << vi->z_logical_clusterbits; - m->delta[0] = le16_to_cpu(di->di_u.delta[0]); - m->delta[1] = le16_to_cpu(di->di_u.delta[1]); - break; - case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: - case Z_EROFS_VLE_CLUSTER_TYPE_HEAD: - m->clusterofs = le16_to_cpu(di->di_clusterofs); - m->pblk = le32_to_cpu(di->di_u.blkaddr); - break; - default: - DBG_BUGON(1); - return -EIO; - } - m->type = type; - return 0; -} - -static unsigned int decode_compactedbits(unsigned int lobits, - unsigned int lomask, - u8 *in, unsigned int pos, u8 *type) -{ - const unsigned int v = get_unaligned_le32(in + pos / 8) >> (pos & 7); - const unsigned int lo = v & lomask; - - *type = (v >> lobits) & 3; - return lo; -} - -static int unpack_compacted_index(struct z_erofs_maprecorder *m, - unsigned int amortizedshift, - unsigned int eofs) -{ - struct erofs_vnode *const vi = EROFS_V(m->inode); - const unsigned int lclusterbits = vi->z_logical_clusterbits; - const unsigned int lomask = (1 << lclusterbits) - 1; - unsigned int vcnt, base, lo, encodebits, nblk; - int i; - u8 *in, type; - - if (1 << amortizedshift == 4) - vcnt = 2; - else if (1 << amortizedshift == 2 && lclusterbits == 12) - vcnt = 16; - else - return -ENOTSUPP; - - encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt; - base = round_down(eofs, vcnt << amortizedshift); - in = m->kaddr + base; - - i = (eofs - base) >> amortizedshift; - - lo = decode_compactedbits(lclusterbits, lomask, - in, encodebits * i, &type); - m->type = type; - if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) { - m->clusterofs = 1 << lclusterbits; - if (i + 1 != vcnt) { - m->delta[0] = lo; - return 0; - } - /* - * since the last lcluster in the pack is special, - * of which lo saves delta[1] rather than delta[0]. - * Hence, get delta[0] by the previous lcluster indirectly. - */ - lo = decode_compactedbits(lclusterbits, lomask, - in, encodebits * (i - 1), &type); - if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) - lo = 0; - m->delta[0] = lo + 1; - return 0; - } - m->clusterofs = lo; - m->delta[0] = 0; - /* figout out blkaddr (pblk) for HEAD lclusters */ - nblk = 1; - while (i > 0) { - --i; - lo = decode_compactedbits(lclusterbits, lomask, - in, encodebits * i, &type); - if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) - i -= lo; - - if (i >= 0) - ++nblk; - } - in += (vcnt << amortizedshift) - sizeof(__le32); - m->pblk = le32_to_cpu(*(__le32 *)in) + nblk; - return 0; -} - -static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, - unsigned long lcn) -{ - struct inode *const inode = m->inode; - struct erofs_vnode *const vi = EROFS_V(inode); - const unsigned int lclusterbits = vi->z_logical_clusterbits; - const erofs_off_t ebase = ALIGN(iloc(EROFS_I_SB(inode), vi->nid) + - vi->inode_isize + vi->xattr_isize, 8) + - sizeof(struct z_erofs_map_header); - const unsigned int totalidx = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); - unsigned int compacted_4b_initial, compacted_2b; - unsigned int amortizedshift; - erofs_off_t pos; - int err; - - if (lclusterbits != 12) - return -ENOTSUPP; - - if (lcn >= totalidx) - return -EINVAL; - - m->lcn = lcn; - /* used to align to 32-byte (compacted_2b) alignment */ - compacted_4b_initial = (32 - ebase % 32) / 4; - if (compacted_4b_initial == 32 / 4) - compacted_4b_initial = 0; - - if (vi->z_advise & Z_EROFS_ADVISE_COMPACTED_2B) - compacted_2b = rounddown(totalidx - compacted_4b_initial, 16); - else - compacted_2b = 0; - - pos = ebase; - if (lcn < compacted_4b_initial) { - amortizedshift = 2; - goto out; - } - pos += compacted_4b_initial * 4; - lcn -= compacted_4b_initial; - - if (lcn < compacted_2b) { - amortizedshift = 1; - goto out; - } - pos += compacted_2b * 2; - lcn -= compacted_2b; - amortizedshift = 2; -out: - pos += lcn * (1 << amortizedshift); - err = z_erofs_reload_indexes(m, erofs_blknr(pos)); - if (err) - return err; - return unpack_compacted_index(m, amortizedshift, erofs_blkoff(pos)); -} - -static int vle_load_cluster_from_disk(struct z_erofs_maprecorder *m, - unsigned int lcn) -{ - const unsigned int datamode = EROFS_V(m->inode)->datamode; - - if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY) - return vle_legacy_load_cluster_from_disk(m, lcn); - - if (datamode == EROFS_INODE_FLAT_COMPRESSION) - return compacted_load_cluster_from_disk(m, lcn); - - return -EINVAL; -} - -static int vle_extent_lookback(struct z_erofs_maprecorder *m, - unsigned int lookback_distance) -{ - struct erofs_vnode *const vi = EROFS_V(m->inode); - struct erofs_map_blocks *const map = m->map; - const unsigned int lclusterbits = vi->z_logical_clusterbits; - unsigned long lcn = m->lcn; - int err; - - if (lcn < lookback_distance) { - DBG_BUGON(1); - return -EIO; - } - - /* load extent head logical cluster if needed */ - lcn -= lookback_distance; - err = vle_load_cluster_from_disk(m, lcn); - if (err) - return err; - - switch (m->type) { - case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: - return vle_extent_lookback(m, m->delta[0]); - case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: - map->m_flags &= ~EROFS_MAP_ZIPPED; - /* fallthrough */ - case Z_EROFS_VLE_CLUSTER_TYPE_HEAD: - map->m_la = (lcn << lclusterbits) | m->clusterofs; - break; - default: - errln("unknown type %u at lcn %lu of nid %llu", - m->type, lcn, vi->nid); - DBG_BUGON(1); - return -EIO; - } - return 0; -} - -int z_erofs_map_blocks_iter(struct inode *inode, - struct erofs_map_blocks *map, - int flags) -{ - struct erofs_vnode *const vi = EROFS_V(inode); - struct z_erofs_maprecorder m = { - .inode = inode, - .map = map, - }; - int err = 0; - unsigned int lclusterbits, endoff; - unsigned long long ofs, end; - - trace_z_erofs_map_blocks_iter_enter(inode, map, flags); - - /* when trying to read beyond EOF, leave it unmapped */ - if (unlikely(map->m_la >= inode->i_size)) { - map->m_llen = map->m_la + 1 - inode->i_size; - map->m_la = inode->i_size; - map->m_flags = 0; - goto out; - } - - err = fill_inode_lazy(inode); - if (err) - goto out; - - lclusterbits = vi->z_logical_clusterbits; - ofs = map->m_la; - m.lcn = ofs >> lclusterbits; - endoff = ofs & ((1 << lclusterbits) - 1); - - err = vle_load_cluster_from_disk(&m, m.lcn); - if (err) - goto unmap_out; - - map->m_flags = EROFS_MAP_ZIPPED; /* by default, compressed */ - end = (m.lcn + 1ULL) << lclusterbits; - - switch (m.type) { - case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: - if (endoff >= m.clusterofs) - map->m_flags &= ~EROFS_MAP_ZIPPED; - /* fallthrough */ - case Z_EROFS_VLE_CLUSTER_TYPE_HEAD: - if (endoff >= m.clusterofs) { - map->m_la = (m.lcn << lclusterbits) | m.clusterofs; - break; - } - /* m.lcn should be >= 1 if endoff < m.clusterofs */ - if (unlikely(!m.lcn)) { - errln("invalid logical cluster 0 at nid %llu", - vi->nid); - err = -EIO; - goto unmap_out; - } - end = (m.lcn << lclusterbits) | m.clusterofs; - map->m_flags |= EROFS_MAP_FULL_MAPPED; - m.delta[0] = 1; - /* fallthrough */ - case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: - /* get the correspoinding first chunk */ - err = vle_extent_lookback(&m, m.delta[0]); - if (unlikely(err)) - goto unmap_out; - break; - default: - errln("unknown type %u at offset %llu of nid %llu", - m.type, ofs, vi->nid); - err = -EIO; - goto unmap_out; - } - - map->m_llen = end - map->m_la; - map->m_plen = 1 << lclusterbits; - map->m_pa = blknr_to_addr(m.pblk); - map->m_flags |= EROFS_MAP_MAPPED; - -unmap_out: - if (m.kaddr) - kunmap_atomic(m.kaddr); - -out: - debugln("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o", - __func__, map->m_la, map->m_pa, - map->m_llen, map->m_plen, map->m_flags); - - trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err); - - /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */ - DBG_BUGON(err < 0 && err != -ENOMEM); - return err; -} - diff --git a/drivers/staging/exfat/Kconfig b/drivers/staging/exfat/Kconfig new file mode 100644 index 000000000000..290dbfc7ace1 --- /dev/null +++ b/drivers/staging/exfat/Kconfig @@ -0,0 +1,49 @@ +config EXFAT_FS + tristate "exFAT fs support" + depends on BLOCK + select NLS + help + This adds support for the exFAT file system. + +config EXFAT_DONT_MOUNT_VFAT + bool "Prohibit mounting of fat/vfat filesysems by exFAT" + depends on EXFAT_FS + default y + help + By default, the exFAT driver will only mount exFAT filesystems, and refuse + to mount fat/vfat filesystems. Set this to 'n' to allow the exFAT driver + to mount these filesystems. + +config EXFAT_DISCARD + bool "enable discard support" + depends on EXFAT_FS + default y + +config EXFAT_DELAYED_SYNC + bool "enable delayed sync" + depends on EXFAT_FS + default n + +config EXFAT_KERNEL_DEBUG + bool "enable kernel debug features via ioctl" + depends on EXFAT_FS + default n + +config EXFAT_DEBUG_MSG + bool "print debug messages" + depends on EXFAT_FS + default n + +config EXFAT_DEFAULT_CODEPAGE + int "Default codepage for exFAT" + default 437 + depends on EXFAT_FS + help + This option should be set to the codepage of your exFAT filesystems. + +config EXFAT_DEFAULT_IOCHARSET + string "Default iocharset for exFAT" + default "utf8" + depends on EXFAT_FS + help + Set this to the default input/output character set you'd like exFAT to use. diff --git a/drivers/staging/exfat/Makefile b/drivers/staging/exfat/Makefile new file mode 100644 index 000000000000..84944dfbae28 --- /dev/null +++ b/drivers/staging/exfat/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_EXFAT_FS) += exfat.o + +exfat-y := exfat_core.o \ + exfat_super.o \ + exfat_blkdev.o \ + exfat_cache.o \ + exfat_nls.o \ + exfat_upcase.o diff --git a/drivers/staging/exfat/TODO b/drivers/staging/exfat/TODO new file mode 100644 index 000000000000..a3eb282f9efc --- /dev/null +++ b/drivers/staging/exfat/TODO @@ -0,0 +1,12 @@ +exfat_core.c - ffsReadFile - the goto err_out seem to leak a brelse(). +same for ffsWriteFile. + +exfat_core.c - fs_sync(sb,0) all over the place looks fishy as hell. +There's only one place that calls it with a non-zero argument. + +ffsTruncateFile - if (old_size <= new_size) { +That doesn't look right. How did it ever work? Are they relying on lazy +block allocation when actual writes happen? If nothing else, it never +does the 'fid->size = new_size' and do the inode update.... + +ffsSetAttr() is just dangling in the breeze, not wired up at all... diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h new file mode 100644 index 000000000000..6c12f2d79f4d --- /dev/null +++ b/drivers/staging/exfat/exfat.h @@ -0,0 +1,971 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#ifndef _EXFAT_H +#define _EXFAT_H + +#include <linux/types.h> +#include <linux/buffer_head.h> + +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + /* For Debugging Purpose */ + /* IOCTL code 'f' used by + * - file systems typically #0~0x1F + * - embedded terminal devices #128~ + * - exts for debugging purpose #99 + * number 100 and 101 is available now but has possible conflicts + */ +#define EXFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long) +#define EXFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long) + +#define EXFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01 +#define EXFAT_DEBUGFLAGS_ERROR_RW 0x02 +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + +#ifdef CONFIG_EXFAT_DEBUG_MSG +#define DEBUG 1 +#else +#undef DEBUG +#endif + +#define DENTRY_SIZE 32 /* dir entry size */ +#define DENTRY_SIZE_BITS 5 + +/* PBR entries */ +#define PBR_SIGNATURE 0xAA55 +#define EXT_SIGNATURE 0xAA550000 +#define VOL_LABEL "NO NAME " /* size should be 11 */ +#define OEM_NAME "MSWIN4.1" /* size should be 8 */ +#define STR_FAT12 "FAT12 " /* size should be 8 */ +#define STR_FAT16 "FAT16 " /* size should be 8 */ +#define STR_FAT32 "FAT32 " /* size should be 8 */ +#define STR_EXFAT "EXFAT " /* size should be 8 */ +#define VOL_CLEAN 0x0000 +#define VOL_DIRTY 0x0002 + +/* max number of clusters */ +#define FAT12_THRESHOLD 4087 /* 2^12 - 1 + 2 (clu 0 & 1) */ +#define FAT16_THRESHOLD 65527 /* 2^16 - 1 + 2 */ +#define FAT32_THRESHOLD 268435457 /* 2^28 - 1 + 2 */ +#define EXFAT_THRESHOLD 268435457 /* 2^28 - 1 + 2 */ + +/* file types */ +#define TYPE_UNUSED 0x0000 +#define TYPE_DELETED 0x0001 +#define TYPE_INVALID 0x0002 +#define TYPE_CRITICAL_PRI 0x0100 +#define TYPE_BITMAP 0x0101 +#define TYPE_UPCASE 0x0102 +#define TYPE_VOLUME 0x0103 +#define TYPE_DIR 0x0104 +#define TYPE_FILE 0x011F +#define TYPE_SYMLINK 0x015F +#define TYPE_CRITICAL_SEC 0x0200 +#define TYPE_STREAM 0x0201 +#define TYPE_EXTEND 0x0202 +#define TYPE_ACL 0x0203 +#define TYPE_BENIGN_PRI 0x0400 +#define TYPE_GUID 0x0401 +#define TYPE_PADDING 0x0402 +#define TYPE_ACLTAB 0x0403 +#define TYPE_BENIGN_SEC 0x0800 +#define TYPE_ALL 0x0FFF + +/* time modes */ +#define TM_CREATE 0 +#define TM_MODIFY 1 +#define TM_ACCESS 2 + +/* checksum types */ +#define CS_DIR_ENTRY 0 +#define CS_PBR_SECTOR 1 +#define CS_DEFAULT 2 + +#define CLUSTER_16(x) ((u16)(x)) +#define CLUSTER_32(x) ((u32)(x)) + +#define START_SECTOR(x) \ + ((((sector_t)((x) - 2)) << p_fs->sectors_per_clu_bits) + \ + p_fs->data_start_sector) + +#define IS_LAST_SECTOR_IN_CLUSTER(sec) \ + ((((sec) - p_fs->data_start_sector + 1) & \ + ((1 << p_fs->sectors_per_clu_bits) - 1)) == 0) + +#define GET_CLUSTER_FROM_SECTOR(sec) \ + ((u32)((((sec) - p_fs->data_start_sector) >> \ + p_fs->sectors_per_clu_bits) + 2)) + +#define GET16(p_src) \ + (((u16)(p_src)[0]) | (((u16)(p_src)[1]) << 8)) +#define GET32(p_src) \ + (((u32)(p_src)[0]) | (((u32)(p_src)[1]) << 8) | \ + (((u32)(p_src)[2]) << 16) | (((u32)(p_src)[3]) << 24)) +#define GET64(p_src) \ + (((u64)(p_src)[0]) | (((u64)(p_src)[1]) << 8) | \ + (((u64)(p_src)[2]) << 16) | (((u64)(p_src)[3]) << 24) | \ + (((u64)(p_src)[4]) << 32) | (((u64)(p_src)[5]) << 40) | \ + (((u64)(p_src)[6]) << 48) | (((u64)(p_src)[7]) << 56)) + +#define SET16(p_dst, src) \ + do { \ + (p_dst)[0] = (u8)(src); \ + (p_dst)[1] = (u8)(((u16)(src)) >> 8); \ + } while (0) +#define SET32(p_dst, src) \ + do { \ + (p_dst)[0] = (u8)(src); \ + (p_dst)[1] = (u8)(((u32)(src)) >> 8); \ + (p_dst)[2] = (u8)(((u32)(src)) >> 16); \ + (p_dst)[3] = (u8)(((u32)(src)) >> 24); \ + } while (0) +#define SET64(p_dst, src) \ + do { \ + (p_dst)[0] = (u8)(src); \ + (p_dst)[1] = (u8)(((u64)(src)) >> 8); \ + (p_dst)[2] = (u8)(((u64)(src)) >> 16); \ + (p_dst)[3] = (u8)(((u64)(src)) >> 24); \ + (p_dst)[4] = (u8)(((u64)(src)) >> 32); \ + (p_dst)[5] = (u8)(((u64)(src)) >> 40); \ + (p_dst)[6] = (u8)(((u64)(src)) >> 48); \ + (p_dst)[7] = (u8)(((u64)(src)) >> 56); \ + } while (0) + +#ifdef __LITTLE_ENDIAN +#define GET16_A(p_src) (*((u16 *)(p_src))) +#define GET32_A(p_src) (*((u32 *)(p_src))) +#define GET64_A(p_src) (*((u64 *)(p_src))) +#define SET16_A(p_dst, src) (*((u16 *)(p_dst)) = (u16)(src)) +#define SET32_A(p_dst, src) (*((u32 *)(p_dst)) = (u32)(src)) +#define SET64_A(p_dst, src) (*((u64 *)(p_dst)) = (u64)(src)) +#else /* BIG_ENDIAN */ +#define GET16_A(p_src) GET16(p_src) +#define GET32_A(p_src) GET32(p_src) +#define GET64_A(p_src) GET64(p_src) +#define SET16_A(p_dst, src) SET16(p_dst, src) +#define SET32_A(p_dst, src) SET32(p_dst, src) +#define SET64_A(p_dst, src) SET64(p_dst, src) +#endif + +/* cache size (in number of sectors) */ +/* (should be an exponential value of 2) */ +#define FAT_CACHE_SIZE 128 +#define FAT_CACHE_HASH_SIZE 64 +#define BUF_CACHE_SIZE 256 +#define BUF_CACHE_HASH_SIZE 64 + +/* Upcase table macro */ +#define HIGH_INDEX_BIT (8) +#define HIGH_INDEX_MASK (0xFF00) +#define LOW_INDEX_BIT (16 - HIGH_INDEX_BIT) +#define UTBL_ROW_COUNT BIT(LOW_INDEX_BIT) +#define UTBL_COL_COUNT BIT(HIGH_INDEX_BIT) + +static inline u16 get_col_index(u16 i) +{ + return i >> LOW_INDEX_BIT; +} + +static inline u16 get_row_index(u16 i) +{ + return i & ~HIGH_INDEX_MASK; +} + +#define EXFAT_SUPER_MAGIC (0x2011BAB0L) +#define EXFAT_ROOT_INO 1 + +/* FAT types */ +#define FAT12 0x01 /* FAT12 */ +#define FAT16 0x0E /* Win95 FAT16 (LBA) */ +#define FAT32 0x0C /* Win95 FAT32 (LBA) */ +#define EXFAT 0x07 /* exFAT */ + +/* file name lengths */ +#define MAX_CHARSET_SIZE 3 /* max size of multi-byte character */ +#define MAX_PATH_DEPTH 15 /* max depth of path name */ +#define MAX_NAME_LENGTH 256 /* max len of filename including NULL */ +#define MAX_PATH_LENGTH 260 /* max len of pathname including NULL */ +#define DOS_NAME_LENGTH 11 /* DOS filename length excluding NULL */ +#define DOS_PATH_LENGTH 80 /* DOS pathname length excluding NULL */ + +/* file attributes */ +#define ATTR_NORMAL 0x0000 +#define ATTR_READONLY 0x0001 +#define ATTR_HIDDEN 0x0002 +#define ATTR_SYSTEM 0x0004 +#define ATTR_VOLUME 0x0008 +#define ATTR_SUBDIR 0x0010 +#define ATTR_ARCHIVE 0x0020 +#define ATTR_SYMLINK 0x0040 +#define ATTR_EXTEND 0x000F +#define ATTR_RWMASK 0x007E + +/* file creation modes */ +#define FM_REGULAR 0x00 +#define FM_SYMLINK 0x40 + +/* return values */ +#define FFS_SUCCESS 0 +#define FFS_MEDIAERR 1 +#define FFS_FORMATERR 2 +#define FFS_MOUNTED 3 +#define FFS_NOTMOUNTED 4 +#define FFS_ALIGNMENTERR 5 +#define FFS_SEMAPHOREERR 6 +#define FFS_INVALIDPATH 7 +#define FFS_INVALIDFID 8 +#define FFS_NOTFOUND 9 +#define FFS_FILEEXIST 10 +#define FFS_PERMISSIONERR 11 +#define FFS_NOTOPENED 12 +#define FFS_MAXOPENED 13 +#define FFS_FULL 14 +#define FFS_EOF 15 +#define FFS_DIRBUSY 16 +#define FFS_MEMORYERR 17 +#define FFS_NAMETOOLONG 18 +#define FFS_ERROR 19 + +#define NUM_UPCASE 2918 + +#define DOS_CUR_DIR_NAME ". " +#define DOS_PAR_DIR_NAME ".. " + +#ifdef __LITTLE_ENDIAN +#define UNI_CUR_DIR_NAME ".\0" +#define UNI_PAR_DIR_NAME ".\0.\0" +#else +#define UNI_CUR_DIR_NAME "\0." +#define UNI_PAR_DIR_NAME "\0.\0." +#endif + +struct date_time_t { + u16 Year; + u16 Month; + u16 Day; + u16 Hour; + u16 Minute; + u16 Second; + u16 MilliSecond; +}; + +struct part_info_t { + u32 Offset; /* start sector number of the partition */ + u32 Size; /* in sectors */ +}; + +struct dev_info_t { + u32 SecSize; /* sector size in bytes */ + u32 DevSize; /* block device size in sectors */ +}; + +struct vol_info_t { + u32 FatType; + u32 ClusterSize; + u32 NumClusters; + u32 FreeClusters; + u32 UsedClusters; +}; + +/* directory structure */ +struct chain_t { + u32 dir; + s32 size; + u8 flags; +}; + +struct file_id_t { + struct chain_t dir; + s32 entry; + u32 type; + u32 attr; + u32 start_clu; + u64 size; + u8 flags; + s64 rwoffset; + s32 hint_last_off; + u32 hint_last_clu; +}; + +struct dir_entry_t { + char Name[MAX_NAME_LENGTH * MAX_CHARSET_SIZE]; + + /* used only for FAT12/16/32, not used for exFAT */ + char ShortName[DOS_NAME_LENGTH + 2]; + + u32 Attr; + u64 Size; + u32 NumSubdirs; + struct date_time_t CreateTimestamp; + struct date_time_t ModifyTimestamp; + struct date_time_t AccessTimestamp; +}; + +struct timestamp_t { + u16 sec; /* 0 ~ 59 */ + u16 min; /* 0 ~ 59 */ + u16 hour; /* 0 ~ 23 */ + u16 day; /* 1 ~ 31 */ + u16 mon; /* 1 ~ 12 */ + u16 year; /* 0 ~ 127 (since 1980) */ +}; + +/* MS_DOS FAT partition boot record (512 bytes) */ +struct pbr_sector_t { + u8 jmp_boot[3]; + u8 oem_name[8]; + u8 bpb[109]; + u8 boot_code[390]; + u8 signature[2]; +}; + +/* MS-DOS FAT12/16 BIOS parameter block (51 bytes) */ +struct bpb16_t { + u8 sector_size[2]; + u8 sectors_per_clu; + u8 num_reserved[2]; + u8 num_fats; + u8 num_root_entries[2]; + u8 num_sectors[2]; + u8 media_type; + u8 num_fat_sectors[2]; + u8 sectors_in_track[2]; + u8 num_heads[2]; + u8 num_hid_sectors[4]; + u8 num_huge_sectors[4]; + + u8 phy_drv_no; + u8 reserved; + u8 ext_signature; + u8 vol_serial[4]; + u8 vol_label[11]; + u8 vol_type[8]; +}; + +/* MS-DOS FAT32 BIOS parameter block (79 bytes) */ +struct bpb32_t { + u8 sector_size[2]; + u8 sectors_per_clu; + u8 num_reserved[2]; + u8 num_fats; + u8 num_root_entries[2]; + u8 num_sectors[2]; + u8 media_type; + u8 num_fat_sectors[2]; + u8 sectors_in_track[2]; + u8 num_heads[2]; + u8 num_hid_sectors[4]; + u8 num_huge_sectors[4]; + u8 num_fat32_sectors[4]; + u8 ext_flags[2]; + u8 fs_version[2]; + u8 root_cluster[4]; + u8 fsinfo_sector[2]; + u8 backup_sector[2]; + u8 reserved[12]; + + u8 phy_drv_no; + u8 ext_reserved; + u8 ext_signature; + u8 vol_serial[4]; + u8 vol_label[11]; + u8 vol_type[8]; +}; + +/* MS-DOS EXFAT BIOS parameter block (109 bytes) */ +struct bpbex_t { + u8 reserved1[53]; + u8 vol_offset[8]; + u8 vol_length[8]; + u8 fat_offset[4]; + u8 fat_length[4]; + u8 clu_offset[4]; + u8 clu_count[4]; + u8 root_cluster[4]; + u8 vol_serial[4]; + u8 fs_version[2]; + u8 vol_flags[2]; + u8 sector_size_bits; + u8 sectors_per_clu_bits; + u8 num_fats; + u8 phy_drv_no; + u8 perc_in_use; + u8 reserved2[7]; +}; + +/* MS-DOS FAT file system information sector (512 bytes) */ +struct fsi_sector_t { + u8 signature1[4]; + u8 reserved1[480]; + u8 signature2[4]; + u8 free_cluster[4]; + u8 next_cluster[4]; + u8 reserved2[14]; + u8 signature3[2]; +}; + +/* MS-DOS FAT directory entry (32 bytes) */ +struct dentry_t { + u8 dummy[32]; +}; + +struct dos_dentry_t { + u8 name[DOS_NAME_LENGTH]; + u8 attr; + u8 lcase; + u8 create_time_ms; + u8 create_time[2]; + u8 create_date[2]; + u8 access_date[2]; + u8 start_clu_hi[2]; + u8 modify_time[2]; + u8 modify_date[2]; + u8 start_clu_lo[2]; + u8 size[4]; +}; + +/* MS-DOS FAT extended directory entry (32 bytes) */ +struct ext_dentry_t { + u8 order; + u8 unicode_0_4[10]; + u8 attr; + u8 sysid; + u8 checksum; + u8 unicode_5_10[12]; + u8 start_clu[2]; + u8 unicode_11_12[4]; +}; + +/* MS-DOS EXFAT file directory entry (32 bytes) */ +struct file_dentry_t { + u8 type; + u8 num_ext; + u8 checksum[2]; + u8 attr[2]; + u8 reserved1[2]; + u8 create_time[2]; + u8 create_date[2]; + u8 modify_time[2]; + u8 modify_date[2]; + u8 access_time[2]; + u8 access_date[2]; + u8 create_time_ms; + u8 modify_time_ms; + u8 access_time_ms; + u8 reserved2[9]; +}; + +/* MS-DOS EXFAT stream extension directory entry (32 bytes) */ +struct strm_dentry_t { + u8 type; + u8 flags; + u8 reserved1; + u8 name_len; + u8 name_hash[2]; + u8 reserved2[2]; + u8 valid_size[8]; + u8 reserved3[4]; + u8 start_clu[4]; + u8 size[8]; +}; + +/* MS-DOS EXFAT file name directory entry (32 bytes) */ +struct name_dentry_t { + u8 type; + u8 flags; + u8 unicode_0_14[30]; +}; + +/* MS-DOS EXFAT allocation bitmap directory entry (32 bytes) */ +struct bmap_dentry_t { + u8 type; + u8 flags; + u8 reserved[18]; + u8 start_clu[4]; + u8 size[8]; +}; + +/* MS-DOS EXFAT up-case table directory entry (32 bytes) */ +struct case_dentry_t { + u8 type; + u8 reserved1[3]; + u8 checksum[4]; + u8 reserved2[12]; + u8 start_clu[4]; + u8 size[8]; +}; + +/* MS-DOS EXFAT volume label directory entry (32 bytes) */ +struct volm_dentry_t { + u8 type; + u8 label_len; + u8 unicode_0_10[22]; + u8 reserved[8]; +}; + +/* unused entry hint information */ +struct uentry_t { + u32 dir; + s32 entry; + struct chain_t clu; +}; + +/* DOS name structure */ +struct dos_name_t { + u8 name[DOS_NAME_LENGTH]; + u8 name_case; +}; + +/* unicode name structure */ +struct uni_name_t { + u16 name[MAX_NAME_LENGTH]; + u16 name_hash; + u8 name_len; +}; + +struct buf_cache_t { + struct buf_cache_t *next; + struct buf_cache_t *prev; + struct buf_cache_t *hash_next; + struct buf_cache_t *hash_prev; + s32 drv; + sector_t sec; + u32 flag; + struct buffer_head *buf_bh; +}; + +struct fs_func { + s32 (*alloc_cluster)(struct super_block *sb, s32 num_alloc, + struct chain_t *p_chain); + void (*free_cluster)(struct super_block *sb, struct chain_t *p_chain, + s32 do_relse); + s32 (*count_used_clusters)(struct super_block *sb); + + s32 (*init_dir_entry)(struct super_block *sb, struct chain_t *p_dir, + s32 entry, u32 type, u32 start_clu, u64 size); + s32 (*init_ext_entry)(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 num_entries, + struct uni_name_t *p_uniname, + struct dos_name_t *p_dosname); + s32 (*find_dir_entry)(struct super_block *sb, struct chain_t *p_dir, + struct uni_name_t *p_uniname, s32 num_entries, + struct dos_name_t *p_dosname, u32 type); + void (*delete_dir_entry)(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + s32 offset, s32 num_entries); + void (*get_uni_name_from_ext_entry)(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + u16 *uniname); + s32 (*count_ext_entries)(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + struct dentry_t *p_entry); + s32 (*calc_num_entries)(struct uni_name_t *p_uniname); + + u32 (*get_entry_type)(struct dentry_t *p_entry); + void (*set_entry_type)(struct dentry_t *p_entry, u32 type); + u32 (*get_entry_attr)(struct dentry_t *p_entry); + void (*set_entry_attr)(struct dentry_t *p_entry, u32 attr); + u8 (*get_entry_flag)(struct dentry_t *p_entry); + void (*set_entry_flag)(struct dentry_t *p_entry, u8 flag); + u32 (*get_entry_clu0)(struct dentry_t *p_entry); + void (*set_entry_clu0)(struct dentry_t *p_entry, u32 clu0); + u64 (*get_entry_size)(struct dentry_t *p_entry); + void (*set_entry_size)(struct dentry_t *p_entry, u64 size); + void (*get_entry_time)(struct dentry_t *p_entry, + struct timestamp_t *tp, u8 mode); + void (*set_entry_time)(struct dentry_t *p_entry, + struct timestamp_t *tp, u8 mode); +}; + +struct fs_info_t { + u32 drv; /* drive ID */ + u32 vol_type; /* volume FAT type */ + u32 vol_id; /* volume serial number */ + + u64 num_sectors; /* num of sectors in volume */ + u32 num_clusters; /* num of clusters in volume */ + u32 cluster_size; /* cluster size in bytes */ + u32 cluster_size_bits; + u32 sectors_per_clu; /* cluster size in sectors */ + u32 sectors_per_clu_bits; + + u32 PBR_sector; /* PBR sector */ + u32 FAT1_start_sector; /* FAT1 start sector */ + u32 FAT2_start_sector; /* FAT2 start sector */ + u32 root_start_sector; /* root dir start sector */ + u32 data_start_sector; /* data area start sector */ + u32 num_FAT_sectors; /* num of FAT sectors */ + + u32 root_dir; /* root dir cluster */ + u32 dentries_in_root; /* num of dentries in root dir */ + u32 dentries_per_clu; /* num of dentries per cluster */ + + u32 vol_flag; /* volume dirty flag */ + struct buffer_head *pbr_bh; /* PBR sector */ + + u32 map_clu; /* allocation bitmap start cluster */ + u32 map_sectors; /* num of allocation bitmap sectors */ + struct buffer_head **vol_amap; /* allocation bitmap */ + + u16 **vol_utbl; /* upcase table */ + + u32 clu_srch_ptr; /* cluster search pointer */ + u32 used_clusters; /* number of used clusters */ + struct uentry_t hint_uentry; /* unused entry hint information */ + + u32 dev_ejected; /* block device operation error flag */ + + struct fs_func *fs_func; + struct semaphore v_sem; + + /* FAT cache */ + struct buf_cache_t FAT_cache_array[FAT_CACHE_SIZE]; + struct buf_cache_t FAT_cache_lru_list; + struct buf_cache_t FAT_cache_hash_list[FAT_CACHE_HASH_SIZE]; + + /* buf cache */ + struct buf_cache_t buf_cache_array[BUF_CACHE_SIZE]; + struct buf_cache_t buf_cache_lru_list; + struct buf_cache_t buf_cache_hash_list[BUF_CACHE_HASH_SIZE]; +}; + +#define ES_2_ENTRIES 2 +#define ES_3_ENTRIES 3 +#define ES_ALL_ENTRIES 0 + +struct entry_set_cache_t { + /* sector number that contains file_entry */ + sector_t sector; + + /* byte offset in the sector */ + s32 offset; + + /* + * flag in stream entry. + * 01 for cluster chain, + * 03 for contig. clusteres. + */ + s32 alloc_flag; + + u32 num_entries; + + /* __buf should be the last member */ + void *__buf; +}; + +#define EXFAT_ERRORS_CONT 1 /* ignore error and continue */ +#define EXFAT_ERRORS_PANIC 2 /* panic on error */ +#define EXFAT_ERRORS_RO 3 /* remount r/o on error */ + +/* ioctl command */ +#define EXFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32) + +struct exfat_mount_options { + kuid_t fs_uid; + kgid_t fs_gid; + unsigned short fs_fmask; + unsigned short fs_dmask; + + /* permission for setting the [am]time */ + unsigned short allow_utime; + + /* codepage for shortname conversions */ + unsigned short codepage; + + /* charset for filename input/display */ + char *iocharset; + + unsigned char casesensitive; + + /* on error: continue, panic, remount-ro */ + unsigned char errors; +#ifdef CONFIG_EXFAT_DISCARD + /* flag on if -o dicard specified and device support discard() */ + unsigned char discard; +#endif /* CONFIG_EXFAT_DISCARD */ +}; + +#define EXFAT_HASH_BITS 8 +#define EXFAT_HASH_SIZE BIT(EXFAT_HASH_BITS) + +/* + * EXFAT file system in-core superblock data + */ +struct bd_info_t { + s32 sector_size; /* in bytes */ + s32 sector_size_bits; + s32 sector_size_mask; + + /* total number of sectors in this block device */ + s32 num_sectors; + + /* opened or not */ + bool opened; +}; + +struct exfat_sb_info { + struct fs_info_t fs_info; + struct bd_info_t bd_info; + + struct exfat_mount_options options; + + int s_dirt; + struct mutex s_lock; + struct nls_table *nls_disk; /* Codepage used on disk */ + struct nls_table *nls_io; /* Charset used for input and display */ + + struct inode *fat_inode; + + spinlock_t inode_hash_lock; + struct hlist_head inode_hashtable[EXFAT_HASH_SIZE]; +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + long debug_flags; +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ +}; + +/* + * EXFAT file system inode data in memory + */ +struct exfat_inode_info { + struct file_id_t fid; + char *target; + /* NOTE: mmu_private is 64bits, so must hold ->i_mutex to access */ + loff_t mmu_private; /* physically allocated size */ + loff_t i_pos; /* on-disk position of directory entry or 0 */ + struct hlist_node i_hash_fat; /* hash by i_location */ + struct rw_semaphore truncate_lock; + struct inode vfs_inode; + struct rw_semaphore i_alloc_sem; /* protect bmap against truncate */ +}; + +#define EXFAT_SB(sb) ((struct exfat_sb_info *)((sb)->s_fs_info)) + +static inline struct exfat_inode_info *EXFAT_I(struct inode *inode) +{ + return container_of(inode, struct exfat_inode_info, vfs_inode); +} + +/* NLS management function */ +u16 nls_upper(struct super_block *sb, u16 a); +int nls_dosname_cmp(struct super_block *sb, u8 *a, u8 *b); +int nls_uniname_cmp(struct super_block *sb, u16 *a, u16 *b); +void nls_uniname_to_dosname(struct super_block *sb, + struct dos_name_t *p_dosname, + struct uni_name_t *p_uniname, bool *p_lossy); +void nls_dosname_to_uniname(struct super_block *sb, + struct uni_name_t *p_uniname, + struct dos_name_t *p_dosname); +void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring, + struct uni_name_t *p_uniname); +void nls_cstring_to_uniname(struct super_block *sb, + struct uni_name_t *p_uniname, u8 *p_cstring, + bool *p_lossy); + +/* buffer cache management */ +void buf_init(struct super_block *sb); +void buf_shutdown(struct super_block *sb); +int FAT_read(struct super_block *sb, u32 loc, u32 *content); +s32 FAT_write(struct super_block *sb, u32 loc, u32 content); +u8 *FAT_getblk(struct super_block *sb, sector_t sec); +void FAT_modify(struct super_block *sb, sector_t sec); +void FAT_release_all(struct super_block *sb); +void FAT_sync(struct super_block *sb); +u8 *buf_getblk(struct super_block *sb, sector_t sec); +void buf_modify(struct super_block *sb, sector_t sec); +void buf_lock(struct super_block *sb, sector_t sec); +void buf_unlock(struct super_block *sb, sector_t sec); +void buf_release(struct super_block *sb, sector_t sec); +void buf_release_all(struct super_block *sb); +void buf_sync(struct super_block *sb); + +/* fs management functions */ +void fs_set_vol_flags(struct super_block *sb, u32 new_flag); +void fs_error(struct super_block *sb); + +/* cluster management functions */ +s32 clear_cluster(struct super_block *sb, u32 clu); +s32 fat_alloc_cluster(struct super_block *sb, s32 num_alloc, + struct chain_t *p_chain); +s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc, + struct chain_t *p_chain); +void fat_free_cluster(struct super_block *sb, struct chain_t *p_chain, + s32 do_relse); +void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain, + s32 do_relse); +u32 find_last_cluster(struct super_block *sb, struct chain_t *p_chain); +s32 count_num_clusters(struct super_block *sb, struct chain_t *dir); +s32 fat_count_used_clusters(struct super_block *sb); +s32 exfat_count_used_clusters(struct super_block *sb); +void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len); + +/* allocation bitmap management functions */ +s32 load_alloc_bitmap(struct super_block *sb); +void free_alloc_bitmap(struct super_block *sb); +s32 set_alloc_bitmap(struct super_block *sb, u32 clu); +s32 clr_alloc_bitmap(struct super_block *sb, u32 clu); +u32 test_alloc_bitmap(struct super_block *sb, u32 clu); +void sync_alloc_bitmap(struct super_block *sb); + +/* upcase table management functions */ +s32 load_upcase_table(struct super_block *sb); +void free_upcase_table(struct super_block *sb); + +/* dir entry management functions */ +u32 fat_get_entry_type(struct dentry_t *p_entry); +u32 exfat_get_entry_type(struct dentry_t *p_entry); +void fat_set_entry_type(struct dentry_t *p_entry, u32 type); +void exfat_set_entry_type(struct dentry_t *p_entry, u32 type); +u32 fat_get_entry_attr(struct dentry_t *p_entry); +u32 exfat_get_entry_attr(struct dentry_t *p_entry); +void fat_set_entry_attr(struct dentry_t *p_entry, u32 attr); +void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr); +u8 fat_get_entry_flag(struct dentry_t *p_entry); +u8 exfat_get_entry_flag(struct dentry_t *p_entry); +void fat_set_entry_flag(struct dentry_t *p_entry, u8 flag); +void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flag); +u32 fat_get_entry_clu0(struct dentry_t *p_entry); +u32 exfat_get_entry_clu0(struct dentry_t *p_entry); +void fat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu); +void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu); +u64 fat_get_entry_size(struct dentry_t *p_entry); +u64 exfat_get_entry_size(struct dentry_t *p_entry); +void fat_set_entry_size(struct dentry_t *p_entry, u64 size); +void exfat_set_entry_size(struct dentry_t *p_entry, u64 size); +struct timestamp_t *tm_current(struct timestamp_t *tm); +void fat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode); +void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode); +void fat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode); +void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode); +s32 fat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir, s32 entry, + u32 type, u32 start_clu, u64 size); +s32 exfat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, u32 type, u32 start_clu, u64 size); +s32 fat_init_ext_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 num_entries, + struct uni_name_t *p_uniname, + struct dos_name_t *p_dosname); +s32 exfat_init_ext_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 num_entries, + struct uni_name_t *p_uniname, + struct dos_name_t *p_dosname); +void init_dos_entry(struct dos_dentry_t *ep, u32 type, u32 start_clu); +void init_ext_entry(struct ext_dentry_t *ep, s32 order, u8 chksum, + u16 *uniname); +void init_file_entry(struct file_dentry_t *ep, u32 type); +void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu, + u64 size); +void init_name_entry(struct name_dentry_t *ep, u16 *uniname); +void fat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 order, s32 num_entries); +void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 order, s32 num_entries); + +s32 find_location(struct super_block *sb, struct chain_t *p_dir, s32 entry, + sector_t *sector, s32 *offset); +struct dentry_t *get_entry_with_sector(struct super_block *sb, sector_t sector, + s32 offset); +struct dentry_t *get_entry_in_dir(struct super_block *sb, struct chain_t *p_dir, + s32 entry, sector_t *sector); +struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + u32 type, + struct dentry_t **file_ep); +void release_entry_set(struct entry_set_cache_t *es); +s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es); +s32 write_partial_entries_in_entry_set(struct super_block *sb, + struct entry_set_cache_t *es, + struct dentry_t *ep, u32 count); +s32 search_deleted_or_unused_entry(struct super_block *sb, + struct chain_t *p_dir, s32 num_entries); +s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, + s32 num_entries); +s32 fat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir, + struct uni_name_t *p_uniname, s32 num_entries, + struct dos_name_t *p_dosname, u32 type); +s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir, + struct uni_name_t *p_uniname, s32 num_entries, + struct dos_name_t *p_dosname, u32 type); +s32 fat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir, + s32 entry, struct dentry_t *p_entry); +s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir, + s32 entry, struct dentry_t *p_entry); +s32 count_dos_name_entries(struct super_block *sb, struct chain_t *p_dir, + u32 type); +void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir, + s32 entry); +void update_dir_checksum_with_entry_set(struct super_block *sb, + struct entry_set_cache_t *es); +bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir); + +/* name conversion functions */ +s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir, + struct uni_name_t *p_uniname, s32 *entries, + struct dos_name_t *p_dosname); +void get_uni_name_from_dos_entry(struct super_block *sb, + struct dos_dentry_t *ep, + struct uni_name_t *p_uniname, u8 mode); +void fat_get_uni_name_from_ext_entry(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + u16 *uniname); +void exfat_get_uni_name_from_ext_entry(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + u16 *uniname); +s32 extract_uni_name_from_ext_entry(struct ext_dentry_t *ep, + u16 *uniname, s32 order); +s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, + u16 *uniname, s32 order); +s32 fat_generate_dos_name(struct super_block *sb, struct chain_t *p_dir, + struct dos_name_t *p_dosname); +void fat_attach_count_to_dos_name(u8 *dosname, s32 count); +s32 fat_calc_num_entries(struct uni_name_t *p_uniname); +s32 exfat_calc_num_entries(struct uni_name_t *p_uniname); +u8 calc_checksum_1byte(void *data, s32 len, u8 chksum); +u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type); +u32 calc_checksum_4byte(void *data, s32 len, u32 chksum, s32 type); + +/* name resolution functions */ +s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir, + struct uni_name_t *p_uniname); +s32 resolve_name(u8 *name, u8 **arg); + +/* file operation functions */ +s32 fat16_mount(struct super_block *sb, struct pbr_sector_t *p_pbr); +s32 fat32_mount(struct super_block *sb, struct pbr_sector_t *p_pbr); +s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr); +s32 create_dir(struct inode *inode, struct chain_t *p_dir, + struct uni_name_t *p_uniname, struct file_id_t *fid); +s32 create_file(struct inode *inode, struct chain_t *p_dir, + struct uni_name_t *p_uniname, u8 mode, struct file_id_t *fid); +void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry); +s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry, + struct uni_name_t *p_uniname, struct file_id_t *fid); +s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry, + struct chain_t *p_newdir, struct uni_name_t *p_uniname, + struct file_id_t *fid); + +/* sector read/write functions */ +int sector_read(struct super_block *sb, sector_t sec, + struct buffer_head **bh, bool read); +int sector_write(struct super_block *sb, sector_t sec, + struct buffer_head *bh, bool sync); +int multi_sector_read(struct super_block *sb, sector_t sec, + struct buffer_head **bh, s32 num_secs, bool read); +int multi_sector_write(struct super_block *sb, sector_t sec, + struct buffer_head *bh, s32 num_secs, bool sync); + +void bdev_open(struct super_block *sb); +void bdev_close(struct super_block *sb); +int bdev_read(struct super_block *sb, sector_t secno, + struct buffer_head **bh, u32 num_secs, bool read); +int bdev_write(struct super_block *sb, sector_t secno, + struct buffer_head *bh, u32 num_secs, bool sync); +int bdev_sync(struct super_block *sb); + +extern const u8 uni_upcase[]; +#endif /* _EXFAT_H */ diff --git a/drivers/staging/exfat/exfat_blkdev.c b/drivers/staging/exfat/exfat_blkdev.c new file mode 100644 index 000000000000..f086c75e7076 --- /dev/null +++ b/drivers/staging/exfat/exfat_blkdev.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include <linux/blkdev.h> +#include <linux/buffer_head.h> +#include <linux/fs.h> +#include "exfat.h" + +void bdev_open(struct super_block *sb) +{ + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bd->opened) + return; + + p_bd->sector_size = bdev_logical_block_size(sb->s_bdev); + p_bd->sector_size_bits = ilog2(p_bd->sector_size); + p_bd->sector_size_mask = p_bd->sector_size - 1; + p_bd->num_sectors = i_size_read(sb->s_bdev->bd_inode) >> + p_bd->sector_size_bits; + p_bd->opened = true; +} + +void bdev_close(struct super_block *sb) +{ + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + p_bd->opened = false; +} + +int bdev_read(struct super_block *sb, sector_t secno, struct buffer_head **bh, + u32 num_secs, bool read) +{ + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + struct exfat_sb_info *sbi = EXFAT_SB(sb); + long flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) + return FFS_MEDIAERR; +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + + if (!p_bd->opened) + return FFS_MEDIAERR; + + if (*bh) + __brelse(*bh); + + if (read) + *bh = __bread(sb->s_bdev, secno, + num_secs << p_bd->sector_size_bits); + else + *bh = __getblk(sb->s_bdev, secno, + num_secs << p_bd->sector_size_bits); + + if (*bh) + return 0; + + WARN(!p_fs->dev_ejected, + "[EXFAT] No bh, device seems wrong or to be ejected.\n"); + + return FFS_MEDIAERR; +} + +int bdev_write(struct super_block *sb, sector_t secno, struct buffer_head *bh, + u32 num_secs, bool sync) +{ + s32 count; + struct buffer_head *bh2; + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + struct exfat_sb_info *sbi = EXFAT_SB(sb); + long flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) + return FFS_MEDIAERR; +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + + if (!p_bd->opened) + return FFS_MEDIAERR; + + if (secno == bh->b_blocknr) { + lock_buffer(bh); + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + unlock_buffer(bh); + if (sync && (sync_dirty_buffer(bh) != 0)) + return FFS_MEDIAERR; + } else { + count = num_secs << p_bd->sector_size_bits; + + bh2 = __getblk(sb->s_bdev, secno, count); + if (!bh2) + goto no_bh; + + lock_buffer(bh2); + memcpy(bh2->b_data, bh->b_data, count); + set_buffer_uptodate(bh2); + mark_buffer_dirty(bh2); + unlock_buffer(bh2); + if (sync && (sync_dirty_buffer(bh2) != 0)) { + __brelse(bh2); + goto no_bh; + } + __brelse(bh2); + } + + return 0; + +no_bh: + WARN(!p_fs->dev_ejected, + "[EXFAT] No bh, device seems wrong or to be ejected.\n"); + + return FFS_MEDIAERR; +} + +int bdev_sync(struct super_block *sb) +{ + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + struct exfat_sb_info *sbi = EXFAT_SB(sb); + long flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) + return FFS_MEDIAERR; +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + + if (!p_bd->opened) + return FFS_MEDIAERR; + + return sync_blockdev(sb->s_bdev); +} diff --git a/drivers/staging/exfat/exfat_cache.c b/drivers/staging/exfat/exfat_cache.c new file mode 100644 index 000000000000..1565ce65d39f --- /dev/null +++ b/drivers/staging/exfat/exfat_cache.c @@ -0,0 +1,724 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include <linux/buffer_head.h> +#include <linux/fs.h> +#include <linux/mutex.h> +#include "exfat.h" + +#define LOCKBIT 0x01 +#define DIRTYBIT 0x02 + +/* Local variables */ +static DEFINE_SEMAPHORE(f_sem); +static DEFINE_SEMAPHORE(b_sem); + +static struct buf_cache_t *FAT_cache_find(struct super_block *sb, sector_t sec) +{ + s32 off; + struct buf_cache_t *bp, *hp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + off = (sec + + (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1); + + hp = &p_fs->FAT_cache_hash_list[off]; + for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { + if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { + WARN(!bp->buf_bh, + "[EXFAT] FAT_cache has no bh. It will make system panic.\n"); + + touch_buffer(bp->buf_bh); + return bp; + } + } + return NULL; +} + +static void push_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list) +{ + bp->next = list->next; + bp->prev = list; + list->next->prev = bp; + list->next = bp; +} + +static void push_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list) +{ + bp->prev = list->prev; + bp->next = list; + list->prev->next = bp; + list->prev = bp; +} + +static void move_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list) +{ + bp->prev->next = bp->next; + bp->next->prev = bp->prev; + push_to_mru(bp, list); +} + +static void move_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list) +{ + bp->prev->next = bp->next; + bp->next->prev = bp->prev; + push_to_lru(bp, list); +} + +static struct buf_cache_t *FAT_cache_get(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = p_fs->FAT_cache_lru_list.prev; + + move_to_mru(bp, &p_fs->FAT_cache_lru_list); + return bp; +} + +static void FAT_cache_insert_hash(struct super_block *sb, + struct buf_cache_t *bp) +{ + s32 off; + struct buf_cache_t *hp; + struct fs_info_t *p_fs; + + p_fs = &(EXFAT_SB(sb)->fs_info); + off = (bp->sec + + (bp->sec >> p_fs->sectors_per_clu_bits)) & + (FAT_CACHE_HASH_SIZE - 1); + + hp = &p_fs->FAT_cache_hash_list[off]; + bp->hash_next = hp->hash_next; + bp->hash_prev = hp; + hp->hash_next->hash_prev = bp; + hp->hash_next = bp; +} + +static void FAT_cache_remove_hash(struct buf_cache_t *bp) +{ + (bp->hash_prev)->hash_next = bp->hash_next; + (bp->hash_next)->hash_prev = bp->hash_prev; +} + +static void buf_cache_insert_hash(struct super_block *sb, + struct buf_cache_t *bp) +{ + s32 off; + struct buf_cache_t *hp; + struct fs_info_t *p_fs; + + p_fs = &(EXFAT_SB(sb)->fs_info); + off = (bp->sec + + (bp->sec >> p_fs->sectors_per_clu_bits)) & + (BUF_CACHE_HASH_SIZE - 1); + + hp = &p_fs->buf_cache_hash_list[off]; + bp->hash_next = hp->hash_next; + bp->hash_prev = hp; + hp->hash_next->hash_prev = bp; + hp->hash_next = bp; +} + +static void buf_cache_remove_hash(struct buf_cache_t *bp) +{ + (bp->hash_prev)->hash_next = bp->hash_next; + (bp->hash_next)->hash_prev = bp->hash_prev; +} + +void buf_init(struct super_block *sb) +{ + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + int i; + + /* LRU list */ + p_fs->FAT_cache_lru_list.next = &p_fs->FAT_cache_lru_list; + p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list; + + for (i = 0; i < FAT_CACHE_SIZE; i++) { + p_fs->FAT_cache_array[i].drv = -1; + p_fs->FAT_cache_array[i].sec = ~0; + p_fs->FAT_cache_array[i].flag = 0; + p_fs->FAT_cache_array[i].buf_bh = NULL; + p_fs->FAT_cache_array[i].prev = NULL; + p_fs->FAT_cache_array[i].next = NULL; + push_to_mru(&p_fs->FAT_cache_array[i], + &p_fs->FAT_cache_lru_list); + } + + p_fs->buf_cache_lru_list.next = &p_fs->buf_cache_lru_list; + p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list; + + for (i = 0; i < BUF_CACHE_SIZE; i++) { + p_fs->buf_cache_array[i].drv = -1; + p_fs->buf_cache_array[i].sec = ~0; + p_fs->buf_cache_array[i].flag = 0; + p_fs->buf_cache_array[i].buf_bh = NULL; + p_fs->buf_cache_array[i].prev = NULL; + p_fs->buf_cache_array[i].next = NULL; + push_to_mru(&p_fs->buf_cache_array[i], + &p_fs->buf_cache_lru_list); + } + + /* HASH list */ + for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) { + p_fs->FAT_cache_hash_list[i].drv = -1; + p_fs->FAT_cache_hash_list[i].sec = ~0; + p_fs->FAT_cache_hash_list[i].hash_next = + &p_fs->FAT_cache_hash_list[i]; + p_fs->FAT_cache_hash_list[i].hash_prev = + &p_fs->FAT_cache_hash_list[i]; + } + + for (i = 0; i < FAT_CACHE_SIZE; i++) + FAT_cache_insert_hash(sb, &p_fs->FAT_cache_array[i]); + + for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) { + p_fs->buf_cache_hash_list[i].drv = -1; + p_fs->buf_cache_hash_list[i].sec = ~0; + p_fs->buf_cache_hash_list[i].hash_next = + &p_fs->buf_cache_hash_list[i]; + p_fs->buf_cache_hash_list[i].hash_prev = + &p_fs->buf_cache_hash_list[i]; + } + + for (i = 0; i < BUF_CACHE_SIZE; i++) + buf_cache_insert_hash(sb, &p_fs->buf_cache_array[i]); +} + +void buf_shutdown(struct super_block *sb) +{ +} + +static int __FAT_read(struct super_block *sb, u32 loc, u32 *content) +{ + s32 off; + u32 _content; + sector_t sec; + u8 *fat_sector, *fat_entry; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_fs->vol_type == FAT12) { + sec = p_fs->FAT1_start_sector + + ((loc + (loc >> 1)) >> p_bd->sector_size_bits); + off = (loc + (loc >> 1)) & p_bd->sector_size_mask; + + if (off == (p_bd->sector_size - 1)) { + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + _content = (u32)fat_sector[off]; + + fat_sector = FAT_getblk(sb, ++sec); + if (!fat_sector) + return -1; + + _content |= (u32)fat_sector[0] << 8; + } else { + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &fat_sector[off]; + _content = GET16(fat_entry); + } + + if (loc & 1) + _content >>= 4; + + _content &= 0x00000FFF; + + if (_content >= CLUSTER_16(0x0FF8)) { + *content = CLUSTER_32(~0); + return 0; + } + *content = CLUSTER_32(_content); + return 0; + } else if (p_fs->vol_type == FAT16) { + sec = p_fs->FAT1_start_sector + + (loc >> (p_bd->sector_size_bits - 1)); + off = (loc << 1) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &fat_sector[off]; + + _content = GET16_A(fat_entry); + + _content &= 0x0000FFFF; + + if (_content >= CLUSTER_16(0xFFF8)) { + *content = CLUSTER_32(~0); + return 0; + } + *content = CLUSTER_32(_content); + return 0; + } else if (p_fs->vol_type == FAT32) { + sec = p_fs->FAT1_start_sector + + (loc >> (p_bd->sector_size_bits - 2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &fat_sector[off]; + + _content = GET32_A(fat_entry); + + _content &= 0x0FFFFFFF; + + if (_content >= CLUSTER_32(0x0FFFFFF8)) { + *content = CLUSTER_32(~0); + return 0; + } + *content = CLUSTER_32(_content); + return 0; + } else if (p_fs->vol_type == EXFAT) { + sec = p_fs->FAT1_start_sector + + (loc >> (p_bd->sector_size_bits - 2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &fat_sector[off]; + _content = GET32_A(fat_entry); + + if (_content >= CLUSTER_32(0xFFFFFFF8)) { + *content = CLUSTER_32(~0); + return 0; + } + *content = CLUSTER_32(_content); + return 0; + } + + /* Unknown volume type, throw in the towel and go home */ + *content = CLUSTER_32(~0); + return 0; +} + +/* in : sb, loc + * out: content + * returns 0 on success + * -1 on error + */ +int FAT_read(struct super_block *sb, u32 loc, u32 *content) +{ + s32 ret; + + down(&f_sem); + ret = __FAT_read(sb, loc, content); + up(&f_sem); + + return ret; +} + +static s32 __FAT_write(struct super_block *sb, u32 loc, u32 content) +{ + s32 off; + sector_t sec; + u8 *fat_sector, *fat_entry; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_fs->vol_type == FAT12) { + content &= 0x00000FFF; + + sec = p_fs->FAT1_start_sector + + ((loc + (loc >> 1)) >> p_bd->sector_size_bits); + off = (loc + (loc >> 1)) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + if (loc & 1) { /* odd */ + content <<= 4; + + if (off == (p_bd->sector_size - 1)) { + fat_sector[off] = (u8)(content | + (fat_sector[off] & + 0x0F)); + FAT_modify(sb, sec); + + fat_sector = FAT_getblk(sb, ++sec); + if (!fat_sector) + return -1; + + fat_sector[0] = (u8)(content >> 8); + } else { + fat_entry = &fat_sector[off]; + content |= GET16(fat_entry) & 0x000F; + + SET16(fat_entry, content); + } + } else { /* even */ + fat_sector[off] = (u8)(content); + + if (off == (p_bd->sector_size - 1)) { + fat_sector[off] = (u8)(content); + FAT_modify(sb, sec); + + fat_sector = FAT_getblk(sb, ++sec); + if (!fat_sector) + return -1; + fat_sector[0] = (u8)((fat_sector[0] & 0xF0) | + (content >> 8)); + } else { + fat_entry = &fat_sector[off]; + content |= GET16(fat_entry) & 0xF000; + + SET16(fat_entry, content); + } + } + } + + else if (p_fs->vol_type == FAT16) { + content &= 0x0000FFFF; + + sec = p_fs->FAT1_start_sector + (loc >> + (p_bd->sector_size_bits - 1)); + off = (loc << 1) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &fat_sector[off]; + + SET16_A(fat_entry, content); + } else if (p_fs->vol_type == FAT32) { + content &= 0x0FFFFFFF; + + sec = p_fs->FAT1_start_sector + (loc >> + (p_bd->sector_size_bits - 2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &fat_sector[off]; + + content |= GET32_A(fat_entry) & 0xF0000000; + + SET32_A(fat_entry, content); + } else { /* p_fs->vol_type == EXFAT */ + sec = p_fs->FAT1_start_sector + (loc >> + (p_bd->sector_size_bits - 2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &fat_sector[off]; + + SET32_A(fat_entry, content); + } + + FAT_modify(sb, sec); + return 0; +} + +int FAT_write(struct super_block *sb, u32 loc, u32 content) +{ + s32 ret; + + down(&f_sem); + ret = __FAT_write(sb, loc, content); + up(&f_sem); + + return ret; +} + +u8 *FAT_getblk(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = FAT_cache_find(sb, sec); + if (bp) { + move_to_mru(bp, &p_fs->FAT_cache_lru_list); + return bp->buf_bh->b_data; + } + + bp = FAT_cache_get(sb, sec); + + FAT_cache_remove_hash(bp); + + bp->drv = p_fs->drv; + bp->sec = sec; + bp->flag = 0; + + FAT_cache_insert_hash(sb, bp); + + if (sector_read(sb, sec, &bp->buf_bh, 1) != FFS_SUCCESS) { + FAT_cache_remove_hash(bp); + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + bp->buf_bh = NULL; + + move_to_lru(bp, &p_fs->FAT_cache_lru_list); + return NULL; + } + + return bp->buf_bh->b_data; +} + +void FAT_modify(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + + bp = FAT_cache_find(sb, sec); + if (bp) + sector_write(sb, sec, bp->buf_bh, 0); +} + +void FAT_release_all(struct super_block *sb) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + down(&f_sem); + + bp = p_fs->FAT_cache_lru_list.next; + while (bp != &p_fs->FAT_cache_lru_list) { + if (bp->drv == p_fs->drv) { + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + + if (bp->buf_bh) { + __brelse(bp->buf_bh); + bp->buf_bh = NULL; + } + } + bp = bp->next; + } + + up(&f_sem); +} + +void FAT_sync(struct super_block *sb) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + down(&f_sem); + + bp = p_fs->FAT_cache_lru_list.next; + while (bp != &p_fs->FAT_cache_lru_list) { + if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) { + sync_dirty_buffer(bp->buf_bh); + bp->flag &= ~(DIRTYBIT); + } + bp = bp->next; + } + + up(&f_sem); +} + +static struct buf_cache_t *buf_cache_find(struct super_block *sb, sector_t sec) +{ + s32 off; + struct buf_cache_t *bp, *hp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & + (BUF_CACHE_HASH_SIZE - 1); + + hp = &p_fs->buf_cache_hash_list[off]; + for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { + if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { + touch_buffer(bp->buf_bh); + return bp; + } + } + return NULL; +} + +static struct buf_cache_t *buf_cache_get(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = p_fs->buf_cache_lru_list.prev; + while (bp->flag & LOCKBIT) + bp = bp->prev; + + move_to_mru(bp, &p_fs->buf_cache_lru_list); + return bp; +} + +static u8 *__buf_getblk(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = buf_cache_find(sb, sec); + if (bp) { + move_to_mru(bp, &p_fs->buf_cache_lru_list); + return bp->buf_bh->b_data; + } + + bp = buf_cache_get(sb, sec); + + buf_cache_remove_hash(bp); + + bp->drv = p_fs->drv; + bp->sec = sec; + bp->flag = 0; + + buf_cache_insert_hash(sb, bp); + + if (sector_read(sb, sec, &bp->buf_bh, 1) != FFS_SUCCESS) { + buf_cache_remove_hash(bp); + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + bp->buf_bh = NULL; + + move_to_lru(bp, &p_fs->buf_cache_lru_list); + return NULL; + } + + return bp->buf_bh->b_data; +} + +u8 *buf_getblk(struct super_block *sb, sector_t sec) +{ + u8 *buf; + + down(&b_sem); + buf = __buf_getblk(sb, sec); + up(&b_sem); + + return buf; +} + +void buf_modify(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + + down(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp)) + sector_write(sb, sec, bp->buf_bh, 0); + + WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n", + (unsigned long long)sec); + + up(&b_sem); +} + +void buf_lock(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + + down(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp)) + bp->flag |= LOCKBIT; + + WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n", + (unsigned long long)sec); + + up(&b_sem); +} + +void buf_unlock(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + + down(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp)) + bp->flag &= ~(LOCKBIT); + + WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n", + (unsigned long long)sec); + + up(&b_sem); +} + +void buf_release(struct super_block *sb, sector_t sec) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + down(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp)) { + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + + if (bp->buf_bh) { + __brelse(bp->buf_bh); + bp->buf_bh = NULL; + } + + move_to_lru(bp, &p_fs->buf_cache_lru_list); + } + + up(&b_sem); +} + +void buf_release_all(struct super_block *sb) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + down(&b_sem); + + bp = p_fs->buf_cache_lru_list.next; + while (bp != &p_fs->buf_cache_lru_list) { + if (bp->drv == p_fs->drv) { + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + + if (bp->buf_bh) { + __brelse(bp->buf_bh); + bp->buf_bh = NULL; + } + } + bp = bp->next; + } + + up(&b_sem); +} + +void buf_sync(struct super_block *sb) +{ + struct buf_cache_t *bp; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + down(&b_sem); + + bp = p_fs->buf_cache_lru_list.next; + while (bp != &p_fs->buf_cache_lru_list) { + if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) { + sync_dirty_buffer(bp->buf_bh); + bp->flag &= ~(DIRTYBIT); + } + bp = bp->next; + } + + up(&b_sem); +} diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c new file mode 100644 index 000000000000..b3e9cf725cf5 --- /dev/null +++ b/drivers/staging/exfat/exfat_core.c @@ -0,0 +1,3701 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include <linux/types.h> +#include <linux/buffer_head.h> +#include <linux/fs.h> +#include <linux/mutex.h> +#include <linux/blkdev.h> +#include <linux/slab.h> +#include "exfat.h" + +static void __set_sb_dirty(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + sbi->s_dirt = 1; +} + +static u8 name_buf[MAX_PATH_LENGTH * MAX_CHARSET_SIZE]; + +static char *reserved_names[] = { + "AUX ", "CON ", "NUL ", "PRN ", + "COM1 ", "COM2 ", "COM3 ", "COM4 ", + "COM5 ", "COM6 ", "COM7 ", "COM8 ", "COM9 ", + "LPT1 ", "LPT2 ", "LPT3 ", "LPT4 ", + "LPT5 ", "LPT6 ", "LPT7 ", "LPT8 ", "LPT9 ", + NULL +}; + +static u8 free_bit[] = { + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, /* 0 ~ 19 */ + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, /* 20 ~ 39 */ + 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 40 ~ 59 */ + 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, /* 60 ~ 79 */ + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, /* 80 ~ 99 */ + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, /* 100 ~ 119 */ + 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 120 ~ 139 */ + 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, /* 140 ~ 159 */ + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, /* 160 ~ 179 */ + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, /* 180 ~ 199 */ + 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 200 ~ 219 */ + 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, /* 220 ~ 239 */ + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 240 ~ 254 */ +}; + +static u8 used_bit[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, /* 0 ~ 19 */ + 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, /* 20 ~ 39 */ + 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, /* 40 ~ 59 */ + 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 60 ~ 79 */ + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, /* 80 ~ 99 */ + 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, /* 100 ~ 119 */ + 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, /* 120 ~ 139 */ + 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 140 ~ 159 */ + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, /* 160 ~ 179 */ + 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, /* 180 ~ 199 */ + 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, /* 200 ~ 219 */ + 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* 220 ~ 239 */ + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 /* 240 ~ 255 */ +}; + +#define BITMAP_LOC(v) ((v) >> 3) +#define BITMAP_SHIFT(v) ((v) & 0x07) + +static inline s32 exfat_bitmap_test(u8 *bitmap, int i) +{ + u8 data; + + data = bitmap[BITMAP_LOC(i)]; + if ((data >> BITMAP_SHIFT(i)) & 0x01) + return 1; + return 0; +} + +static inline void exfat_bitmap_set(u8 *bitmap, int i) +{ + bitmap[BITMAP_LOC(i)] |= (0x01 << BITMAP_SHIFT(i)); +} + +static inline void exfat_bitmap_clear(u8 *bitmap, int i) +{ + bitmap[BITMAP_LOC(i)] &= ~(0x01 << BITMAP_SHIFT(i)); +} + +/* + * File System Management Functions + */ + +void fs_set_vol_flags(struct super_block *sb, u32 new_flag) +{ + struct pbr_sector_t *p_pbr; + struct bpbex_t *p_bpb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_fs->vol_flag == new_flag) + return; + + p_fs->vol_flag = new_flag; + + if (p_fs->vol_type == EXFAT) { + if (!p_fs->pbr_bh) { + if (sector_read(sb, p_fs->PBR_sector, + &p_fs->pbr_bh, 1) != FFS_SUCCESS) + return; + } + + p_pbr = (struct pbr_sector_t *)p_fs->pbr_bh->b_data; + p_bpb = (struct bpbex_t *)p_pbr->bpb; + SET16(p_bpb->vol_flags, (u16)new_flag); + + /* XXX duyoung + * what can we do here? (cuz fs_set_vol_flags() is void) + */ + if ((new_flag == VOL_DIRTY) && (!buffer_dirty(p_fs->pbr_bh))) + sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 1); + else + sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 0); + } +} + +void fs_error(struct super_block *sb) +{ + struct exfat_mount_options *opts = &EXFAT_SB(sb)->options; + + if (opts->errors == EXFAT_ERRORS_PANIC) { + panic("[EXFAT] Filesystem panic from previous error\n"); + } else if ((opts->errors == EXFAT_ERRORS_RO) && !sb_rdonly(sb)) { + sb->s_flags |= SB_RDONLY; + pr_err("[EXFAT] Filesystem has been set read-only\n"); + } +} + +/* + * Cluster Management Functions + */ + +s32 clear_cluster(struct super_block *sb, u32 clu) +{ + sector_t s, n; + s32 ret = FFS_SUCCESS; + struct buffer_head *tmp_bh = NULL; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (clu == CLUSTER_32(0)) { /* FAT16 root_dir */ + s = p_fs->root_start_sector; + n = p_fs->data_start_sector; + } else { + s = START_SECTOR(clu); + n = s + p_fs->sectors_per_clu; + } + + for (; s < n; s++) { + ret = sector_read(sb, s, &tmp_bh, 0); + if (ret != FFS_SUCCESS) + return ret; + + memset((char *)tmp_bh->b_data, 0x0, p_bd->sector_size); + ret = sector_write(sb, s, tmp_bh, 0); + if (ret != FFS_SUCCESS) + break; + } + + brelse(tmp_bh); + return ret; +} + +s32 fat_alloc_cluster(struct super_block *sb, s32 num_alloc, + struct chain_t *p_chain) +{ + int i, num_clusters = 0; + u32 new_clu, last_clu = CLUSTER_32(~0), read_clu; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + new_clu = p_chain->dir; + if (new_clu == CLUSTER_32(~0)) + new_clu = p_fs->clu_srch_ptr; + else if (new_clu >= p_fs->num_clusters) + new_clu = 2; + + __set_sb_dirty(sb); + + p_chain->dir = CLUSTER_32(~0); + + for (i = 2; i < p_fs->num_clusters; i++) { + if (FAT_read(sb, new_clu, &read_clu) != 0) + return -1; + + if (read_clu == CLUSTER_32(0)) { + if (FAT_write(sb, new_clu, CLUSTER_32(~0)) < 0) + return -1; + num_clusters++; + + if (p_chain->dir == CLUSTER_32(~0)) { + p_chain->dir = new_clu; + } else { + if (FAT_write(sb, last_clu, new_clu) < 0) + return -1; + } + + last_clu = new_clu; + + if ((--num_alloc) == 0) { + p_fs->clu_srch_ptr = new_clu; + if (p_fs->used_clusters != UINT_MAX) + p_fs->used_clusters += num_clusters; + + return num_clusters; + } + } + if ((++new_clu) >= p_fs->num_clusters) + new_clu = 2; + } + + p_fs->clu_srch_ptr = new_clu; + if (p_fs->used_clusters != UINT_MAX) + p_fs->used_clusters += num_clusters; + + return num_clusters; +} + +s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc, + struct chain_t *p_chain) +{ + s32 num_clusters = 0; + u32 hint_clu, new_clu, last_clu = CLUSTER_32(~0); + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + hint_clu = p_chain->dir; + if (hint_clu == CLUSTER_32(~0)) { + hint_clu = test_alloc_bitmap(sb, p_fs->clu_srch_ptr - 2); + if (hint_clu == CLUSTER_32(~0)) + return 0; + } else if (hint_clu >= p_fs->num_clusters) { + hint_clu = 2; + p_chain->flags = 0x01; + } + + __set_sb_dirty(sb); + + p_chain->dir = CLUSTER_32(~0); + + while ((new_clu = test_alloc_bitmap(sb, hint_clu - 2)) != CLUSTER_32(~0)) { + if (new_clu != hint_clu) { + if (p_chain->flags == 0x03) { + exfat_chain_cont_cluster(sb, p_chain->dir, + num_clusters); + p_chain->flags = 0x01; + } + } + + if (set_alloc_bitmap(sb, new_clu - 2) != FFS_SUCCESS) + return -1; + + num_clusters++; + + if (p_chain->flags == 0x01) { + if (FAT_write(sb, new_clu, CLUSTER_32(~0)) < 0) + return -1; + } + + if (p_chain->dir == CLUSTER_32(~0)) { + p_chain->dir = new_clu; + } else { + if (p_chain->flags == 0x01) { + if (FAT_write(sb, last_clu, new_clu) < 0) + return -1; + } + } + last_clu = new_clu; + + if ((--num_alloc) == 0) { + p_fs->clu_srch_ptr = hint_clu; + if (p_fs->used_clusters != UINT_MAX) + p_fs->used_clusters += num_clusters; + + p_chain->size += num_clusters; + return num_clusters; + } + + hint_clu = new_clu + 1; + if (hint_clu >= p_fs->num_clusters) { + hint_clu = 2; + + if (p_chain->flags == 0x03) { + exfat_chain_cont_cluster(sb, p_chain->dir, + num_clusters); + p_chain->flags = 0x01; + } + } + } + + p_fs->clu_srch_ptr = hint_clu; + if (p_fs->used_clusters != UINT_MAX) + p_fs->used_clusters += num_clusters; + + p_chain->size += num_clusters; + return num_clusters; +} + +void fat_free_cluster(struct super_block *sb, struct chain_t *p_chain, + s32 do_relse) +{ + s32 num_clusters = 0; + u32 clu, prev; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + int i; + sector_t sector; + + if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) + return; + __set_sb_dirty(sb); + clu = p_chain->dir; + + if (p_chain->size <= 0) + return; + + do { + if (p_fs->dev_ejected) + break; + + if (do_relse) { + sector = START_SECTOR(clu); + for (i = 0; i < p_fs->sectors_per_clu; i++) + buf_release(sb, sector + i); + } + + prev = clu; + if (FAT_read(sb, clu, &clu) == -1) + break; + + if (FAT_write(sb, prev, CLUSTER_32(0)) < 0) + break; + num_clusters++; + + } while (clu != CLUSTER_32(~0)); + + if (p_fs->used_clusters != UINT_MAX) + p_fs->used_clusters -= num_clusters; +} + +void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain, + s32 do_relse) +{ + s32 num_clusters = 0; + u32 clu; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + int i; + sector_t sector; + + if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) + return; + + if (p_chain->size <= 0) { + pr_err("[EXFAT] free_cluster : skip free-req clu:%u, because of zero-size truncation\n", + p_chain->dir); + return; + } + + __set_sb_dirty(sb); + clu = p_chain->dir; + + if (p_chain->flags == 0x03) { + do { + if (do_relse) { + sector = START_SECTOR(clu); + for (i = 0; i < p_fs->sectors_per_clu; i++) + buf_release(sb, sector + i); + } + + if (clr_alloc_bitmap(sb, clu - 2) != FFS_SUCCESS) + break; + clu++; + + num_clusters++; + } while (num_clusters < p_chain->size); + } else { + do { + if (p_fs->dev_ejected) + break; + + if (do_relse) { + sector = START_SECTOR(clu); + for (i = 0; i < p_fs->sectors_per_clu; i++) + buf_release(sb, sector + i); + } + + if (clr_alloc_bitmap(sb, clu - 2) != FFS_SUCCESS) + break; + + if (FAT_read(sb, clu, &clu) == -1) + break; + num_clusters++; + } while ((clu != CLUSTER_32(0)) && (clu != CLUSTER_32(~0))); + } + + if (p_fs->used_clusters != UINT_MAX) + p_fs->used_clusters -= num_clusters; +} + +u32 find_last_cluster(struct super_block *sb, struct chain_t *p_chain) +{ + u32 clu, next; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + clu = p_chain->dir; + + if (p_chain->flags == 0x03) { + clu += p_chain->size - 1; + } else { + while ((FAT_read(sb, clu, &next) == 0) && + (next != CLUSTER_32(~0))) { + if (p_fs->dev_ejected) + break; + clu = next; + } + } + + return clu; +} + +s32 count_num_clusters(struct super_block *sb, struct chain_t *p_chain) +{ + int i, count = 0; + u32 clu; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) + return 0; + + clu = p_chain->dir; + + if (p_chain->flags == 0x03) { + count = p_chain->size; + } else { + for (i = 2; i < p_fs->num_clusters; i++) { + count++; + if (FAT_read(sb, clu, &clu) != 0) + return 0; + if (clu == CLUSTER_32(~0)) + break; + } + } + + return count; +} + +s32 fat_count_used_clusters(struct super_block *sb) +{ + int i, count = 0; + u32 clu; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = 2; i < p_fs->num_clusters; i++) { + if (FAT_read(sb, i, &clu) != 0) + break; + if (clu != CLUSTER_32(0)) + count++; + } + + return count; +} + +s32 exfat_count_used_clusters(struct super_block *sb) +{ + int i, map_i, map_b, count = 0; + u8 k; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + map_i = map_b = 0; + + for (i = 2; i < p_fs->num_clusters; i += 8) { + k = *(((u8 *)p_fs->vol_amap[map_i]->b_data) + map_b); + count += used_bit[k]; + + if ((++map_b) >= p_bd->sector_size) { + map_i++; + map_b = 0; + } + } + + return count; +} + +void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len) +{ + if (len == 0) + return; + + while (len > 1) { + if (FAT_write(sb, chain, chain + 1) < 0) + break; + chain++; + len--; + } + FAT_write(sb, chain, CLUSTER_32(~0)); +} + +/* + * Allocation Bitmap Management Functions + */ + +s32 load_alloc_bitmap(struct super_block *sb) +{ + int i, j, ret; + u32 map_size; + u32 type; + sector_t sector; + struct chain_t clu; + struct bmap_dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + clu.dir = p_fs->root_dir; + clu.flags = 0x01; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < p_fs->dentries_per_clu; i++) { + ep = (struct bmap_dentry_t *)get_entry_in_dir(sb, &clu, + i, NULL); + if (!ep) + return FFS_MEDIAERR; + + type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep); + + if (type == TYPE_UNUSED) + break; + if (type != TYPE_BITMAP) + continue; + + if (ep->flags == 0x0) { + p_fs->map_clu = GET32_A(ep->start_clu); + map_size = (u32)GET64_A(ep->size); + + p_fs->map_sectors = ((map_size - 1) >> p_bd->sector_size_bits) + 1; + + p_fs->vol_amap = kmalloc_array(p_fs->map_sectors, + sizeof(struct buffer_head *), + GFP_KERNEL); + if (!p_fs->vol_amap) + return FFS_MEMORYERR; + + sector = START_SECTOR(p_fs->map_clu); + + for (j = 0; j < p_fs->map_sectors; j++) { + p_fs->vol_amap[j] = NULL; + ret = sector_read(sb, sector + j, &(p_fs->vol_amap[j]), 1); + if (ret != FFS_SUCCESS) { + /* release all buffers and free vol_amap */ + i = 0; + while (i < j) + brelse(p_fs->vol_amap[i++]); + + kfree(p_fs->vol_amap); + p_fs->vol_amap = NULL; + return ret; + } + } + + p_fs->pbr_bh = NULL; + return FFS_SUCCESS; + } + } + + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + return FFS_MEDIAERR; + } + + return FFS_FORMATERR; +} + +void free_alloc_bitmap(struct super_block *sb) +{ + int i; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + brelse(p_fs->pbr_bh); + + for (i = 0; i < p_fs->map_sectors; i++) + __brelse(p_fs->vol_amap[i]); + + kfree(p_fs->vol_amap); + p_fs->vol_amap = NULL; +} + +s32 set_alloc_bitmap(struct super_block *sb, u32 clu) +{ + int i, b; + sector_t sector; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + i = clu >> (p_bd->sector_size_bits + 3); + b = clu & ((p_bd->sector_size << 3) - 1); + + sector = START_SECTOR(p_fs->map_clu) + i; + + exfat_bitmap_set((u8 *)p_fs->vol_amap[i]->b_data, b); + + return sector_write(sb, sector, p_fs->vol_amap[i], 0); +} + +s32 clr_alloc_bitmap(struct super_block *sb, u32 clu) +{ + int i, b; + sector_t sector; +#ifdef CONFIG_EXFAT_DISCARD + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_mount_options *opts = &sbi->options; + int ret; +#endif /* CONFIG_EXFAT_DISCARD */ + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + i = clu >> (p_bd->sector_size_bits + 3); + b = clu & ((p_bd->sector_size << 3) - 1); + + sector = START_SECTOR(p_fs->map_clu) + i; + + exfat_bitmap_clear((u8 *)p_fs->vol_amap[i]->b_data, b); + + return sector_write(sb, sector, p_fs->vol_amap[i], 0); + +#ifdef CONFIG_EXFAT_DISCARD + if (opts->discard) { + ret = sb_issue_discard(sb, START_SECTOR(clu), + (1 << p_fs->sectors_per_clu_bits), + GFP_NOFS, 0); + if (ret == -EOPNOTSUPP) { + pr_warn("discard not supported by device, disabling"); + opts->discard = 0; + } + } +#endif /* CONFIG_EXFAT_DISCARD */ +} + +u32 test_alloc_bitmap(struct super_block *sb, u32 clu) +{ + int i, map_i, map_b; + u32 clu_base, clu_free; + u8 k, clu_mask; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + clu_base = (clu & ~(0x7)) + 2; + clu_mask = (1 << (clu - clu_base + 2)) - 1; + + map_i = clu >> (p_bd->sector_size_bits + 3); + map_b = (clu >> 3) & p_bd->sector_size_mask; + + for (i = 2; i < p_fs->num_clusters; i += 8) { + k = *(((u8 *)p_fs->vol_amap[map_i]->b_data) + map_b); + if (clu_mask > 0) { + k |= clu_mask; + clu_mask = 0; + } + if (k < 0xFF) { + clu_free = clu_base + free_bit[k]; + if (clu_free < p_fs->num_clusters) + return clu_free; + } + clu_base += 8; + + if (((++map_b) >= p_bd->sector_size) || + (clu_base >= p_fs->num_clusters)) { + if ((++map_i) >= p_fs->map_sectors) { + clu_base = 2; + map_i = 0; + } + map_b = 0; + } + } + + return CLUSTER_32(~0); +} + +void sync_alloc_bitmap(struct super_block *sb) +{ + int i; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (!p_fs->vol_amap) + return; + + for (i = 0; i < p_fs->map_sectors; i++) + sync_dirty_buffer(p_fs->vol_amap[i]); +} + +/* + * Upcase table Management Functions + */ +static s32 __load_upcase_table(struct super_block *sb, sector_t sector, + u32 num_sectors, u32 utbl_checksum) +{ + int i, ret = FFS_ERROR; + u32 j; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + struct buffer_head *tmp_bh = NULL; + sector_t end_sector = num_sectors + sector; + + bool skip = false; + u32 index = 0; + u16 uni = 0; + u16 **upcase_table; + + u32 checksum = 0; + + upcase_table = p_fs->vol_utbl = kmalloc(UTBL_COL_COUNT * sizeof(u16 *), + GFP_KERNEL); + if (!upcase_table) + return FFS_MEMORYERR; + memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *)); + + while (sector < end_sector) { + ret = sector_read(sb, sector, &tmp_bh, 1); + if (ret != FFS_SUCCESS) { + pr_debug("sector read (0x%llX)fail\n", + (unsigned long long)sector); + goto error; + } + sector++; + + for (i = 0; i < p_bd->sector_size && index <= 0xFFFF; i += 2) { + uni = GET16(((u8 *)tmp_bh->b_data) + i); + + checksum = ((checksum & 1) ? 0x80000000 : 0) + + (checksum >> 1) + *(((u8 *)tmp_bh->b_data) + + i); + checksum = ((checksum & 1) ? 0x80000000 : 0) + + (checksum >> 1) + *(((u8 *)tmp_bh->b_data) + + (i + 1)); + + if (skip) { + pr_debug("skip from 0x%X ", index); + index += uni; + pr_debug("to 0x%X (amount of 0x%X)\n", + index, uni); + skip = false; + } else if (uni == index) { + index++; + } else if (uni == 0xFFFF) { + skip = true; + } else { /* uni != index , uni != 0xFFFF */ + u16 col_index = get_col_index(index); + + if (!upcase_table[col_index]) { + pr_debug("alloc = 0x%X\n", col_index); + upcase_table[col_index] = kmalloc_array(UTBL_ROW_COUNT, + sizeof(u16), GFP_KERNEL); + if (!upcase_table[col_index]) { + ret = FFS_MEMORYERR; + goto error; + } + + for (j = 0; j < UTBL_ROW_COUNT; j++) + upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j; + } + + upcase_table[col_index][get_row_index(index)] = uni; + index++; + } + } + } + if (index >= 0xFFFF && utbl_checksum == checksum) { + if (tmp_bh) + brelse(tmp_bh); + return FFS_SUCCESS; + } + ret = FFS_ERROR; +error: + if (tmp_bh) + brelse(tmp_bh); + free_upcase_table(sb); + return ret; +} + +static s32 __load_default_upcase_table(struct super_block *sb) +{ + int i, ret = FFS_ERROR; + u32 j; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + bool skip = false; + u32 index = 0; + u16 uni = 0; + u16 **upcase_table; + + upcase_table = p_fs->vol_utbl = kmalloc(UTBL_COL_COUNT * sizeof(u16 *), + GFP_KERNEL); + if (!upcase_table) + return FFS_MEMORYERR; + memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *)); + + for (i = 0; index <= 0xFFFF && i < NUM_UPCASE * 2; i += 2) { + uni = GET16(uni_upcase + i); + if (skip) { + pr_debug("skip from 0x%X ", index); + index += uni; + pr_debug("to 0x%X (amount of 0x%X)\n", index, uni); + skip = false; + } else if (uni == index) { + index++; + } else if (uni == 0xFFFF) { + skip = true; + } else { /* uni != index , uni != 0xFFFF */ + u16 col_index = get_col_index(index); + + if (!upcase_table[col_index]) { + pr_debug("alloc = 0x%X\n", col_index); + upcase_table[col_index] = kmalloc_array(UTBL_ROW_COUNT, + sizeof(u16), + GFP_KERNEL); + if (!upcase_table[col_index]) { + ret = FFS_MEMORYERR; + goto error; + } + + for (j = 0; j < UTBL_ROW_COUNT; j++) + upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j; + } + + upcase_table[col_index][get_row_index(index)] = uni; + index++; + } + } + + if (index >= 0xFFFF) + return FFS_SUCCESS; + +error: + /* FATAL error: default upcase table has error */ + free_upcase_table(sb); + return ret; +} + +s32 load_upcase_table(struct super_block *sb) +{ + int i; + u32 tbl_clu, tbl_size; + sector_t sector; + u32 type, num_sectors; + struct chain_t clu; + struct case_dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + clu.dir = p_fs->root_dir; + clu.flags = 0x01; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + while (clu.dir != CLUSTER_32(~0)) { + for (i = 0; i < p_fs->dentries_per_clu; i++) { + ep = (struct case_dentry_t *)get_entry_in_dir(sb, &clu, + i, NULL); + if (!ep) + return FFS_MEDIAERR; + + type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep); + + if (type == TYPE_UNUSED) + break; + if (type != TYPE_UPCASE) + continue; + + tbl_clu = GET32_A(ep->start_clu); + tbl_size = (u32)GET64_A(ep->size); + + sector = START_SECTOR(tbl_clu); + num_sectors = ((tbl_size - 1) >> p_bd->sector_size_bits) + 1; + if (__load_upcase_table(sb, sector, num_sectors, + GET32_A(ep->checksum)) != FFS_SUCCESS) + break; + return FFS_SUCCESS; + } + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + return FFS_MEDIAERR; + } + /* load default upcase table */ + return __load_default_upcase_table(sb); +} + +void free_upcase_table(struct super_block *sb) +{ + u32 i; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + u16 **upcase_table; + + upcase_table = p_fs->vol_utbl; + for (i = 0; i < UTBL_COL_COUNT; i++) + kfree(upcase_table[i]); + + kfree(p_fs->vol_utbl); + p_fs->vol_utbl = NULL; +} + +/* + * Directory Entry Management Functions + */ + +u32 fat_get_entry_type(struct dentry_t *p_entry) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + if (*(ep->name) == 0x0) + return TYPE_UNUSED; + + else if (*(ep->name) == 0xE5) + return TYPE_DELETED; + + else if (ep->attr == ATTR_EXTEND) + return TYPE_EXTEND; + + else if ((ep->attr & (ATTR_SUBDIR | ATTR_VOLUME)) == ATTR_VOLUME) + return TYPE_VOLUME; + + else if ((ep->attr & (ATTR_SUBDIR | ATTR_VOLUME)) == ATTR_SUBDIR) + return TYPE_DIR; + + return TYPE_FILE; +} + +u32 exfat_get_entry_type(struct dentry_t *p_entry) +{ + struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; + + if (ep->type == 0x0) { + return TYPE_UNUSED; + } else if (ep->type < 0x80) { + return TYPE_DELETED; + } else if (ep->type == 0x80) { + return TYPE_INVALID; + } else if (ep->type < 0xA0) { + if (ep->type == 0x81) { + return TYPE_BITMAP; + } else if (ep->type == 0x82) { + return TYPE_UPCASE; + } else if (ep->type == 0x83) { + return TYPE_VOLUME; + } else if (ep->type == 0x85) { + if (GET16_A(ep->attr) & ATTR_SUBDIR) + return TYPE_DIR; + else + return TYPE_FILE; + } + return TYPE_CRITICAL_PRI; + } else if (ep->type < 0xC0) { + if (ep->type == 0xA0) + return TYPE_GUID; + else if (ep->type == 0xA1) + return TYPE_PADDING; + else if (ep->type == 0xA2) + return TYPE_ACLTAB; + return TYPE_BENIGN_PRI; + } else if (ep->type < 0xE0) { + if (ep->type == 0xC0) + return TYPE_STREAM; + else if (ep->type == 0xC1) + return TYPE_EXTEND; + else if (ep->type == 0xC2) + return TYPE_ACL; + return TYPE_CRITICAL_SEC; + } + + return TYPE_BENIGN_SEC; +} + +void fat_set_entry_type(struct dentry_t *p_entry, u32 type) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + if (type == TYPE_UNUSED) + *(ep->name) = 0x0; + + else if (type == TYPE_DELETED) + *(ep->name) = 0xE5; + + else if (type == TYPE_EXTEND) + ep->attr = ATTR_EXTEND; + + else if (type == TYPE_DIR) + ep->attr = ATTR_SUBDIR; + + else if (type == TYPE_FILE) + ep->attr = ATTR_ARCHIVE; + + else if (type == TYPE_SYMLINK) + ep->attr = ATTR_ARCHIVE | ATTR_SYMLINK; +} + +void exfat_set_entry_type(struct dentry_t *p_entry, u32 type) +{ + struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; + + if (type == TYPE_UNUSED) { + ep->type = 0x0; + } else if (type == TYPE_DELETED) { + ep->type &= ~0x80; + } else if (type == TYPE_STREAM) { + ep->type = 0xC0; + } else if (type == TYPE_EXTEND) { + ep->type = 0xC1; + } else if (type == TYPE_BITMAP) { + ep->type = 0x81; + } else if (type == TYPE_UPCASE) { + ep->type = 0x82; + } else if (type == TYPE_VOLUME) { + ep->type = 0x83; + } else if (type == TYPE_DIR) { + ep->type = 0x85; + SET16_A(ep->attr, ATTR_SUBDIR); + } else if (type == TYPE_FILE) { + ep->type = 0x85; + SET16_A(ep->attr, ATTR_ARCHIVE); + } else if (type == TYPE_SYMLINK) { + ep->type = 0x85; + SET16_A(ep->attr, ATTR_ARCHIVE | ATTR_SYMLINK); + } +} + +u32 fat_get_entry_attr(struct dentry_t *p_entry) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + return (u32)ep->attr; +} + +u32 exfat_get_entry_attr(struct dentry_t *p_entry) +{ + struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; + + return (u32)GET16_A(ep->attr); +} + +void fat_set_entry_attr(struct dentry_t *p_entry, u32 attr) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + ep->attr = (u8)attr; +} + +void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr) +{ + struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; + + SET16_A(ep->attr, (u16)attr); +} + +u8 fat_get_entry_flag(struct dentry_t *p_entry) +{ + return 0x01; +} + +u8 exfat_get_entry_flag(struct dentry_t *p_entry) +{ + struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; + + return ep->flags; +} + +void fat_set_entry_flag(struct dentry_t *p_entry, u8 flags) +{ +} + +void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flags) +{ + struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; + + ep->flags = flags; +} + +u32 fat_get_entry_clu0(struct dentry_t *p_entry) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + return ((u32)GET16_A(ep->start_clu_hi) << 16) | + GET16_A(ep->start_clu_lo); +} + +u32 exfat_get_entry_clu0(struct dentry_t *p_entry) +{ + struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; + + return GET32_A(ep->start_clu); +} + +void fat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + SET16_A(ep->start_clu_lo, CLUSTER_16(start_clu)); + SET16_A(ep->start_clu_hi, CLUSTER_16(start_clu >> 16)); +} + +void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu) +{ + struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; + + SET32_A(ep->start_clu, start_clu); +} + +u64 fat_get_entry_size(struct dentry_t *p_entry) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + return (u64)GET32_A(ep->size); +} + +u64 exfat_get_entry_size(struct dentry_t *p_entry) +{ + struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; + + return GET64_A(ep->valid_size); +} + +void fat_set_entry_size(struct dentry_t *p_entry, u64 size) +{ + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + SET32_A(ep->size, (u32)size); +} + +void exfat_set_entry_size(struct dentry_t *p_entry, u64 size) +{ + struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry; + + SET64_A(ep->valid_size, size); + SET64_A(ep->size, size); +} + +void fat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode) +{ + u16 t = 0x00, d = 0x21; + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + switch (mode) { + case TM_CREATE: + t = GET16_A(ep->create_time); + d = GET16_A(ep->create_date); + break; + case TM_MODIFY: + t = GET16_A(ep->modify_time); + d = GET16_A(ep->modify_date); + break; + } + + tp->sec = (t & 0x001F) << 1; + tp->min = (t >> 5) & 0x003F; + tp->hour = (t >> 11); + tp->day = (d & 0x001F); + tp->mon = (d >> 5) & 0x000F; + tp->year = (d >> 9); +} + +void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode) +{ + u16 t = 0x00, d = 0x21; + struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; + + switch (mode) { + case TM_CREATE: + t = GET16_A(ep->create_time); + d = GET16_A(ep->create_date); + break; + case TM_MODIFY: + t = GET16_A(ep->modify_time); + d = GET16_A(ep->modify_date); + break; + case TM_ACCESS: + t = GET16_A(ep->access_time); + d = GET16_A(ep->access_date); + break; + } + + tp->sec = (t & 0x001F) << 1; + tp->min = (t >> 5) & 0x003F; + tp->hour = (t >> 11); + tp->day = (d & 0x001F); + tp->mon = (d >> 5) & 0x000F; + tp->year = (d >> 9); +} + +void fat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode) +{ + u16 t, d; + struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry; + + t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1); + d = (tp->year << 9) | (tp->mon << 5) | tp->day; + + switch (mode) { + case TM_CREATE: + SET16_A(ep->create_time, t); + SET16_A(ep->create_date, d); + break; + case TM_MODIFY: + SET16_A(ep->modify_time, t); + SET16_A(ep->modify_date, d); + break; + } +} + +void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp, + u8 mode) +{ + u16 t, d; + struct file_dentry_t *ep = (struct file_dentry_t *)p_entry; + + t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1); + d = (tp->year << 9) | (tp->mon << 5) | tp->day; + + switch (mode) { + case TM_CREATE: + SET16_A(ep->create_time, t); + SET16_A(ep->create_date, d); + break; + case TM_MODIFY: + SET16_A(ep->modify_time, t); + SET16_A(ep->modify_date, d); + break; + case TM_ACCESS: + SET16_A(ep->access_time, t); + SET16_A(ep->access_date, d); + break; + } +} + +s32 fat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir, s32 entry, + u32 type, u32 start_clu, u64 size) +{ + sector_t sector; + struct dos_dentry_t *dos_ep; + + dos_ep = (struct dos_dentry_t *)get_entry_in_dir(sb, p_dir, entry, + §or); + if (!dos_ep) + return FFS_MEDIAERR; + + init_dos_entry(dos_ep, type, start_clu); + buf_modify(sb, sector); + + return FFS_SUCCESS; +} + +s32 exfat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, u32 type, u32 start_clu, u64 size) +{ + sector_t sector; + u8 flags; + struct file_dentry_t *file_ep; + struct strm_dentry_t *strm_ep; + + flags = (type == TYPE_FILE) ? 0x01 : 0x03; + + /* we cannot use get_entry_set_in_dir here because file ep is not initialized yet */ + file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry, + §or); + if (!file_ep) + return FFS_MEDIAERR; + + strm_ep = (struct strm_dentry_t *)get_entry_in_dir(sb, p_dir, entry + 1, + §or); + if (!strm_ep) + return FFS_MEDIAERR; + + init_file_entry(file_ep, type); + buf_modify(sb, sector); + + init_strm_entry(strm_ep, flags, start_clu, size); + buf_modify(sb, sector); + + return FFS_SUCCESS; +} + +static s32 fat_init_ext_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 num_entries, + struct uni_name_t *p_uniname, + struct dos_name_t *p_dosname) +{ + int i; + sector_t sector; + u8 chksum; + u16 *uniname = p_uniname->name; + struct dos_dentry_t *dos_ep; + struct ext_dentry_t *ext_ep; + + dos_ep = (struct dos_dentry_t *)get_entry_in_dir(sb, p_dir, entry, + §or); + if (!dos_ep) + return FFS_MEDIAERR; + + dos_ep->lcase = p_dosname->name_case; + memcpy(dos_ep->name, p_dosname->name, DOS_NAME_LENGTH); + buf_modify(sb, sector); + + if ((--num_entries) > 0) { + chksum = calc_checksum_1byte((void *)dos_ep->name, + DOS_NAME_LENGTH, 0); + + for (i = 1; i < num_entries; i++) { + ext_ep = (struct ext_dentry_t *)get_entry_in_dir(sb, + p_dir, + entry - i, + §or); + if (!ext_ep) + return FFS_MEDIAERR; + + init_ext_entry(ext_ep, i, chksum, uniname); + buf_modify(sb, sector); + uniname += 13; + } + + ext_ep = (struct ext_dentry_t *)get_entry_in_dir(sb, p_dir, + entry - i, + §or); + if (!ext_ep) + return FFS_MEDIAERR; + + init_ext_entry(ext_ep, i + 0x40, chksum, uniname); + buf_modify(sb, sector); + } + + return FFS_SUCCESS; +} + +static s32 exfat_init_ext_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 num_entries, + struct uni_name_t *p_uniname, + struct dos_name_t *p_dosname) +{ + int i; + sector_t sector; + u16 *uniname = p_uniname->name; + struct file_dentry_t *file_ep; + struct strm_dentry_t *strm_ep; + struct name_dentry_t *name_ep; + + file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry, + §or); + if (!file_ep) + return FFS_MEDIAERR; + + file_ep->num_ext = (u8)(num_entries - 1); + buf_modify(sb, sector); + + strm_ep = (struct strm_dentry_t *)get_entry_in_dir(sb, p_dir, entry + 1, + §or); + if (!strm_ep) + return FFS_MEDIAERR; + + strm_ep->name_len = p_uniname->name_len; + SET16_A(strm_ep->name_hash, p_uniname->name_hash); + buf_modify(sb, sector); + + for (i = 2; i < num_entries; i++) { + name_ep = (struct name_dentry_t *)get_entry_in_dir(sb, p_dir, + entry + i, + §or); + if (!name_ep) + return FFS_MEDIAERR; + + init_name_entry(name_ep, uniname); + buf_modify(sb, sector); + uniname += 15; + } + + update_dir_checksum(sb, p_dir, entry); + + return FFS_SUCCESS; +} + +void init_dos_entry(struct dos_dentry_t *ep, u32 type, u32 start_clu) +{ + struct timestamp_t tm, *tp; + + fat_set_entry_type((struct dentry_t *)ep, type); + SET16_A(ep->start_clu_lo, CLUSTER_16(start_clu)); + SET16_A(ep->start_clu_hi, CLUSTER_16(start_clu >> 16)); + SET32_A(ep->size, 0); + + tp = tm_current(&tm); + fat_set_entry_time((struct dentry_t *)ep, tp, TM_CREATE); + fat_set_entry_time((struct dentry_t *)ep, tp, TM_MODIFY); + SET16_A(ep->access_date, 0); + ep->create_time_ms = 0; +} + +void init_ext_entry(struct ext_dentry_t *ep, s32 order, u8 chksum, u16 *uniname) +{ + int i; + bool end = false; + + fat_set_entry_type((struct dentry_t *)ep, TYPE_EXTEND); + ep->order = (u8)order; + ep->sysid = 0; + ep->checksum = chksum; + SET16_A(ep->start_clu, 0); + + for (i = 0; i < 10; i += 2) { + if (!end) { + SET16(ep->unicode_0_4 + i, *uniname); + if (*uniname == 0x0) + end = true; + else + uniname++; + } else { + SET16(ep->unicode_0_4 + i, 0xFFFF); + } + } + + for (i = 0; i < 12; i += 2) { + if (!end) { + SET16_A(ep->unicode_5_10 + i, *uniname); + if (*uniname == 0x0) + end = true; + else + uniname++; + } else { + SET16_A(ep->unicode_5_10 + i, 0xFFFF); + } + } + + for (i = 0; i < 4; i += 2) { + if (!end) { + SET16_A(ep->unicode_11_12 + i, *uniname); + if (*uniname == 0x0) + end = true; + else + uniname++; + } else { + SET16_A(ep->unicode_11_12 + i, 0xFFFF); + } + } +} + +void init_file_entry(struct file_dentry_t *ep, u32 type) +{ + struct timestamp_t tm, *tp; + + exfat_set_entry_type((struct dentry_t *)ep, type); + + tp = tm_current(&tm); + exfat_set_entry_time((struct dentry_t *)ep, tp, TM_CREATE); + exfat_set_entry_time((struct dentry_t *)ep, tp, TM_MODIFY); + exfat_set_entry_time((struct dentry_t *)ep, tp, TM_ACCESS); + ep->create_time_ms = 0; + ep->modify_time_ms = 0; + ep->access_time_ms = 0; +} + +void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu, u64 size) +{ + exfat_set_entry_type((struct dentry_t *)ep, TYPE_STREAM); + ep->flags = flags; + SET32_A(ep->start_clu, start_clu); + SET64_A(ep->valid_size, size); + SET64_A(ep->size, size); +} + +void init_name_entry(struct name_dentry_t *ep, u16 *uniname) +{ + int i; + + exfat_set_entry_type((struct dentry_t *)ep, TYPE_EXTEND); + ep->flags = 0x0; + + for (i = 0; i < 30; i++, i++) { + SET16_A(ep->unicode_0_14 + i, *uniname); + if (*uniname == 0x0) + break; + uniname++; + } +} + +void fat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 order, s32 num_entries) +{ + int i; + sector_t sector; + struct dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = num_entries - 1; i >= order; i--) { + ep = get_entry_in_dir(sb, p_dir, entry - i, §or); + if (!ep) + return; + + p_fs->fs_func->set_entry_type(ep, TYPE_DELETED); + buf_modify(sb, sector); + } +} + +void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir, + s32 entry, s32 order, s32 num_entries) +{ + int i; + sector_t sector; + struct dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = order; i < num_entries; i++) { + ep = get_entry_in_dir(sb, p_dir, entry + i, §or); + if (!ep) + return; + + p_fs->fs_func->set_entry_type(ep, TYPE_DELETED); + buf_modify(sb, sector); + } +} + +void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir, + s32 entry) +{ + int i, num_entries; + sector_t sector; + u16 chksum; + struct file_dentry_t *file_ep; + struct dentry_t *ep; + + file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry, + §or); + if (!file_ep) + return; + + buf_lock(sb, sector); + + num_entries = (s32)file_ep->num_ext + 1; + chksum = calc_checksum_2byte((void *)file_ep, DENTRY_SIZE, 0, + CS_DIR_ENTRY); + + for (i = 1; i < num_entries; i++) { + ep = get_entry_in_dir(sb, p_dir, entry + i, NULL); + if (!ep) { + buf_unlock(sb, sector); + return; + } + + chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum, + CS_DEFAULT); + } + + SET16_A(file_ep->checksum, chksum); + buf_modify(sb, sector); + buf_unlock(sb, sector); +} + +void update_dir_checksum_with_entry_set(struct super_block *sb, + struct entry_set_cache_t *es) +{ + struct dentry_t *ep; + u16 chksum = 0; + s32 chksum_type = CS_DIR_ENTRY, i; + + ep = (struct dentry_t *)&(es->__buf); + for (i = 0; i < es->num_entries; i++) { + pr_debug("%s ep %p\n", __func__, ep); + chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum, + chksum_type); + ep++; + chksum_type = CS_DEFAULT; + } + + ep = (struct dentry_t *)&(es->__buf); + SET16_A(((struct file_dentry_t *)ep)->checksum, chksum); + write_whole_entry_set(sb, es); +} + +static s32 _walk_fat_chain(struct super_block *sb, struct chain_t *p_dir, + s32 byte_offset, u32 *clu) +{ + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + s32 clu_offset; + u32 cur_clu; + + clu_offset = byte_offset >> p_fs->cluster_size_bits; + cur_clu = p_dir->dir; + + if (p_dir->flags == 0x03) { + cur_clu += clu_offset; + } else { + while (clu_offset > 0) { + if (FAT_read(sb, cur_clu, &cur_clu) == -1) + return FFS_MEDIAERR; + clu_offset--; + } + } + + if (clu) + *clu = cur_clu; + return FFS_SUCCESS; +} + +s32 find_location(struct super_block *sb, struct chain_t *p_dir, s32 entry, + sector_t *sector, s32 *offset) +{ + s32 off, ret; + u32 clu = 0; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + off = entry << DENTRY_SIZE_BITS; + + if (p_dir->dir == CLUSTER_32(0)) { /* FAT16 root_dir */ + *offset = off & p_bd->sector_size_mask; + *sector = off >> p_bd->sector_size_bits; + *sector += p_fs->root_start_sector; + } else { + ret = _walk_fat_chain(sb, p_dir, off, &clu); + if (ret != FFS_SUCCESS) + return ret; + + /* byte offset in cluster */ + off &= p_fs->cluster_size - 1; + + /* byte offset in sector */ + *offset = off & p_bd->sector_size_mask; + + /* sector offset in cluster */ + *sector = off >> p_bd->sector_size_bits; + *sector += START_SECTOR(clu); + } + return FFS_SUCCESS; +} + +struct dentry_t *get_entry_with_sector(struct super_block *sb, sector_t sector, + s32 offset) +{ + u8 *buf; + + buf = buf_getblk(sb, sector); + + if (!buf) + return NULL; + + return (struct dentry_t *)(buf + offset); +} + +struct dentry_t *get_entry_in_dir(struct super_block *sb, struct chain_t *p_dir, + s32 entry, sector_t *sector) +{ + s32 off; + sector_t sec; + u8 *buf; + + if (find_location(sb, p_dir, entry, &sec, &off) != FFS_SUCCESS) + return NULL; + + buf = buf_getblk(sb, sec); + + if (!buf) + return NULL; + + if (sector) + *sector = sec; + return (struct dentry_t *)(buf + off); +} + +/* returns a set of dentries for a file or dir. + * Note that this is a copy (dump) of dentries so that user should call write_entry_set() + * to apply changes made in this entry set to the real device. + * in: + * sb+p_dir+entry: indicates a file/dir + * type: specifies how many dentries should be included. + * out: + * file_ep: will point the first dentry(= file dentry) on success + * return: + * pointer of entry set on success, + * NULL on failure. + */ + +#define ES_MODE_STARTED 0 +#define ES_MODE_GET_FILE_ENTRY 1 +#define ES_MODE_GET_STRM_ENTRY 2 +#define ES_MODE_GET_NAME_ENTRY 3 +#define ES_MODE_GET_CRITICAL_SEC_ENTRY 4 +struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + u32 type, + struct dentry_t **file_ep) +{ + s32 off, ret, byte_offset; + u32 clu = 0; + sector_t sec; + u32 entry_type; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + struct entry_set_cache_t *es = NULL; + struct dentry_t *ep, *pos; + u8 *buf; + u8 num_entries; + s32 mode = ES_MODE_STARTED; + size_t bufsize; + + pr_debug("%s entered p_dir dir %u flags %x size %d\n", + __func__, p_dir->dir, p_dir->flags, p_dir->size); + + byte_offset = entry << DENTRY_SIZE_BITS; + ret = _walk_fat_chain(sb, p_dir, byte_offset, &clu); + if (ret != FFS_SUCCESS) + return NULL; + + /* byte offset in cluster */ + byte_offset &= p_fs->cluster_size - 1; + + /* byte offset in sector */ + off = byte_offset & p_bd->sector_size_mask; + + /* sector offset in cluster */ + sec = byte_offset >> p_bd->sector_size_bits; + sec += START_SECTOR(clu); + + buf = buf_getblk(sb, sec); + if (!buf) + goto err_out; + + ep = (struct dentry_t *)(buf + off); + entry_type = p_fs->fs_func->get_entry_type(ep); + + if ((entry_type != TYPE_FILE) + && (entry_type != TYPE_DIR)) + goto err_out; + + if (type == ES_ALL_ENTRIES) + num_entries = ((struct file_dentry_t *)ep)->num_ext + 1; + else + num_entries = type; + + bufsize = offsetof(struct entry_set_cache_t, __buf) + (num_entries) * + sizeof(struct dentry_t); + pr_debug("%s: trying to kmalloc %zx bytes for %d entries\n", __func__, + bufsize, num_entries); + es = kmalloc(bufsize, GFP_KERNEL); + if (!es) + goto err_out; + + es->num_entries = num_entries; + es->sector = sec; + es->offset = off; + es->alloc_flag = p_dir->flags; + + pos = (struct dentry_t *)&es->__buf; + + while (num_entries) { + /* + * instead of copying whole sector, we will check every entry. + * this will provide minimum stablity and consistency. + */ + entry_type = p_fs->fs_func->get_entry_type(ep); + + if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) + goto err_out; + + switch (mode) { + case ES_MODE_STARTED: + if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) + mode = ES_MODE_GET_FILE_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_FILE_ENTRY: + if (entry_type == TYPE_STREAM) + mode = ES_MODE_GET_STRM_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_STRM_ENTRY: + if (entry_type == TYPE_EXTEND) + mode = ES_MODE_GET_NAME_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_NAME_ENTRY: + if (entry_type == TYPE_EXTEND) + break; + else if (entry_type == TYPE_STREAM) + goto err_out; + else if (entry_type & TYPE_CRITICAL_SEC) + mode = ES_MODE_GET_CRITICAL_SEC_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_CRITICAL_SEC_ENTRY: + if ((entry_type == TYPE_EXTEND) || + (entry_type == TYPE_STREAM)) + goto err_out; + else if ((entry_type & TYPE_CRITICAL_SEC) != + TYPE_CRITICAL_SEC) + goto err_out; + break; + } + + memcpy(pos, ep, sizeof(struct dentry_t)); + + if (--num_entries == 0) + break; + + if (((off + DENTRY_SIZE) & p_bd->sector_size_mask) < + (off & p_bd->sector_size_mask)) { + /* get the next sector */ + if (IS_LAST_SECTOR_IN_CLUSTER(sec)) { + if (es->alloc_flag == 0x03) { + clu++; + } else { + if (FAT_read(sb, clu, &clu) == -1) + goto err_out; + } + sec = START_SECTOR(clu); + } else { + sec++; + } + buf = buf_getblk(sb, sec); + if (!buf) + goto err_out; + off = 0; + ep = (struct dentry_t *)(buf); + } else { + ep++; + off += DENTRY_SIZE; + } + pos++; + } + + if (file_ep) + *file_ep = (struct dentry_t *)&(es->__buf); + + pr_debug("%s exiting es %p sec %llu offset %d flags %d, num_entries %u buf ptr %p\n", + __func__, es, (unsigned long long)es->sector, es->offset, + es->alloc_flag, es->num_entries, &es->__buf); + return es; +err_out: + pr_debug("%s exited NULL (es %p)\n", __func__, es); + kfree(es); + return NULL; +} + +void release_entry_set(struct entry_set_cache_t *es) +{ + pr_debug("%s es=%p\n", __func__, es); + kfree(es); +} + +static s32 __write_partial_entries_in_entry_set(struct super_block *sb, + struct entry_set_cache_t *es, + sector_t sec, s32 off, u32 count) +{ + s32 num_entries, buf_off = (off - es->offset); + u32 remaining_byte_in_sector, copy_entries; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + u32 clu; + u8 *buf, *esbuf = (u8 *)&(es->__buf); + + pr_debug("%s entered es %p sec %llu off %d count %d\n", + __func__, es, (unsigned long long)sec, off, count); + num_entries = count; + + while (num_entries) { + /* white per sector base */ + remaining_byte_in_sector = (1 << p_bd->sector_size_bits) - off; + copy_entries = min_t(s32, + remaining_byte_in_sector >> DENTRY_SIZE_BITS, + num_entries); + buf = buf_getblk(sb, sec); + if (!buf) + goto err_out; + pr_debug("es->buf %p buf_off %u\n", esbuf, buf_off); + pr_debug("copying %d entries from %p to sector %llu\n", + copy_entries, (esbuf + buf_off), + (unsigned long long)sec); + memcpy(buf + off, esbuf + buf_off, + copy_entries << DENTRY_SIZE_BITS); + buf_modify(sb, sec); + num_entries -= copy_entries; + + if (num_entries) { + /* get next sector */ + if (IS_LAST_SECTOR_IN_CLUSTER(sec)) { + clu = GET_CLUSTER_FROM_SECTOR(sec); + if (es->alloc_flag == 0x03) { + clu++; + } else { + if (FAT_read(sb, clu, &clu) == -1) + goto err_out; + } + sec = START_SECTOR(clu); + } else { + sec++; + } + off = 0; + buf_off += copy_entries << DENTRY_SIZE_BITS; + } + } + + pr_debug("%s exited successfully\n", __func__); + return FFS_SUCCESS; +err_out: + pr_debug("%s failed\n", __func__); + return FFS_ERROR; +} + +/* write back all entries in entry set */ +s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es) +{ + return __write_partial_entries_in_entry_set(sb, es, es->sector, + es->offset, + es->num_entries); +} + +/* write back some entries in entry set */ +s32 write_partial_entries_in_entry_set(struct super_block *sb, + struct entry_set_cache_t *es, struct dentry_t *ep, u32 count) +{ + s32 ret, byte_offset, off; + u32 clu = 0; + sector_t sec; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + struct chain_t dir; + + /* vaidity check */ + if (ep + count > ((struct dentry_t *)&(es->__buf)) + es->num_entries) + return FFS_ERROR; + + dir.dir = GET_CLUSTER_FROM_SECTOR(es->sector); + dir.flags = es->alloc_flag; + dir.size = 0xffffffff; /* XXX */ + + byte_offset = (es->sector - START_SECTOR(dir.dir)) << + p_bd->sector_size_bits; + byte_offset += ((void **)ep - &(es->__buf)) + es->offset; + + ret = _walk_fat_chain(sb, &dir, byte_offset, &clu); + if (ret != FFS_SUCCESS) + return ret; + + /* byte offset in cluster */ + byte_offset &= p_fs->cluster_size - 1; + + /* byte offset in sector */ + off = byte_offset & p_bd->sector_size_mask; + + /* sector offset in cluster */ + sec = byte_offset >> p_bd->sector_size_bits; + sec += START_SECTOR(clu); + return __write_partial_entries_in_entry_set(sb, es, sec, off, count); +} + +/* search EMPTY CONTINUOUS "num_entries" entries */ +s32 search_deleted_or_unused_entry(struct super_block *sb, + struct chain_t *p_dir, s32 num_entries) +{ + int i, dentry, num_empty = 0; + s32 dentries_per_clu; + u32 type; + struct chain_t clu; + struct dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + if (p_fs->hint_uentry.dir == p_dir->dir) { + if (p_fs->hint_uentry.entry == -1) + return -1; + + clu.dir = p_fs->hint_uentry.clu.dir; + clu.size = p_fs->hint_uentry.clu.size; + clu.flags = p_fs->hint_uentry.clu.flags; + + dentry = p_fs->hint_uentry.entry; + } else { + p_fs->hint_uentry.entry = -1; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + dentry = 0; + } + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + i = dentry % dentries_per_clu; + else + i = dentry & (dentries_per_clu - 1); + + for (; i < dentries_per_clu; i++, dentry++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -1; + + type = p_fs->fs_func->get_entry_type(ep); + + if (type == TYPE_UNUSED) { + num_empty++; + if (p_fs->hint_uentry.entry == -1) { + p_fs->hint_uentry.dir = p_dir->dir; + p_fs->hint_uentry.entry = dentry; + + p_fs->hint_uentry.clu.dir = clu.dir; + p_fs->hint_uentry.clu.size = clu.size; + p_fs->hint_uentry.clu.flags = clu.flags; + } + } else if (type == TYPE_DELETED) { + num_empty++; + } else { + num_empty = 0; + } + + if (num_empty >= num_entries) { + p_fs->hint_uentry.dir = CLUSTER_32(~0); + p_fs->hint_uentry.entry = -1; + + if (p_fs->vol_type == EXFAT) + return dentry - (num_entries - 1); + else + return dentry; + } + } + + if (p_dir->dir == CLUSTER_32(0)) + break; /* FAT16 root_dir */ + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + return -1; + } + } + + return -1; +} + +s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_entries) +{ + s32 ret, dentry; + u32 last_clu; + sector_t sector; + u64 size = 0; + struct chain_t clu; + struct dentry_t *ep = NULL; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + return search_deleted_or_unused_entry(sb, p_dir, num_entries); + + while ((dentry = search_deleted_or_unused_entry(sb, p_dir, num_entries)) < 0) { + if (p_fs->dev_ejected) + break; + + if (p_fs->vol_type == EXFAT) { + if (p_dir->dir != p_fs->root_dir) + size = i_size_read(inode); + } + + last_clu = find_last_cluster(sb, p_dir); + clu.dir = last_clu + 1; + clu.size = 0; + clu.flags = p_dir->flags; + + /* (1) allocate a cluster */ + ret = p_fs->fs_func->alloc_cluster(sb, 1, &clu); + if (ret < 1) + return -1; + + if (clear_cluster(sb, clu.dir) != FFS_SUCCESS) + return -1; + + /* (2) append to the FAT chain */ + if (clu.flags != p_dir->flags) { + exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size); + p_dir->flags = 0x01; + p_fs->hint_uentry.clu.flags = 0x01; + } + if (clu.flags == 0x01) + if (FAT_write(sb, last_clu, clu.dir) < 0) + return -1; + + if (p_fs->hint_uentry.entry == -1) { + p_fs->hint_uentry.dir = p_dir->dir; + p_fs->hint_uentry.entry = p_dir->size << (p_fs->cluster_size_bits - DENTRY_SIZE_BITS); + + p_fs->hint_uentry.clu.dir = clu.dir; + p_fs->hint_uentry.clu.size = 0; + p_fs->hint_uentry.clu.flags = clu.flags; + } + p_fs->hint_uentry.clu.size++; + p_dir->size++; + + /* (3) update the directory entry */ + if (p_fs->vol_type == EXFAT) { + if (p_dir->dir != p_fs->root_dir) { + size += p_fs->cluster_size; + + ep = get_entry_in_dir(sb, &fid->dir, + fid->entry + 1, §or); + if (!ep) + return -1; + p_fs->fs_func->set_entry_size(ep, size); + p_fs->fs_func->set_entry_flag(ep, p_dir->flags); + buf_modify(sb, sector); + + update_dir_checksum(sb, &(fid->dir), + fid->entry); + } + } + + i_size_write(inode, i_size_read(inode) + p_fs->cluster_size); + EXFAT_I(inode)->mmu_private += p_fs->cluster_size; + EXFAT_I(inode)->fid.size += p_fs->cluster_size; + EXFAT_I(inode)->fid.flags = p_dir->flags; + inode->i_blocks += 1 << (p_fs->cluster_size_bits - 9); + } + + return dentry; +} + +/* return values of fat_find_dir_entry() + * >= 0 : return dir entiry position with the name in dir + * -1 : (root dir, ".") it is the root dir itself + * -2 : entry with the name does not exist + */ +s32 fat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir, + struct uni_name_t *p_uniname, s32 num_entries, + struct dos_name_t *p_dosname, u32 type) +{ + int i, dentry = 0, len; + s32 order = 0; + bool is_feasible_entry = true, has_ext_entry = false; + s32 dentries_per_clu; + u32 entry_type; + u16 entry_uniname[14], *uniname = NULL, unichar; + struct chain_t clu; + struct dentry_t *ep; + struct dos_dentry_t *dos_ep; + struct ext_dentry_t *ext_ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == p_fs->root_dir) { + if ((!nls_uniname_cmp(sb, p_uniname->name, + (u16 *)UNI_CUR_DIR_NAME)) || + (!nls_uniname_cmp(sb, p_uniname->name, + (u16 *)UNI_PAR_DIR_NAME))) + return -1; // special case, root directory itself + } + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++, dentry++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -2; + + entry_type = p_fs->fs_func->get_entry_type(ep); + + if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) { + if ((type == TYPE_ALL) || (type == entry_type)) { + if (is_feasible_entry && has_ext_entry) + return dentry; + + dos_ep = (struct dos_dentry_t *)ep; + if (!nls_dosname_cmp(sb, p_dosname->name, dos_ep->name)) + return dentry; + } + is_feasible_entry = true; + has_ext_entry = false; + } else if (entry_type == TYPE_EXTEND) { + if (is_feasible_entry) { + ext_ep = (struct ext_dentry_t *)ep; + if (ext_ep->order > 0x40) { + order = (s32)(ext_ep->order - 0x40); + uniname = p_uniname->name + 13 * (order - 1); + } else { + order = (s32)ext_ep->order; + uniname -= 13; + } + + len = extract_uni_name_from_ext_entry(ext_ep, entry_uniname, order); + + unichar = *(uniname + len); + *(uniname + len) = 0x0; + + if (nls_uniname_cmp(sb, uniname, entry_uniname)) + is_feasible_entry = false; + + *(uniname + len) = unichar; + } + has_ext_entry = true; + } else if (entry_type == TYPE_UNUSED) { + return -2; + } + is_feasible_entry = true; + has_ext_entry = false; + } + + if (p_dir->dir == CLUSTER_32(0)) + break; /* FAT16 root_dir */ + + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + return -2; + } + + return -2; +} + +/* return values of exfat_find_dir_entry() + * >= 0 : return dir entiry position with the name in dir + * -1 : (root dir, ".") it is the root dir itself + * -2 : entry with the name does not exist + */ +s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir, + struct uni_name_t *p_uniname, s32 num_entries, + struct dos_name_t *p_dosname, u32 type) +{ + int i = 0, dentry = 0, num_ext_entries = 0, len, step; + s32 order = 0; + bool is_feasible_entry = false; + s32 dentries_per_clu, num_empty = 0; + u32 entry_type; + u16 entry_uniname[16], *uniname = NULL, unichar; + struct chain_t clu; + struct dentry_t *ep; + struct file_dentry_t *file_ep; + struct strm_dentry_t *strm_ep; + struct name_dentry_t *name_ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == p_fs->root_dir) { + if ((!nls_uniname_cmp(sb, p_uniname->name, + (u16 *)UNI_CUR_DIR_NAME)) || + (!nls_uniname_cmp(sb, p_uniname->name, + (u16 *)UNI_PAR_DIR_NAME))) + return -1; // special case, root directory itself + } + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + p_fs->hint_uentry.dir = p_dir->dir; + p_fs->hint_uentry.entry = -1; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + while (i < dentries_per_clu) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -2; + + entry_type = p_fs->fs_func->get_entry_type(ep); + step = 1; + + if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) { + is_feasible_entry = false; + + if (p_fs->hint_uentry.entry == -1) { + num_empty++; + + if (num_empty == 1) { + p_fs->hint_uentry.clu.dir = clu.dir; + p_fs->hint_uentry.clu.size = clu.size; + p_fs->hint_uentry.clu.flags = clu.flags; + } + if ((num_empty >= num_entries) || (entry_type == TYPE_UNUSED)) + p_fs->hint_uentry.entry = dentry - (num_empty - 1); + } + + if (entry_type == TYPE_UNUSED) + return -2; + } else { + num_empty = 0; + + if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) { + file_ep = (struct file_dentry_t *)ep; + if ((type == TYPE_ALL) || (type == entry_type)) { + num_ext_entries = file_ep->num_ext; + is_feasible_entry = true; + } else { + is_feasible_entry = false; + step = file_ep->num_ext + 1; + } + } else if (entry_type == TYPE_STREAM) { + if (is_feasible_entry) { + strm_ep = (struct strm_dentry_t *)ep; + if (p_uniname->name_hash == GET16_A(strm_ep->name_hash) && + p_uniname->name_len == strm_ep->name_len) { + order = 1; + } else { + is_feasible_entry = false; + step = num_ext_entries; + } + } + } else if (entry_type == TYPE_EXTEND) { + if (is_feasible_entry) { + name_ep = (struct name_dentry_t *)ep; + + if ((++order) == 2) + uniname = p_uniname->name; + else + uniname += 15; + + len = extract_uni_name_from_name_entry(name_ep, + entry_uniname, order); + + unichar = *(uniname + len); + *(uniname + len) = 0x0; + + if (nls_uniname_cmp(sb, uniname, entry_uniname)) { + is_feasible_entry = false; + step = num_ext_entries - order + 1; + } else if (order == num_ext_entries) { + p_fs->hint_uentry.dir = CLUSTER_32(~0); + p_fs->hint_uentry.entry = -1; + return dentry - (num_ext_entries); + } + + *(uniname + len) = unichar; + } + } else { + is_feasible_entry = false; + } + } + + i += step; + dentry += step; + } + + i -= dentries_per_clu; + + if (p_dir->dir == CLUSTER_32(0)) + break; /* FAT16 root_dir */ + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + return -2; + } + } + + return -2; +} + +s32 fat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir, + s32 entry, struct dentry_t *p_entry) +{ + s32 count = 0; + u8 chksum; + struct dos_dentry_t *dos_ep = (struct dos_dentry_t *)p_entry; + struct ext_dentry_t *ext_ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + chksum = calc_checksum_1byte((void *)dos_ep->name, DOS_NAME_LENGTH, 0); + + for (entry--; entry >= 0; entry--) { + ext_ep = (struct ext_dentry_t *)get_entry_in_dir(sb, p_dir, + entry, NULL); + if (!ext_ep) + return -1; + + if ((p_fs->fs_func->get_entry_type((struct dentry_t *)ext_ep) == + TYPE_EXTEND) && (ext_ep->checksum == chksum)) { + count++; + if (ext_ep->order > 0x40) + return count; + } else { + return count; + } + } + + return count; +} + +s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir, + s32 entry, struct dentry_t *p_entry) +{ + int i, count = 0; + u32 type; + struct file_dentry_t *file_ep = (struct file_dentry_t *)p_entry; + struct dentry_t *ext_ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = 0, entry++; i < file_ep->num_ext; i++, entry++) { + ext_ep = get_entry_in_dir(sb, p_dir, entry, NULL); + if (!ext_ep) + return -1; + + type = p_fs->fs_func->get_entry_type(ext_ep); + if ((type == TYPE_EXTEND) || (type == TYPE_STREAM)) + count++; + else + return count; + } + + return count; +} + +s32 count_dos_name_entries(struct super_block *sb, struct chain_t *p_dir, + u32 type) +{ + int i, count = 0; + s32 dentries_per_clu; + u32 entry_type; + struct chain_t clu; + struct dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -1; + + entry_type = p_fs->fs_func->get_entry_type(ep); + + if (entry_type == TYPE_UNUSED) + return count; + if (!(type & TYPE_CRITICAL_PRI) && + !(type & TYPE_BENIGN_PRI)) + continue; + + if ((type == TYPE_ALL) || (type == entry_type)) + count++; + } + + if (p_dir->dir == CLUSTER_32(0)) + break; /* FAT16 root_dir */ + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + return -1; + } + } + + return count; +} + +bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir) +{ + int i, count = 0; + s32 dentries_per_clu; + u32 type; + struct chain_t clu; + struct dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + break; + + type = p_fs->fs_func->get_entry_type(ep); + + if (type == TYPE_UNUSED) + return true; + if ((type != TYPE_FILE) && (type != TYPE_DIR)) + continue; + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + return false; + + if (p_fs->vol_type == EXFAT) + return false; + if ((p_dir->dir == p_fs->root_dir) || ((++count) > 2)) + return false; + } + + if (p_dir->dir == CLUSTER_32(0)) + break; /* FAT16 root_dir */ + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + break; + } + + return true; +} + +/* + * Name Conversion Functions + */ + +/* input : dir, uni_name + * output : num_of_entry, dos_name(format : aaaaaa~1.bbb) + */ +s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir, + struct uni_name_t *p_uniname, s32 *entries, + struct dos_name_t *p_dosname) +{ + s32 ret, num_entries; + bool lossy = false; + char **r; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + num_entries = p_fs->fs_func->calc_num_entries(p_uniname); + if (num_entries == 0) + return FFS_INVALIDPATH; + + if (p_fs->vol_type != EXFAT) { + nls_uniname_to_dosname(sb, p_dosname, p_uniname, &lossy); + + if (lossy) { + ret = fat_generate_dos_name(sb, p_dir, p_dosname); + if (ret) + return ret; + } else { + for (r = reserved_names; *r; r++) { + if (!strncmp((void *)p_dosname->name, *r, 8)) + return FFS_INVALIDPATH; + } + + if (p_dosname->name_case != 0xFF) + num_entries = 1; + } + + if (num_entries > 1) + p_dosname->name_case = 0x0; + } + + *entries = num_entries; + + return FFS_SUCCESS; +} + +void get_uni_name_from_dos_entry(struct super_block *sb, + struct dos_dentry_t *ep, + struct uni_name_t *p_uniname, u8 mode) +{ + struct dos_name_t dos_name; + + if (mode == 0x0) + dos_name.name_case = 0x0; + else + dos_name.name_case = ep->lcase; + + memcpy(dos_name.name, ep->name, DOS_NAME_LENGTH); + nls_dosname_to_uniname(sb, p_uniname, &dos_name); +} + +void fat_get_uni_name_from_ext_entry(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + u16 *uniname) +{ + int i; + struct ext_dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (entry--, i = 1; entry >= 0; entry--, i++) { + ep = (struct ext_dentry_t *)get_entry_in_dir(sb, p_dir, entry, + NULL); + if (!ep) + return; + + if (p_fs->fs_func->get_entry_type((struct dentry_t *)ep) == + TYPE_EXTEND) { + extract_uni_name_from_ext_entry(ep, uniname, i); + if (ep->order > 0x40) + return; + } else { + return; + } + + uniname += 13; + } +} + +void exfat_get_uni_name_from_ext_entry(struct super_block *sb, + struct chain_t *p_dir, s32 entry, + u16 *uniname) +{ + int i; + struct dentry_t *ep; + struct entry_set_cache_t *es; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + es = get_entry_set_in_dir(sb, p_dir, entry, ES_ALL_ENTRIES, &ep); + if (!es || es->num_entries < 3) { + if (es) + release_entry_set(es); + return; + } + + ep += 2; + + /* + * First entry : file entry + * Second entry : stream-extension entry + * Third entry : first file-name entry + * So, the index of first file-name dentry should start from 2. + */ + for (i = 2; i < es->num_entries; i++, ep++) { + if (p_fs->fs_func->get_entry_type(ep) == TYPE_EXTEND) + extract_uni_name_from_name_entry((struct name_dentry_t *) + ep, uniname, i); + else + goto out; + uniname += 15; + } + +out: + release_entry_set(es); +} + +s32 extract_uni_name_from_ext_entry(struct ext_dentry_t *ep, u16 *uniname, + s32 order) +{ + int i, len = 0; + + for (i = 0; i < 10; i += 2) { + *uniname = GET16(ep->unicode_0_4 + i); + if (*uniname == 0x0) + return len; + uniname++; + len++; + } + + if (order < 20) { + for (i = 0; i < 12; i += 2) { + *uniname = GET16_A(ep->unicode_5_10 + i); + if (*uniname == 0x0) + return len; + uniname++; + len++; + } + } else { + for (i = 0; i < 8; i += 2) { + *uniname = GET16_A(ep->unicode_5_10 + i); + if (*uniname == 0x0) + return len; + uniname++; + len++; + } + *uniname = 0x0; /* uniname[MAX_NAME_LENGTH-1] */ + return len; + } + + for (i = 0; i < 4; i += 2) { + *uniname = GET16_A(ep->unicode_11_12 + i); + if (*uniname == 0x0) + return len; + uniname++; + len++; + } + + *uniname = 0x0; + return len; +} + +s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *uniname, + s32 order) +{ + int i, len = 0; + + for (i = 0; i < 30; i += 2) { + *uniname = GET16_A(ep->unicode_0_14 + i); + if (*uniname == 0x0) + return len; + uniname++; + len++; + } + + *uniname = 0x0; + return len; +} + +s32 fat_generate_dos_name(struct super_block *sb, struct chain_t *p_dir, + struct dos_name_t *p_dosname) +{ + int i, j, count = 0; + bool count_begin = false; + s32 dentries_per_clu; + u32 type; + u8 bmap[128/* 1 ~ 1023 */]; + struct chain_t clu; + struct dos_dentry_t *ep; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + memset(bmap, 0, sizeof(bmap)); + exfat_bitmap_set(bmap, 0); + + if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */ + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++) { + ep = (struct dos_dentry_t *)get_entry_in_dir(sb, &clu, + i, NULL); + if (!ep) + return FFS_MEDIAERR; + + type = p_fs->fs_func->get_entry_type((struct dentry_t *) + ep); + + if (type == TYPE_UNUSED) + break; + if ((type != TYPE_FILE) && (type != TYPE_DIR)) + continue; + + count = 0; + count_begin = false; + + for (j = 0; j < 8; j++) { + if (ep->name[j] == ' ') + break; + + if (ep->name[j] == '~') { + count_begin = true; + } else if (count_begin) { + if ((ep->name[j] >= '0') && + (ep->name[j] <= '9')) { + count = count * 10 + + (ep->name[j] - '0'); + } else { + count = 0; + count_begin = false; + } + } + } + + if ((count > 0) && (count < 1024)) + exfat_bitmap_set(bmap, count); + } + + if (p_dir->dir == CLUSTER_32(0)) + break; /* FAT16 root_dir */ + + if (FAT_read(sb, clu.dir, &clu.dir) != 0) + return FFS_MEDIAERR; + } + + count = 0; + for (i = 0; i < 128; i++) { + if (bmap[i] != 0xFF) { + for (j = 0; j < 8; j++) { + if (exfat_bitmap_test(&bmap[i], j) == 0) { + count = (i << 3) + j; + break; + } + } + if (count != 0) + break; + } + } + + if ((count == 0) || (count >= 1024)) + return FFS_FILEEXIST; + fat_attach_count_to_dos_name(p_dosname->name, count); + + /* Now dos_name has DOS~????.EXT */ + return FFS_SUCCESS; +} + +void fat_attach_count_to_dos_name(u8 *dosname, s32 count) +{ + int i, j, length; + char str_count[6]; + + snprintf(str_count, sizeof(str_count), "~%d", count); + length = strlen(str_count); + + i = 0; + j = 0; + while (j <= (8 - length)) { + i = j; + if (dosname[j] == ' ') + break; + if (dosname[j] & 0x80) + j += 2; + else + j++; + } + + for (j = 0; j < length; i++, j++) + dosname[i] = (u8)str_count[j]; + + if (i == 7) + dosname[7] = ' '; +} + +s32 fat_calc_num_entries(struct uni_name_t *p_uniname) +{ + s32 len; + + len = p_uniname->name_len; + if (len == 0) + return 0; + + /* 1 dos name entry + extended entries */ + return (len - 1) / 13 + 2; +} + +s32 exfat_calc_num_entries(struct uni_name_t *p_uniname) +{ + s32 len; + + len = p_uniname->name_len; + if (len == 0) + return 0; + + /* 1 file entry + 1 stream entry + name entries */ + return (len - 1) / 15 + 3; +} + +u8 calc_checksum_1byte(void *data, s32 len, u8 chksum) +{ + int i; + u8 *c = (u8 *)data; + + for (i = 0; i < len; i++, c++) + chksum = (((chksum & 1) << 7) | ((chksum & 0xFE) >> 1)) + *c; + + return chksum; +} + +u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type) +{ + int i; + u8 *c = (u8 *)data; + + switch (type) { + case CS_DIR_ENTRY: + for (i = 0; i < len; i++, c++) { + if ((i == 2) || (i == 3)) + continue; + chksum = (((chksum & 1) << 15) | + ((chksum & 0xFFFE) >> 1)) + (u16)*c; + } + break; + default + : + for (i = 0; i < len; i++, c++) + chksum = (((chksum & 1) << 15) | + ((chksum & 0xFFFE) >> 1)) + (u16)*c; + } + + return chksum; +} + +u32 calc_checksum_4byte(void *data, s32 len, u32 chksum, s32 type) +{ + int i; + u8 *c = (u8 *)data; + + switch (type) { + case CS_PBR_SECTOR: + for (i = 0; i < len; i++, c++) { + if ((i == 106) || (i == 107) || (i == 112)) + continue; + chksum = (((chksum & 1) << 31) | + ((chksum & 0xFFFFFFFE) >> 1)) + (u32)*c; + } + break; + default + : + for (i = 0; i < len; i++, c++) + chksum = (((chksum & 1) << 31) | + ((chksum & 0xFFFFFFFE) >> 1)) + (u32)*c; + } + + return chksum; +} + +/* + * Name Resolution Functions + */ + +/* return values of resolve_path() + * > 0 : return the length of the path + * < 0 : return error + */ +s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir, + struct uni_name_t *p_uniname) +{ + bool lossy = false; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + + if (strscpy(name_buf, path, sizeof(name_buf)) < 0) + return FFS_INVALIDPATH; + + nls_cstring_to_uniname(sb, p_uniname, name_buf, &lossy); + if (lossy) + return FFS_INVALIDPATH; + + fid->size = i_size_read(inode); + + p_dir->dir = fid->start_clu; + p_dir->size = (s32)(fid->size >> p_fs->cluster_size_bits); + p_dir->flags = fid->flags; + + return FFS_SUCCESS; +} + +/* + * File Operation Functions + */ +static struct fs_func fat_fs_func = { + .alloc_cluster = fat_alloc_cluster, + .free_cluster = fat_free_cluster, + .count_used_clusters = fat_count_used_clusters, + + .init_dir_entry = fat_init_dir_entry, + .init_ext_entry = fat_init_ext_entry, + .find_dir_entry = fat_find_dir_entry, + .delete_dir_entry = fat_delete_dir_entry, + .get_uni_name_from_ext_entry = fat_get_uni_name_from_ext_entry, + .count_ext_entries = fat_count_ext_entries, + .calc_num_entries = fat_calc_num_entries, + + .get_entry_type = fat_get_entry_type, + .set_entry_type = fat_set_entry_type, + .get_entry_attr = fat_get_entry_attr, + .set_entry_attr = fat_set_entry_attr, + .get_entry_flag = fat_get_entry_flag, + .set_entry_flag = fat_set_entry_flag, + .get_entry_clu0 = fat_get_entry_clu0, + .set_entry_clu0 = fat_set_entry_clu0, + .get_entry_size = fat_get_entry_size, + .set_entry_size = fat_set_entry_size, + .get_entry_time = fat_get_entry_time, + .set_entry_time = fat_set_entry_time, +}; + +s32 fat16_mount(struct super_block *sb, struct pbr_sector_t *p_pbr) +{ + s32 num_reserved, num_root_sectors; + struct bpb16_t *p_bpb = (struct bpb16_t *)p_pbr->bpb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bpb->num_fats == 0) + return FFS_FORMATERR; + + num_root_sectors = GET16(p_bpb->num_root_entries) << DENTRY_SIZE_BITS; + num_root_sectors = ((num_root_sectors - 1) >> + p_bd->sector_size_bits) + 1; + + p_fs->sectors_per_clu = p_bpb->sectors_per_clu; + p_fs->sectors_per_clu_bits = ilog2(p_bpb->sectors_per_clu); + p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits + + p_bd->sector_size_bits; + p_fs->cluster_size = 1 << p_fs->cluster_size_bits; + + p_fs->num_FAT_sectors = GET16(p_bpb->num_fat_sectors); + + p_fs->FAT1_start_sector = p_fs->PBR_sector + GET16(p_bpb->num_reserved); + if (p_bpb->num_fats == 1) + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector; + else + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector + + p_fs->num_FAT_sectors; + + p_fs->root_start_sector = p_fs->FAT2_start_sector + + p_fs->num_FAT_sectors; + p_fs->data_start_sector = p_fs->root_start_sector + num_root_sectors; + + p_fs->num_sectors = GET16(p_bpb->num_sectors); + if (p_fs->num_sectors == 0) + p_fs->num_sectors = GET32(p_bpb->num_huge_sectors); + + num_reserved = p_fs->data_start_sector - p_fs->PBR_sector; + p_fs->num_clusters = ((p_fs->num_sectors - num_reserved) >> + p_fs->sectors_per_clu_bits) + 2; + /* because the cluster index starts with 2 */ + + if (p_fs->num_clusters < FAT12_THRESHOLD) + p_fs->vol_type = FAT12; + else + p_fs->vol_type = FAT16; + p_fs->vol_id = GET32(p_bpb->vol_serial); + + p_fs->root_dir = 0; + p_fs->dentries_in_root = GET16(p_bpb->num_root_entries); + p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits - + DENTRY_SIZE_BITS); + + p_fs->vol_flag = VOL_CLEAN; + p_fs->clu_srch_ptr = 2; + p_fs->used_clusters = UINT_MAX; + + p_fs->fs_func = &fat_fs_func; + + return FFS_SUCCESS; +} + +s32 fat32_mount(struct super_block *sb, struct pbr_sector_t *p_pbr) +{ + s32 num_reserved; + struct bpb32_t *p_bpb = (struct bpb32_t *)p_pbr->bpb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bpb->num_fats == 0) + return FFS_FORMATERR; + + p_fs->sectors_per_clu = p_bpb->sectors_per_clu; + p_fs->sectors_per_clu_bits = ilog2(p_bpb->sectors_per_clu); + p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits + + p_bd->sector_size_bits; + p_fs->cluster_size = 1 << p_fs->cluster_size_bits; + + p_fs->num_FAT_sectors = GET32(p_bpb->num_fat32_sectors); + + p_fs->FAT1_start_sector = p_fs->PBR_sector + GET16(p_bpb->num_reserved); + if (p_bpb->num_fats == 1) + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector; + else + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector + + p_fs->num_FAT_sectors; + + p_fs->root_start_sector = p_fs->FAT2_start_sector + + p_fs->num_FAT_sectors; + p_fs->data_start_sector = p_fs->root_start_sector; + + p_fs->num_sectors = GET32(p_bpb->num_huge_sectors); + num_reserved = p_fs->data_start_sector - p_fs->PBR_sector; + + p_fs->num_clusters = ((p_fs->num_sectors - num_reserved) >> + p_fs->sectors_per_clu_bits) + 2; + /* because the cluster index starts with 2 */ + + p_fs->vol_type = FAT32; + p_fs->vol_id = GET32(p_bpb->vol_serial); + + p_fs->root_dir = GET32(p_bpb->root_cluster); + p_fs->dentries_in_root = 0; + p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits - + DENTRY_SIZE_BITS); + + p_fs->vol_flag = VOL_CLEAN; + p_fs->clu_srch_ptr = 2; + p_fs->used_clusters = UINT_MAX; + + p_fs->fs_func = &fat_fs_func; + + return FFS_SUCCESS; +} + +static struct fs_func exfat_fs_func = { + .alloc_cluster = exfat_alloc_cluster, + .free_cluster = exfat_free_cluster, + .count_used_clusters = exfat_count_used_clusters, + + .init_dir_entry = exfat_init_dir_entry, + .init_ext_entry = exfat_init_ext_entry, + .find_dir_entry = exfat_find_dir_entry, + .delete_dir_entry = exfat_delete_dir_entry, + .get_uni_name_from_ext_entry = exfat_get_uni_name_from_ext_entry, + .count_ext_entries = exfat_count_ext_entries, + .calc_num_entries = exfat_calc_num_entries, + + .get_entry_type = exfat_get_entry_type, + .set_entry_type = exfat_set_entry_type, + .get_entry_attr = exfat_get_entry_attr, + .set_entry_attr = exfat_set_entry_attr, + .get_entry_flag = exfat_get_entry_flag, + .set_entry_flag = exfat_set_entry_flag, + .get_entry_clu0 = exfat_get_entry_clu0, + .set_entry_clu0 = exfat_set_entry_clu0, + .get_entry_size = exfat_get_entry_size, + .set_entry_size = exfat_set_entry_size, + .get_entry_time = exfat_get_entry_time, + .set_entry_time = exfat_set_entry_time, +}; + +s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr) +{ + struct bpbex_t *p_bpb = (struct bpbex_t *)p_pbr->bpb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bpb->num_fats == 0) + return FFS_FORMATERR; + + p_fs->sectors_per_clu = 1 << p_bpb->sectors_per_clu_bits; + p_fs->sectors_per_clu_bits = p_bpb->sectors_per_clu_bits; + p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits + + p_bd->sector_size_bits; + p_fs->cluster_size = 1 << p_fs->cluster_size_bits; + + p_fs->num_FAT_sectors = GET32(p_bpb->fat_length); + + p_fs->FAT1_start_sector = p_fs->PBR_sector + GET32(p_bpb->fat_offset); + if (p_bpb->num_fats == 1) + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector; + else + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector + + p_fs->num_FAT_sectors; + + p_fs->root_start_sector = p_fs->PBR_sector + GET32(p_bpb->clu_offset); + p_fs->data_start_sector = p_fs->root_start_sector; + + p_fs->num_sectors = GET64(p_bpb->vol_length); + p_fs->num_clusters = GET32(p_bpb->clu_count) + 2; + /* because the cluster index starts with 2 */ + + p_fs->vol_type = EXFAT; + p_fs->vol_id = GET32(p_bpb->vol_serial); + + p_fs->root_dir = GET32(p_bpb->root_cluster); + p_fs->dentries_in_root = 0; + p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits - + DENTRY_SIZE_BITS); + + p_fs->vol_flag = (u32)GET16(p_bpb->vol_flags); + p_fs->clu_srch_ptr = 2; + p_fs->used_clusters = UINT_MAX; + + p_fs->fs_func = &exfat_fs_func; + + return FFS_SUCCESS; +} + +s32 create_dir(struct inode *inode, struct chain_t *p_dir, + struct uni_name_t *p_uniname, struct file_id_t *fid) +{ + s32 ret, dentry, num_entries; + u64 size; + struct chain_t clu; + struct dos_name_t dos_name, dot_name; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct fs_func *fs_func = p_fs->fs_func; + + ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries, + &dos_name); + if (ret) + return ret; + + /* find_empty_entry must be called before alloc_cluster */ + dentry = find_empty_entry(inode, p_dir, num_entries); + if (dentry < 0) + return FFS_FULL; + + clu.dir = CLUSTER_32(~0); + clu.size = 0; + clu.flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + + /* (1) allocate a cluster */ + ret = fs_func->alloc_cluster(sb, 1, &clu); + if (ret < 0) + return FFS_MEDIAERR; + else if (ret == 0) + return FFS_FULL; + + ret = clear_cluster(sb, clu.dir); + if (ret != FFS_SUCCESS) + return ret; + + if (p_fs->vol_type == EXFAT) { + size = p_fs->cluster_size; + } else { + size = 0; + + /* initialize the . and .. entry + * Information for . points to itself + * Information for .. points to parent dir + */ + + dot_name.name_case = 0x0; + memcpy(dot_name.name, DOS_CUR_DIR_NAME, DOS_NAME_LENGTH); + + ret = fs_func->init_dir_entry(sb, &clu, 0, TYPE_DIR, clu.dir, + 0); + if (ret != FFS_SUCCESS) + return ret; + + ret = fs_func->init_ext_entry(sb, &clu, 0, 1, NULL, &dot_name); + if (ret != FFS_SUCCESS) + return ret; + + memcpy(dot_name.name, DOS_PAR_DIR_NAME, DOS_NAME_LENGTH); + + if (p_dir->dir == p_fs->root_dir) + ret = fs_func->init_dir_entry(sb, &clu, 1, TYPE_DIR, + CLUSTER_32(0), 0); + else + ret = fs_func->init_dir_entry(sb, &clu, 1, TYPE_DIR, + p_dir->dir, 0); + + if (ret != FFS_SUCCESS) + return ret; + + ret = p_fs->fs_func->init_ext_entry(sb, &clu, 1, 1, NULL, + &dot_name); + if (ret != FFS_SUCCESS) + return ret; + } + + /* (2) update the directory entry */ + /* make sub-dir entry in parent directory */ + ret = fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_DIR, clu.dir, + size); + if (ret != FFS_SUCCESS) + return ret; + + ret = fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname, + &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + fid->dir.dir = p_dir->dir; + fid->dir.size = p_dir->size; + fid->dir.flags = p_dir->flags; + fid->entry = dentry; + + fid->attr = ATTR_SUBDIR; + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->size = size; + fid->start_clu = clu.dir; + + fid->type = TYPE_DIR; + fid->rwoffset = 0; + fid->hint_last_off = -1; + + return FFS_SUCCESS; +} + +s32 create_file(struct inode *inode, struct chain_t *p_dir, + struct uni_name_t *p_uniname, u8 mode, struct file_id_t *fid) +{ + s32 ret, dentry, num_entries; + struct dos_name_t dos_name; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct fs_func *fs_func = p_fs->fs_func; + + ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries, + &dos_name); + if (ret) + return ret; + + /* find_empty_entry must be called before alloc_cluster() */ + dentry = find_empty_entry(inode, p_dir, num_entries); + if (dentry < 0) + return FFS_FULL; + + /* (1) update the directory entry */ + /* fill the dos name directory entry information of the created file. + * the first cluster is not determined yet. (0) + */ + ret = fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_FILE | mode, + CLUSTER_32(0), 0); + if (ret != FFS_SUCCESS) + return ret; + + ret = fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname, + &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + fid->dir.dir = p_dir->dir; + fid->dir.size = p_dir->size; + fid->dir.flags = p_dir->flags; + fid->entry = dentry; + + fid->attr = ATTR_ARCHIVE | mode; + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->size = 0; + fid->start_clu = CLUSTER_32(~0); + + fid->type = TYPE_FILE; + fid->rwoffset = 0; + fid->hint_last_off = -1; + + return FFS_SUCCESS; +} + +void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry) +{ + s32 num_entries; + sector_t sector; + struct dentry_t *ep; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct fs_func *fs_func = p_fs->fs_func; + + ep = get_entry_in_dir(sb, p_dir, entry, §or); + if (!ep) + return; + + buf_lock(sb, sector); + + /* buf_lock() before call count_ext_entries() */ + num_entries = fs_func->count_ext_entries(sb, p_dir, entry, ep); + if (num_entries < 0) { + buf_unlock(sb, sector); + return; + } + num_entries++; + + buf_unlock(sb, sector); + + /* (1) update the directory entry */ + fs_func->delete_dir_entry(sb, p_dir, entry, 0, num_entries); +} + +s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry, + struct uni_name_t *p_uniname, struct file_id_t *fid) +{ + s32 ret, newentry = -1, num_old_entries, num_new_entries; + sector_t sector_old, sector_new; + struct dos_name_t dos_name; + struct dentry_t *epold, *epnew; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct fs_func *fs_func = p_fs->fs_func; + + epold = get_entry_in_dir(sb, p_dir, oldentry, §or_old); + if (!epold) + return FFS_MEDIAERR; + + buf_lock(sb, sector_old); + + /* buf_lock() before call count_ext_entries() */ + num_old_entries = fs_func->count_ext_entries(sb, p_dir, oldentry, + epold); + if (num_old_entries < 0) { + buf_unlock(sb, sector_old); + return FFS_MEDIAERR; + } + num_old_entries++; + + ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, + &num_new_entries, &dos_name); + if (ret) { + buf_unlock(sb, sector_old); + return ret; + } + + if (num_old_entries < num_new_entries) { + newentry = find_empty_entry(inode, p_dir, num_new_entries); + if (newentry < 0) { + buf_unlock(sb, sector_old); + return FFS_FULL; + } + + epnew = get_entry_in_dir(sb, p_dir, newentry, §or_new); + if (!epnew) { + buf_unlock(sb, sector_old); + return FFS_MEDIAERR; + } + + memcpy((void *)epnew, (void *)epold, DENTRY_SIZE); + if (fs_func->get_entry_type(epnew) == TYPE_FILE) { + fs_func->set_entry_attr(epnew, + fs_func->get_entry_attr(epnew) | + ATTR_ARCHIVE); + fid->attr |= ATTR_ARCHIVE; + } + buf_modify(sb, sector_new); + buf_unlock(sb, sector_old); + + if (p_fs->vol_type == EXFAT) { + epold = get_entry_in_dir(sb, p_dir, oldentry + 1, + §or_old); + buf_lock(sb, sector_old); + epnew = get_entry_in_dir(sb, p_dir, newentry + 1, + §or_new); + + if (!epold || !epnew) { + buf_unlock(sb, sector_old); + return FFS_MEDIAERR; + } + + memcpy((void *)epnew, (void *)epold, DENTRY_SIZE); + buf_modify(sb, sector_new); + buf_unlock(sb, sector_old); + } + + ret = fs_func->init_ext_entry(sb, p_dir, newentry, + num_new_entries, p_uniname, + &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + fs_func->delete_dir_entry(sb, p_dir, oldentry, 0, + num_old_entries); + fid->entry = newentry; + } else { + if (fs_func->get_entry_type(epold) == TYPE_FILE) { + fs_func->set_entry_attr(epold, + fs_func->get_entry_attr(epold) | + ATTR_ARCHIVE); + fid->attr |= ATTR_ARCHIVE; + } + buf_modify(sb, sector_old); + buf_unlock(sb, sector_old); + + ret = fs_func->init_ext_entry(sb, p_dir, oldentry, + num_new_entries, p_uniname, + &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + fs_func->delete_dir_entry(sb, p_dir, oldentry, num_new_entries, + num_old_entries); + } + + return FFS_SUCCESS; +} + +s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry, + struct chain_t *p_newdir, struct uni_name_t *p_uniname, + struct file_id_t *fid) +{ + s32 ret, newentry, num_new_entries, num_old_entries; + sector_t sector_mov, sector_new; + struct chain_t clu; + struct dos_name_t dos_name; + struct dentry_t *epmov, *epnew; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct fs_func *fs_func = p_fs->fs_func; + + epmov = get_entry_in_dir(sb, p_olddir, oldentry, §or_mov); + if (!epmov) + return FFS_MEDIAERR; + + /* check if the source and target directory is the same */ + if (fs_func->get_entry_type(epmov) == TYPE_DIR && + fs_func->get_entry_clu0(epmov) == p_newdir->dir) + return FFS_INVALIDPATH; + + buf_lock(sb, sector_mov); + + /* buf_lock() before call count_ext_entries() */ + num_old_entries = fs_func->count_ext_entries(sb, p_olddir, oldentry, + epmov); + if (num_old_entries < 0) { + buf_unlock(sb, sector_mov); + return FFS_MEDIAERR; + } + num_old_entries++; + + ret = get_num_entries_and_dos_name(sb, p_newdir, p_uniname, + &num_new_entries, &dos_name); + if (ret) { + buf_unlock(sb, sector_mov); + return ret; + } + + newentry = find_empty_entry(inode, p_newdir, num_new_entries); + if (newentry < 0) { + buf_unlock(sb, sector_mov); + return FFS_FULL; + } + + epnew = get_entry_in_dir(sb, p_newdir, newentry, §or_new); + if (!epnew) { + buf_unlock(sb, sector_mov); + return FFS_MEDIAERR; + } + + memcpy((void *)epnew, (void *)epmov, DENTRY_SIZE); + if (fs_func->get_entry_type(epnew) == TYPE_FILE) { + fs_func->set_entry_attr(epnew, fs_func->get_entry_attr(epnew) | + ATTR_ARCHIVE); + fid->attr |= ATTR_ARCHIVE; + } + buf_modify(sb, sector_new); + buf_unlock(sb, sector_mov); + + if (p_fs->vol_type == EXFAT) { + epmov = get_entry_in_dir(sb, p_olddir, oldentry + 1, + §or_mov); + buf_lock(sb, sector_mov); + epnew = get_entry_in_dir(sb, p_newdir, newentry + 1, + §or_new); + if (!epmov || !epnew) { + buf_unlock(sb, sector_mov); + return FFS_MEDIAERR; + } + + memcpy((void *)epnew, (void *)epmov, DENTRY_SIZE); + buf_modify(sb, sector_new); + buf_unlock(sb, sector_mov); + } else if (fs_func->get_entry_type(epnew) == TYPE_DIR) { + /* change ".." pointer to new parent dir */ + clu.dir = fs_func->get_entry_clu0(epnew); + clu.flags = 0x01; + + epnew = get_entry_in_dir(sb, &clu, 1, §or_new); + if (!epnew) + return FFS_MEDIAERR; + + if (p_newdir->dir == p_fs->root_dir) + fs_func->set_entry_clu0(epnew, CLUSTER_32(0)); + else + fs_func->set_entry_clu0(epnew, p_newdir->dir); + buf_modify(sb, sector_new); + } + + ret = fs_func->init_ext_entry(sb, p_newdir, newentry, num_new_entries, + p_uniname, &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + fs_func->delete_dir_entry(sb, p_olddir, oldentry, 0, num_old_entries); + + fid->dir.dir = p_newdir->dir; + fid->dir.size = p_newdir->size; + fid->dir.flags = p_newdir->flags; + + fid->entry = newentry; + + return FFS_SUCCESS; +} + +/* + * Sector Read/Write Functions + */ + +int sector_read(struct super_block *sb, sector_t sec, struct buffer_head **bh, + bool read) +{ + s32 ret = FFS_MEDIAERR; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((sec >= (p_fs->PBR_sector + p_fs->num_sectors)) && + (p_fs->num_sectors > 0)) { + pr_err("[EXFAT] %s: out of range error! (sec = %llu)\n", + __func__, (unsigned long long)sec); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_read(sb, sec, bh, 1, read); + if (ret != FFS_SUCCESS) + p_fs->dev_ejected = 1; + } + + return ret; +} + +int sector_write(struct super_block *sb, sector_t sec, struct buffer_head *bh, + bool sync) +{ + s32 ret = FFS_MEDIAERR; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (sec >= (p_fs->PBR_sector + p_fs->num_sectors) && + (p_fs->num_sectors > 0)) { + pr_err("[EXFAT] %s: out of range error! (sec = %llu)\n", + __func__, (unsigned long long)sec); + fs_error(sb); + return ret; + } + + if (!bh) { + pr_err("[EXFAT] %s: bh is NULL!\n", __func__); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_write(sb, sec, bh, 1, sync); + if (ret != FFS_SUCCESS) + p_fs->dev_ejected = 1; + } + + return ret; +} + +int multi_sector_read(struct super_block *sb, sector_t sec, + struct buffer_head **bh, s32 num_secs, bool read) +{ + s32 ret = FFS_MEDIAERR; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (((sec + num_secs) > (p_fs->PBR_sector + p_fs->num_sectors)) && + (p_fs->num_sectors > 0)) { + pr_err("[EXFAT] %s: out of range error! (sec = %llu, num_secs = %d)\n", + __func__, (unsigned long long)sec, num_secs); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_read(sb, sec, bh, num_secs, read); + if (ret != FFS_SUCCESS) + p_fs->dev_ejected = 1; + } + + return ret; +} + +int multi_sector_write(struct super_block *sb, sector_t sec, + struct buffer_head *bh, s32 num_secs, bool sync) +{ + s32 ret = FFS_MEDIAERR; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((sec + num_secs) > (p_fs->PBR_sector + p_fs->num_sectors) && + (p_fs->num_sectors > 0)) { + pr_err("[EXFAT] %s: out of range error! (sec = %llu, num_secs = %d)\n", + __func__, (unsigned long long)sec, num_secs); + fs_error(sb); + return ret; + } + if (!bh) { + pr_err("[EXFAT] %s: bh is NULL!\n", __func__); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_write(sb, sec, bh, num_secs, sync); + if (ret != FFS_SUCCESS) + p_fs->dev_ejected = 1; + } + + return ret; +} diff --git a/drivers/staging/exfat/exfat_nls.c b/drivers/staging/exfat/exfat_nls.c new file mode 100644 index 000000000000..03cb8290b5d2 --- /dev/null +++ b/drivers/staging/exfat/exfat_nls.c @@ -0,0 +1,404 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include <linux/string.h> +#include <linux/nls.h> +#include "exfat.h" + +static u16 bad_dos_chars[] = { + /* + , ; = [ ] */ + 0x002B, 0x002C, 0x003B, 0x003D, 0x005B, 0x005D, + 0xFF0B, 0xFF0C, 0xFF1B, 0xFF1D, 0xFF3B, 0xFF3D, + 0 +}; + +static u16 bad_uni_chars[] = { + /* " * / : < > ? \ | */ + 0x0022, 0x002A, 0x002F, 0x003A, + 0x003C, 0x003E, 0x003F, 0x005C, 0x007C, + 0 +}; + +static int convert_ch_to_uni(struct nls_table *nls, u16 *uni, u8 *ch, + bool *lossy) +{ + int len; + + *uni = 0x0; + + if (ch[0] < 0x80) { + *uni = (u16)ch[0]; + return 1; + } + + len = nls->char2uni(ch, NLS_MAX_CHARSET_SIZE, uni); + if (len < 0) { + /* conversion failed */ + pr_info("%s: fail to use nls\n", __func__); + if (lossy) + *lossy = true; + *uni = (u16)'_'; + if (!strcmp(nls->charset, "utf8")) + return 1; + else + return 2; + } + + return len; +} + +static int convert_uni_to_ch(struct nls_table *nls, u8 *ch, u16 uni, + bool *lossy) +{ + int len; + + ch[0] = 0x0; + + if (uni < 0x0080) { + ch[0] = (u8)uni; + return 1; + } + + len = nls->uni2char(uni, ch, NLS_MAX_CHARSET_SIZE); + if (len < 0) { + /* conversion failed */ + pr_info("%s: fail to use nls\n", __func__); + if (lossy) + *lossy = true; + ch[0] = '_'; + return 1; + } + + return len; +} + +u16 nls_upper(struct super_block *sb, u16 a) +{ + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (EXFAT_SB(sb)->options.casesensitive) + return a; + if (p_fs->vol_utbl && p_fs->vol_utbl[get_col_index(a)]) + return p_fs->vol_utbl[get_col_index(a)][get_row_index(a)]; + else + return a; +} + +static u16 *nls_wstrchr(u16 *str, u16 wchar) +{ + while (*str) { + if (*(str++) == wchar) + return str; + } + + return NULL; +} + +int nls_dosname_cmp(struct super_block *sb, u8 *a, u8 *b) +{ + return strncmp(a, b, DOS_NAME_LENGTH); +} + +int nls_uniname_cmp(struct super_block *sb, u16 *a, u16 *b) +{ + int i; + + for (i = 0; i < MAX_NAME_LENGTH; i++, a++, b++) { + if (nls_upper(sb, *a) != nls_upper(sb, *b)) + return 1; + if (*a == 0x0) + return 0; + } + return 0; +} + +void nls_uniname_to_dosname(struct super_block *sb, + struct dos_name_t *p_dosname, + struct uni_name_t *p_uniname, bool *p_lossy) +{ + int i, j, len; + bool lossy = false; + u8 buf[MAX_CHARSET_SIZE]; + u8 lower = 0, upper = 0; + u8 *dosname = p_dosname->name; + u16 *uniname = p_uniname->name; + u16 *p, *last_period; + struct nls_table *nls = EXFAT_SB(sb)->nls_disk; + + for (i = 0; i < DOS_NAME_LENGTH; i++) + *(dosname + i) = ' '; + + if (!nls_uniname_cmp(sb, uniname, (u16 *)UNI_CUR_DIR_NAME)) { + *(dosname) = '.'; + p_dosname->name_case = 0x0; + if (p_lossy) + *p_lossy = false; + return; + } + + if (!nls_uniname_cmp(sb, uniname, (u16 *)UNI_PAR_DIR_NAME)) { + *(dosname) = '.'; + *(dosname + 1) = '.'; + p_dosname->name_case = 0x0; + if (p_lossy) + *p_lossy = false; + return; + } + + /* search for the last embedded period */ + last_period = NULL; + for (p = uniname; *p; p++) { + if (*p == (u16)'.') + last_period = p; + } + + i = 0; + while (i < DOS_NAME_LENGTH) { + if (i == 8) { + if (!last_period) + break; + + if (uniname <= last_period) { + if (uniname < last_period) + lossy = true; + uniname = last_period + 1; + } + } + + if (*uniname == (u16)'\0') { + break; + } else if (*uniname == (u16)' ') { + lossy = true; + } else if (*uniname == (u16)'.') { + if (uniname < last_period) + lossy = true; + else + i = 8; + } else if (nls_wstrchr(bad_dos_chars, *uniname)) { + lossy = true; + *(dosname + i) = '_'; + i++; + } else { + len = convert_uni_to_ch(nls, buf, *uniname, &lossy); + + if (len > 1) { + if ((i >= 8) && ((i + len) > DOS_NAME_LENGTH)) + break; + + if ((i < 8) && ((i + len) > 8)) { + i = 8; + continue; + } + + lower = 0xFF; + + for (j = 0; j < len; j++, i++) + *(dosname + i) = *(buf + j); + } else { /* len == 1 */ + if ((*buf >= 'a') && (*buf <= 'z')) { + *(dosname + i) = *buf - ('a' - 'A'); + + if (i < 8) + lower |= 0x08; + else + lower |= 0x10; + } else if ((*buf >= 'A') && (*buf <= 'Z')) { + *(dosname + i) = *buf; + + if (i < 8) + upper |= 0x08; + else + upper |= 0x10; + } else { + *(dosname + i) = *buf; + } + i++; + } + } + + uniname++; + } + + if (*dosname == 0xE5) + *dosname = 0x05; + + if (*uniname != 0x0) + lossy = true; + + if (upper & lower) + p_dosname->name_case = 0xFF; + else + p_dosname->name_case = lower; + + if (p_lossy) + *p_lossy = lossy; +} + +void nls_dosname_to_uniname(struct super_block *sb, + struct uni_name_t *p_uniname, + struct dos_name_t *p_dosname) +{ + int i = 0, j, n = 0; + u8 buf[DOS_NAME_LENGTH + 2]; + u8 *dosname = p_dosname->name; + u16 *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_disk; + + if (*dosname == 0x05) { + *buf = 0xE5; + i++; + n++; + } + + for (; i < 8; i++, n++) { + if (*(dosname + i) == ' ') + break; + + if ((*(dosname + i) >= 'A') && (*(dosname + i) <= 'Z') && + (p_dosname->name_case & 0x08)) + *(buf + n) = *(dosname + i) + ('a' - 'A'); + else + *(buf + n) = *(dosname + i); + } + if (*(dosname + 8) != ' ') { + *(buf + n) = '.'; + n++; + } + + for (i = 8; i < DOS_NAME_LENGTH; i++, n++) { + if (*(dosname + i) == ' ') + break; + + if ((*(dosname + i) >= 'A') && (*(dosname + i) <= 'Z') && + (p_dosname->name_case & 0x10)) + *(buf + n) = *(dosname + i) + ('a' - 'A'); + else + *(buf + n) = *(dosname + i); + } + *(buf + n) = '\0'; + + i = 0; + j = 0; + while (j < (MAX_NAME_LENGTH - 1)) { + if (*(buf + i) == '\0') + break; + + i += convert_ch_to_uni(nls, uniname, (buf + i), NULL); + + uniname++; + j++; + } + + *uniname = (u16)'\0'; +} + +void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring, + struct uni_name_t *p_uniname) +{ + int i, j, len; + u8 buf[MAX_CHARSET_SIZE]; + u16 *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_io; + + if (!nls) { + len = utf16s_to_utf8s(uniname, MAX_NAME_LENGTH, + UTF16_HOST_ENDIAN, p_cstring, + MAX_NAME_LENGTH); + p_cstring[len] = 0; + return; + } + + i = 0; + while (i < (MAX_NAME_LENGTH - 1)) { + if (*uniname == (u16)'\0') + break; + + len = convert_uni_to_ch(nls, buf, *uniname, NULL); + + if (len > 1) { + for (j = 0; j < len; j++) + *p_cstring++ = (char)*(buf + j); + } else { /* len == 1 */ + *p_cstring++ = (char)*buf; + } + + uniname++; + i++; + } + + *p_cstring = '\0'; +} + +void nls_cstring_to_uniname(struct super_block *sb, + struct uni_name_t *p_uniname, u8 *p_cstring, + bool *p_lossy) +{ + int i, j; + bool lossy = false; + u8 *end_of_name; + u8 upname[MAX_NAME_LENGTH * 2]; + u16 *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_io; + + /* strip all trailing spaces */ + end_of_name = p_cstring + strlen(p_cstring); + + while (*(--end_of_name) == ' ') { + if (end_of_name < p_cstring) + break; + } + *(++end_of_name) = '\0'; + + if (strcmp(p_cstring, ".") && strcmp(p_cstring, "..")) { + /* strip all trailing periods */ + while (*(--end_of_name) == '.') { + if (end_of_name < p_cstring) + break; + } + *(++end_of_name) = '\0'; + } + + if (*p_cstring == '\0') + lossy = true; + + if (!nls) { + i = utf8s_to_utf16s(p_cstring, MAX_NAME_LENGTH, + UTF16_HOST_ENDIAN, uniname, + MAX_NAME_LENGTH); + for (j = 0; j < i; j++) + SET16_A(upname + j * 2, nls_upper(sb, uniname[j])); + uniname[i] = '\0'; + } else { + i = 0; + j = 0; + while (j < (MAX_NAME_LENGTH - 1)) { + if (*(p_cstring + i) == '\0') + break; + + i += convert_ch_to_uni(nls, uniname, + (u8 *)(p_cstring + i), &lossy); + + if ((*uniname < 0x0020) || + nls_wstrchr(bad_uni_chars, *uniname)) + lossy = true; + + SET16_A(upname + j * 2, nls_upper(sb, *uniname)); + + uniname++; + j++; + } + + if (*(p_cstring + i) != '\0') + lossy = true; + *uniname = (u16)'\0'; + } + + p_uniname->name_len = j; + p_uniname->name_hash = calc_checksum_2byte(upname, j << 1, 0, + CS_DEFAULT); + + if (p_lossy) + *p_lossy = lossy; +} diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c new file mode 100644 index 000000000000..5f6caee819a6 --- /dev/null +++ b/drivers/staging/exfat/exfat_super.c @@ -0,0 +1,4049 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/time.h> +#include <linux/slab.h> +#include <linux/seq_file.h> +#include <linux/pagemap.h> +#include <linux/mpage.h> +#include <linux/buffer_head.h> +#include <linux/exportfs.h> +#include <linux/mount.h> +#include <linux/vfs.h> +#include <linux/aio.h> +#include <linux/iversion.h> +#include <linux/parser.h> +#include <linux/uio.h> +#include <linux/writeback.h> +#include <linux/log2.h> +#include <linux/hash.h> +#include <linux/backing-dev.h> +#include <linux/sched.h> +#include <linux/fs_struct.h> +#include <linux/namei.h> + +#include <linux/string.h> +#include <linux/nls.h> +#include <linux/mutex.h> +#include <linux/swap.h> + +#define EXFAT_VERSION "1.3.0" + +#include "exfat.h" + +static struct kmem_cache *exfat_inode_cachep; + +static int exfat_default_codepage = CONFIG_EXFAT_DEFAULT_CODEPAGE; +static char exfat_default_iocharset[] = CONFIG_EXFAT_DEFAULT_IOCHARSET; + +#define INC_IVERSION(x) (inode_inc_iversion(x)) +#define GET_IVERSION(x) (inode_peek_iversion_raw(x)) +#define SET_IVERSION(x, y) (inode_set_iversion(x, y)) + +static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos); +static int exfat_sync_inode(struct inode *inode); +static struct inode *exfat_build_inode(struct super_block *sb, + struct file_id_t *fid, loff_t i_pos); +static int exfat_write_inode(struct inode *inode, + struct writeback_control *wbc); +static void exfat_write_super(struct super_block *sb); + +#define UNIX_SECS_1980 315532800L +#define UNIX_SECS_2108 4354819200L + +/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */ +static void exfat_time_fat2unix(struct timespec64 *ts, struct date_time_t *tp) +{ + ts->tv_sec = mktime64(tp->Year + 1980, tp->Month + 1, tp->Day, + tp->Hour, tp->Minute, tp->Second); + + ts->tv_nsec = tp->MilliSecond * NSEC_PER_MSEC; +} + +/* Convert linear UNIX date to a FAT time/date pair. */ +static void exfat_time_unix2fat(struct timespec64 *ts, struct date_time_t *tp) +{ + time64_t second = ts->tv_sec; + struct tm tm; + + time64_to_tm(second, 0, &tm); + + if (second < UNIX_SECS_1980) { + tp->MilliSecond = 0; + tp->Second = 0; + tp->Minute = 0; + tp->Hour = 0; + tp->Day = 1; + tp->Month = 1; + tp->Year = 0; + return; + } + + if (second >= UNIX_SECS_2108) { + tp->MilliSecond = 999; + tp->Second = 59; + tp->Minute = 59; + tp->Hour = 23; + tp->Day = 31; + tp->Month = 12; + tp->Year = 127; + return; + } + + tp->MilliSecond = ts->tv_nsec / NSEC_PER_MSEC; + tp->Second = tm.tm_sec; + tp->Minute = tm.tm_min; + tp->Hour = tm.tm_hour; + tp->Day = tm.tm_mday; + tp->Month = tm.tm_mon + 1; + tp->Year = tm.tm_year + 1900 - 1980; +} + +struct timestamp_t *tm_current(struct timestamp_t *tp) +{ + time64_t second = ktime_get_real_seconds(); + struct tm tm; + + time64_to_tm(second, 0, &tm); + + if (second < UNIX_SECS_1980) { + tp->sec = 0; + tp->min = 0; + tp->hour = 0; + tp->day = 1; + tp->mon = 1; + tp->year = 0; + return tp; + } + + if (second >= UNIX_SECS_2108) { + tp->sec = 59; + tp->min = 59; + tp->hour = 23; + tp->day = 31; + tp->mon = 12; + tp->year = 127; + return tp; + } + + tp->sec = tm.tm_sec; + tp->min = tm.tm_min; + tp->hour = tm.tm_hour; + tp->day = tm.tm_mday; + tp->mon = tm.tm_mon + 1; + tp->year = tm.tm_year + 1900 - 1980; + + return tp; +} + +static void __lock_super(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + mutex_lock(&sbi->s_lock); +} + +static void __unlock_super(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + mutex_unlock(&sbi->s_lock); +} + +static int __is_sb_dirty(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + return sbi->s_dirt; +} + +static void __set_sb_clean(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + sbi->s_dirt = 0; +} + +static int __exfat_revalidate(struct dentry *dentry) +{ + return 0; +} + +static int exfat_revalidate(struct dentry *dentry, unsigned int flags) +{ + if (flags & LOOKUP_RCU) + return -ECHILD; + + if (dentry->d_inode) + return 1; + return __exfat_revalidate(dentry); +} + +static int exfat_revalidate_ci(struct dentry *dentry, unsigned int flags) +{ + if (flags & LOOKUP_RCU) + return -ECHILD; + + if (dentry->d_inode) + return 1; + + if (!flags) + return 0; + + if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) + return 0; + + return __exfat_revalidate(dentry); +} + +static unsigned int __exfat_striptail_len(unsigned int len, const char *name) +{ + while (len && name[len - 1] == '.') + len--; + return len; +} + +static unsigned int exfat_striptail_len(const struct qstr *qstr) +{ + return __exfat_striptail_len(qstr->len, qstr->name); +} + +static int exfat_d_hash(const struct dentry *dentry, struct qstr *qstr) +{ + qstr->hash = full_name_hash(dentry, qstr->name, + exfat_striptail_len(qstr)); + return 0; +} + +static int exfat_d_hashi(const struct dentry *dentry, struct qstr *qstr) +{ + struct super_block *sb = dentry->d_sb; + const unsigned char *name; + unsigned int len; + unsigned long hash; + + name = qstr->name; + len = exfat_striptail_len(qstr); + + hash = init_name_hash(dentry); + while (len--) + hash = partial_name_hash(nls_upper(sb, *name++), hash); + qstr->hash = end_name_hash(hash); + + return 0; +} + +static int exfat_cmpi(const struct dentry *dentry, unsigned int len, + const char *str, const struct qstr *name) +{ + struct nls_table *t = EXFAT_SB(dentry->d_sb)->nls_io; + unsigned int alen, blen; + + alen = exfat_striptail_len(name); + blen = __exfat_striptail_len(len, str); + if (alen == blen) { + if (!t) { + if (strncasecmp(name->name, str, alen) == 0) + return 0; + } else { + if (nls_strnicmp(t, name->name, str, alen) == 0) + return 0; + } + } + return 1; +} + +static int exfat_cmp(const struct dentry *dentry, unsigned int len, + const char *str, const struct qstr *name) +{ + unsigned int alen, blen; + + alen = exfat_striptail_len(name); + blen = __exfat_striptail_len(len, str); + if (alen == blen) { + if (strncmp(name->name, str, alen) == 0) + return 0; + } + return 1; +} + +static const struct dentry_operations exfat_ci_dentry_ops = { + .d_revalidate = exfat_revalidate_ci, + .d_hash = exfat_d_hashi, + .d_compare = exfat_cmpi, +}; + +static const struct dentry_operations exfat_dentry_ops = { + .d_revalidate = exfat_revalidate, + .d_hash = exfat_d_hash, + .d_compare = exfat_cmp, +}; + +static DEFINE_SEMAPHORE(z_sem); + +static inline void fs_sync(struct super_block *sb, bool do_sync) +{ + if (do_sync) + bdev_sync(sb); +} + +/* + * If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to + * save ATTR_RO instead of ->i_mode. + * + * If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only + * bit, it's just used as flag for app. + */ +static inline int exfat_mode_can_hold_ro(struct inode *inode) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + + if (S_ISDIR(inode->i_mode)) + return 0; + + if ((~sbi->options.fs_fmask) & 0222) + return 1; + return 0; +} + +/* Convert attribute bits and a mask to the UNIX mode. */ +static inline mode_t exfat_make_mode(struct exfat_sb_info *sbi, u32 attr, + mode_t mode) +{ + if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR)) + mode &= ~0222; + + if (attr & ATTR_SUBDIR) + return (mode & ~sbi->options.fs_dmask) | S_IFDIR; + else if (attr & ATTR_SYMLINK) + return (mode & ~sbi->options.fs_dmask) | S_IFLNK; + else + return (mode & ~sbi->options.fs_fmask) | S_IFREG; +} + +/* Return the FAT attribute byte for this inode */ +static inline u32 exfat_make_attr(struct inode *inode) +{ + if (exfat_mode_can_hold_ro(inode) && !(inode->i_mode & 0222)) + return (EXFAT_I(inode)->fid.attr) | ATTR_READONLY; + else + return EXFAT_I(inode)->fid.attr; +} + +static inline void exfat_save_attr(struct inode *inode, u32 attr) +{ + if (exfat_mode_can_hold_ro(inode)) + EXFAT_I(inode)->fid.attr = attr & ATTR_RWMASK; + else + EXFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY); +} + +static int ffsMountVol(struct super_block *sb) +{ + int i, ret; + struct pbr_sector_t *p_pbr; + struct buffer_head *tmp_bh = NULL; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + pr_info("[EXFAT] trying to mount...\n"); + + down(&z_sem); + + buf_init(sb); + + sema_init(&p_fs->v_sem, 1); + p_fs->dev_ejected = 0; + + /* open the block device */ + bdev_open(sb); + + if (p_bd->sector_size < sb->s_blocksize) { + ret = FFS_MEDIAERR; + goto out; + } + if (p_bd->sector_size > sb->s_blocksize) + sb_set_blocksize(sb, p_bd->sector_size); + + /* read Sector 0 */ + if (sector_read(sb, 0, &tmp_bh, 1) != FFS_SUCCESS) { + ret = FFS_MEDIAERR; + goto out; + } + + p_fs->PBR_sector = 0; + + p_pbr = (struct pbr_sector_t *)tmp_bh->b_data; + + /* check the validity of PBR */ + if (GET16_A(p_pbr->signature) != PBR_SIGNATURE) { + brelse(tmp_bh); + bdev_close(sb); + ret = FFS_FORMATERR; + goto out; + } + + /* fill fs_struct */ + for (i = 0; i < 53; i++) + if (p_pbr->bpb[i]) + break; + + if (i < 53) { +#ifdef CONFIG_EXFAT_DONT_MOUNT_VFAT + ret = -EINVAL; + printk(KERN_INFO "EXFAT: Attempted to mount VFAT filesystem\n"); + goto out; +#else + if (GET16(p_pbr->bpb + 11)) /* num_fat_sectors */ + ret = fat16_mount(sb, p_pbr); + else + ret = fat32_mount(sb, p_pbr); +#endif + } else { + ret = exfat_mount(sb, p_pbr); + } + + brelse(tmp_bh); + + if (ret) { + bdev_close(sb); + goto out; + } + + if (p_fs->vol_type == EXFAT) { + ret = load_alloc_bitmap(sb); + if (ret) { + bdev_close(sb); + goto out; + } + ret = load_upcase_table(sb); + if (ret) { + free_alloc_bitmap(sb); + bdev_close(sb); + goto out; + } + } + + if (p_fs->dev_ejected) { + if (p_fs->vol_type == EXFAT) { + free_upcase_table(sb); + free_alloc_bitmap(sb); + } + bdev_close(sb); + ret = FFS_MEDIAERR; + goto out; + } + + pr_info("[EXFAT] mounted successfully\n"); + +out: + up(&z_sem); + + return ret; +} + +static int ffsUmountVol(struct super_block *sb) +{ + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + int err = FFS_SUCCESS; + + pr_info("[EXFAT] trying to unmount...\n"); + + down(&z_sem); + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); + + if (p_fs->vol_type == EXFAT) { + free_upcase_table(sb); + free_alloc_bitmap(sb); + } + + FAT_release_all(sb); + buf_release_all(sb); + + /* close the block device */ + bdev_close(sb); + + if (p_fs->dev_ejected) { + pr_info("[EXFAT] unmounted with media errors. Device is already ejected.\n"); + err = FFS_MEDIAERR; + } + + buf_shutdown(sb); + + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + up(&z_sem); + + pr_info("[EXFAT] unmounted successfully\n"); + + return err; +} + +static int ffsGetVolInfo(struct super_block *sb, struct vol_info_t *info) +{ + int err = FFS_SUCCESS; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + /* check the validity of pointer parameters */ + if (!info) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + if (p_fs->used_clusters == UINT_MAX) + p_fs->used_clusters = p_fs->fs_func->count_used_clusters(sb); + + info->FatType = p_fs->vol_type; + info->ClusterSize = p_fs->cluster_size; + info->NumClusters = p_fs->num_clusters - 2; /* clu 0 & 1 */ + info->UsedClusters = p_fs->used_clusters; + info->FreeClusters = info->NumClusters - info->UsedClusters; + + if (p_fs->dev_ejected) + err = FFS_MEDIAERR; + + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return err; +} + +static int ffsSyncVol(struct super_block *sb, bool do_sync) +{ + int err = FFS_SUCCESS; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* synchronize the file system */ + fs_sync(sb, do_sync); + fs_set_vol_flags(sb, VOL_CLEAN); + + if (p_fs->dev_ejected) + err = FFS_MEDIAERR; + + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return err; +} + +/*----------------------------------------------------------------------*/ +/* File Operation Functions */ +/*----------------------------------------------------------------------*/ + +static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid) +{ + int ret, dentry, num_entries; + struct chain_t dir; + struct uni_name_t uni_name; + struct dos_name_t dos_name; + struct dentry_t *ep, *ep2; + struct entry_set_cache_t *es = NULL; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + pr_debug("%s entered\n", __func__); + + /* check the validity of pointer parameters */ + if (!fid || !path || (*path == '\0')) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* check the validity of directory name in the given pathname */ + ret = resolve_path(inode, path, &dir, &uni_name); + if (ret) + goto out; + + ret = get_num_entries_and_dos_name(sb, &dir, &uni_name, &num_entries, + &dos_name); + if (ret) + goto out; + + /* search the file name for directories */ + dentry = p_fs->fs_func->find_dir_entry(sb, &dir, &uni_name, num_entries, + &dos_name, TYPE_ALL); + if (dentry < -1) { + ret = FFS_NOTFOUND; + goto out; + } + + fid->dir.dir = dir.dir; + fid->dir.size = dir.size; + fid->dir.flags = dir.flags; + fid->entry = dentry; + + if (dentry == -1) { + fid->type = TYPE_DIR; + fid->rwoffset = 0; + fid->hint_last_off = -1; + + fid->attr = ATTR_SUBDIR; + fid->flags = 0x01; + fid->size = 0; + fid->start_clu = p_fs->root_dir; + } else { + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &dir, dentry, + ES_2_ENTRIES, &ep); + if (!es) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep + 1; + } else { + ep = get_entry_in_dir(sb, &dir, dentry, NULL); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep; + } + + fid->type = p_fs->fs_func->get_entry_type(ep); + fid->rwoffset = 0; + fid->hint_last_off = -1; + fid->attr = p_fs->fs_func->get_entry_attr(ep); + + fid->size = p_fs->fs_func->get_entry_size(ep2); + if ((fid->type == TYPE_FILE) && (fid->size == 0)) { + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->start_clu = CLUSTER_32(~0); + } else { + fid->flags = p_fs->fs_func->get_entry_flag(ep2); + fid->start_clu = p_fs->fs_func->get_entry_clu0(ep2); + } + + if (p_fs->vol_type == EXFAT) + release_entry_set(es); + } + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static int ffsCreateFile(struct inode *inode, char *path, u8 mode, + struct file_id_t *fid) +{ + struct chain_t dir; + struct uni_name_t uni_name; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + int ret; + + /* check the validity of pointer parameters */ + if (!fid || !path || (*path == '\0')) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* check the validity of directory name in the given pathname */ + ret = resolve_path(inode, path, &dir, &uni_name); + if (ret) + goto out; + + fs_set_vol_flags(sb, VOL_DIRTY); + + /* create a new file */ + ret = create_file(inode, &dir, &uni_name, mode, fid); + +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static int ffsReadFile(struct inode *inode, struct file_id_t *fid, void *buffer, + u64 count, u64 *rcount) +{ + s32 offset, sec_offset, clu_offset; + u32 clu; + int ret = 0; + sector_t LogSector; + u64 oneblkread, read_bytes; + struct buffer_head *tmp_bh = NULL; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + /* check the validity of the given file id */ + if (!fid) + return FFS_INVALIDFID; + + /* check the validity of pointer parameters */ + if (!buffer) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* check if the given file ID is opened */ + if (fid->type != TYPE_FILE) { + ret = FFS_PERMISSIONERR; + goto out; + } + + if (fid->rwoffset > fid->size) + fid->rwoffset = fid->size; + + if (count > (fid->size - fid->rwoffset)) + count = fid->size - fid->rwoffset; + + if (count == 0) { + if (rcount) + *rcount = 0; + ret = FFS_EOF; + goto out; + } + + read_bytes = 0; + + while (count > 0) { + clu_offset = (s32)(fid->rwoffset >> p_fs->cluster_size_bits); + clu = fid->start_clu; + + if (fid->flags == 0x03) { + clu += clu_offset; + } else { + /* hint information */ + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + clu = fid->hint_last_clu; + } + + while (clu_offset > 0) { + /* clu = FAT_read(sb, clu); */ + if (FAT_read(sb, clu, &clu) == -1) + return FFS_MEDIAERR; + + clu_offset--; + } + } + + /* hint information */ + fid->hint_last_off = (s32)(fid->rwoffset >> + p_fs->cluster_size_bits); + fid->hint_last_clu = clu; + + /* byte offset in cluster */ + offset = (s32)(fid->rwoffset & (p_fs->cluster_size - 1)); + + /* sector offset in cluster */ + sec_offset = offset >> p_bd->sector_size_bits; + + /* byte offset in sector */ + offset &= p_bd->sector_size_mask; + + LogSector = START_SECTOR(clu) + sec_offset; + + oneblkread = (u64)(p_bd->sector_size - offset); + if (oneblkread > count) + oneblkread = count; + + if ((offset == 0) && (oneblkread == p_bd->sector_size)) { + if (sector_read(sb, LogSector, &tmp_bh, 1) != + FFS_SUCCESS) + goto err_out; + memcpy((char *)buffer + read_bytes, + (char *)tmp_bh->b_data, (s32)oneblkread); + } else { + if (sector_read(sb, LogSector, &tmp_bh, 1) != + FFS_SUCCESS) + goto err_out; + memcpy((char *)buffer + read_bytes, + (char *)tmp_bh->b_data + offset, + (s32)oneblkread); + } + count -= oneblkread; + read_bytes += oneblkread; + fid->rwoffset += oneblkread; + } + brelse(tmp_bh); + +/* How did this ever work and not leak a brlse()?? */ +err_out: + /* set the size of read bytes */ + if (rcount) + *rcount = read_bytes; + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static int ffsWriteFile(struct inode *inode, struct file_id_t *fid, + void *buffer, u64 count, u64 *wcount) +{ + bool modified = false; + s32 offset, sec_offset, clu_offset; + s32 num_clusters, num_alloc, num_alloced = (s32)~0; + int ret = 0; + u32 clu, last_clu; + sector_t LogSector, sector = 0; + u64 oneblkwrite, write_bytes; + struct chain_t new_clu; + struct timestamp_t tm; + struct dentry_t *ep, *ep2; + struct entry_set_cache_t *es = NULL; + struct buffer_head *tmp_bh = NULL; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + + /* check the validity of the given file id */ + if (!fid) + return FFS_INVALIDFID; + + /* check the validity of pointer parameters */ + if (!buffer) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* check if the given file ID is opened */ + if (fid->type != TYPE_FILE) { + ret = FFS_PERMISSIONERR; + goto out; + } + + if (fid->rwoffset > fid->size) + fid->rwoffset = fid->size; + + if (count == 0) { + if (wcount) + *wcount = 0; + ret = FFS_SUCCESS; + goto out; + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + if (fid->size == 0) + num_clusters = 0; + else + num_clusters = (s32)((fid->size - 1) >> + p_fs->cluster_size_bits) + 1; + + write_bytes = 0; + + while (count > 0) { + clu_offset = (s32)(fid->rwoffset >> p_fs->cluster_size_bits); + clu = last_clu = fid->start_clu; + + if (fid->flags == 0x03) { + if ((clu_offset > 0) && (clu != CLUSTER_32(~0))) { + last_clu += clu_offset - 1; + + if (clu_offset == num_clusters) + clu = CLUSTER_32(~0); + else + clu += clu_offset; + } + } else { + /* hint information */ + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + clu = fid->hint_last_clu; + } + + while ((clu_offset > 0) && (clu != CLUSTER_32(~0))) { + last_clu = clu; + /* clu = FAT_read(sb, clu); */ + if (FAT_read(sb, clu, &clu) == -1) { + ret = FFS_MEDIAERR; + goto out; + } + clu_offset--; + } + } + + if (clu == CLUSTER_32(~0)) { + num_alloc = (s32)((count - 1) >> + p_fs->cluster_size_bits) + 1; + new_clu.dir = (last_clu == CLUSTER_32(~0)) ? + CLUSTER_32(~0) : last_clu + 1; + new_clu.size = 0; + new_clu.flags = fid->flags; + + /* (1) allocate a chain of clusters */ + num_alloced = p_fs->fs_func->alloc_cluster(sb, + num_alloc, + &new_clu); + if (num_alloced == 0) + break; + if (num_alloced < 0) { + ret = FFS_MEDIAERR; + goto out; + } + + /* (2) append to the FAT chain */ + if (last_clu == CLUSTER_32(~0)) { + if (new_clu.flags == 0x01) + fid->flags = 0x01; + fid->start_clu = new_clu.dir; + modified = true; + } else { + if (new_clu.flags != fid->flags) { + exfat_chain_cont_cluster(sb, + fid->start_clu, + num_clusters); + fid->flags = 0x01; + modified = true; + } + if (new_clu.flags == 0x01) + FAT_write(sb, last_clu, new_clu.dir); + } + + num_clusters += num_alloced; + clu = new_clu.dir; + } + + /* hint information */ + fid->hint_last_off = (s32)(fid->rwoffset >> + p_fs->cluster_size_bits); + fid->hint_last_clu = clu; + + /* byte offset in cluster */ + offset = (s32)(fid->rwoffset & (p_fs->cluster_size - 1)); + + /* sector offset in cluster */ + sec_offset = offset >> p_bd->sector_size_bits; + + /* byte offset in sector */ + offset &= p_bd->sector_size_mask; + + LogSector = START_SECTOR(clu) + sec_offset; + + oneblkwrite = (u64)(p_bd->sector_size - offset); + if (oneblkwrite > count) + oneblkwrite = count; + + if ((offset == 0) && (oneblkwrite == p_bd->sector_size)) { + if (sector_read(sb, LogSector, &tmp_bh, 0) != + FFS_SUCCESS) + goto err_out; + memcpy((char *)tmp_bh->b_data, + (char *)buffer + write_bytes, (s32)oneblkwrite); + if (sector_write(sb, LogSector, tmp_bh, 0) != + FFS_SUCCESS) { + brelse(tmp_bh); + goto err_out; + } + } else { + if ((offset > 0) || + ((fid->rwoffset + oneblkwrite) < fid->size)) { + if (sector_read(sb, LogSector, &tmp_bh, 1) != + FFS_SUCCESS) + goto err_out; + } else { + if (sector_read(sb, LogSector, &tmp_bh, 0) != + FFS_SUCCESS) + goto err_out; + } + + memcpy((char *)tmp_bh->b_data + offset, + (char *)buffer + write_bytes, (s32)oneblkwrite); + if (sector_write(sb, LogSector, tmp_bh, 0) != + FFS_SUCCESS) { + brelse(tmp_bh); + goto err_out; + } + } + + count -= oneblkwrite; + write_bytes += oneblkwrite; + fid->rwoffset += oneblkwrite; + + fid->attr |= ATTR_ARCHIVE; + + if (fid->size < fid->rwoffset) { + fid->size = fid->rwoffset; + modified = true; + } + } + + brelse(tmp_bh); + + /* (3) update the direcoty entry */ + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, + ES_ALL_ENTRIES, &ep); + if (!es) + goto err_out; + ep2 = ep + 1; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) + goto err_out; + ep2 = ep; + } + + p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY); + p_fs->fs_func->set_entry_attr(ep, fid->attr); + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + + if (modified) { + if (p_fs->fs_func->get_entry_flag(ep2) != fid->flags) + p_fs->fs_func->set_entry_flag(ep2, fid->flags); + + if (p_fs->fs_func->get_entry_size(ep2) != fid->size) + p_fs->fs_func->set_entry_size(ep2, fid->size); + + if (p_fs->fs_func->get_entry_clu0(ep2) != fid->start_clu) + p_fs->fs_func->set_entry_clu0(ep2, fid->start_clu); + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + } + + if (p_fs->vol_type == EXFAT) { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + +err_out: + /* set the size of written bytes */ + if (wcount) + *wcount = write_bytes; + + if (num_alloced == 0) + ret = FFS_FULL; + + else if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size) +{ + s32 num_clusters; + u32 last_clu = CLUSTER_32(0); + int ret = 0; + sector_t sector = 0; + struct chain_t clu; + struct timestamp_t tm; + struct dentry_t *ep, *ep2; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + struct entry_set_cache_t *es = NULL; + + pr_debug("%s entered (inode %p size %llu)\n", __func__, inode, + new_size); + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* check if the given file ID is opened */ + if (fid->type != TYPE_FILE) { + ret = FFS_PERMISSIONERR; + goto out; + } + + if (fid->size != old_size) { + pr_err("[EXFAT] truncate : can't skip it because of size-mismatch(old:%lld->fid:%lld).\n", + old_size, fid->size); + } + + if (old_size <= new_size) { + ret = FFS_SUCCESS; + goto out; + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + clu.dir = fid->start_clu; + clu.size = (s32)((old_size - 1) >> p_fs->cluster_size_bits) + 1; + clu.flags = fid->flags; + + if (new_size > 0) { + num_clusters = (s32)((new_size - 1) >> + p_fs->cluster_size_bits) + 1; + + if (clu.flags == 0x03) { + clu.dir += num_clusters; + } else { + while (num_clusters > 0) { + last_clu = clu.dir; + if (FAT_read(sb, clu.dir, &clu.dir) == -1) { + ret = FFS_MEDIAERR; + goto out; + } + num_clusters--; + } + } + + clu.size -= num_clusters; + } + + fid->size = new_size; + fid->attr |= ATTR_ARCHIVE; + if (new_size == 0) { + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->start_clu = CLUSTER_32(~0); + } + + /* (1) update the directory entry */ + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &fid->dir, fid->entry, + ES_ALL_ENTRIES, &ep); + if (!es) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep + 1; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep; + } + + p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY); + p_fs->fs_func->set_entry_attr(ep, fid->attr); + + p_fs->fs_func->set_entry_size(ep2, new_size); + if (new_size == 0) { + p_fs->fs_func->set_entry_flag(ep2, 0x01); + p_fs->fs_func->set_entry_clu0(ep2, CLUSTER_32(0)); + } + + if (p_fs->vol_type != EXFAT) { + buf_modify(sb, sector); + } else { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + + /* (2) cut off from the FAT chain */ + if (last_clu != CLUSTER_32(0)) { + if (fid->flags == 0x01) + FAT_write(sb, last_clu, CLUSTER_32(~0)); + } + + /* (3) free the clusters */ + p_fs->fs_func->free_cluster(sb, &clu, 0); + + /* hint information */ + fid->hint_last_off = -1; + if (fid->rwoffset > fid->size) + fid->rwoffset = fid->size; + +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + pr_debug("%s exited (%d)\n", __func__, ret); + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static void update_parent_info(struct file_id_t *fid, + struct inode *parent_inode) +{ + struct fs_info_t *p_fs = &(EXFAT_SB(parent_inode->i_sb)->fs_info); + struct file_id_t *parent_fid = &(EXFAT_I(parent_inode)->fid); + + if (unlikely((parent_fid->flags != fid->dir.flags) || + (parent_fid->size != + (fid->dir.size << p_fs->cluster_size_bits)) || + (parent_fid->start_clu != fid->dir.dir))) { + fid->dir.dir = parent_fid->start_clu; + fid->dir.flags = parent_fid->flags; + fid->dir.size = ((parent_fid->size + (p_fs->cluster_size - 1)) + >> p_fs->cluster_size_bits); + } +} + +static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid, + struct inode *new_parent_inode, struct dentry *new_dentry) +{ + s32 ret; + s32 dentry; + struct chain_t olddir, newdir; + struct chain_t *p_dir = NULL; + struct uni_name_t uni_name; + struct dentry_t *ep; + struct super_block *sb = old_parent_inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + u8 *new_path = (u8 *)new_dentry->d_name.name; + struct inode *new_inode = new_dentry->d_inode; + int num_entries; + struct file_id_t *new_fid = NULL; + s32 new_entry = 0; + + /* check the validity of the given file id */ + if (!fid) + return FFS_INVALIDFID; + + /* check the validity of pointer parameters */ + if (!new_path || (*new_path == '\0')) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + update_parent_info(fid, old_parent_inode); + + olddir.dir = fid->dir.dir; + olddir.size = fid->dir.size; + olddir.flags = fid->dir.flags; + + dentry = fid->entry; + + /* check if the old file is "." or ".." */ + if (p_fs->vol_type != EXFAT) { + if ((olddir.dir != p_fs->root_dir) && (dentry < 2)) { + ret = FFS_PERMISSIONERR; + goto out2; + } + } + + ep = get_entry_in_dir(sb, &olddir, dentry, NULL); + if (!ep) { + ret = FFS_MEDIAERR; + goto out2; + } + + if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) { + ret = FFS_PERMISSIONERR; + goto out2; + } + + /* check whether new dir is existing directory and empty */ + if (new_inode) { + u32 entry_type; + + ret = FFS_MEDIAERR; + new_fid = &EXFAT_I(new_inode)->fid; + + update_parent_info(new_fid, new_parent_inode); + + p_dir = &(new_fid->dir); + new_entry = new_fid->entry; + ep = get_entry_in_dir(sb, p_dir, new_entry, NULL); + if (!ep) + goto out; + + entry_type = p_fs->fs_func->get_entry_type(ep); + + if (entry_type == TYPE_DIR) { + struct chain_t new_clu; + + new_clu.dir = new_fid->start_clu; + new_clu.size = (s32)((new_fid->size - 1) >> + p_fs->cluster_size_bits) + 1; + new_clu.flags = new_fid->flags; + + if (!is_dir_empty(sb, &new_clu)) { + ret = FFS_FILEEXIST; + goto out; + } + } + } + + /* check the validity of directory name in the given new pathname */ + ret = resolve_path(new_parent_inode, new_path, &newdir, &uni_name); + if (ret) + goto out2; + + fs_set_vol_flags(sb, VOL_DIRTY); + + if (olddir.dir == newdir.dir) + ret = rename_file(new_parent_inode, &olddir, dentry, &uni_name, + fid); + else + ret = move_file(new_parent_inode, &olddir, dentry, &newdir, + &uni_name, fid); + + if ((ret == FFS_SUCCESS) && new_inode) { + /* delete entries of new_dir */ + ep = get_entry_in_dir(sb, p_dir, new_entry, NULL); + if (!ep) + goto out; + + num_entries = p_fs->fs_func->count_ext_entries(sb, p_dir, + new_entry, ep); + if (num_entries < 0) + goto out; + p_fs->fs_func->delete_dir_entry(sb, p_dir, new_entry, 0, + num_entries + 1); + } +out: +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; +out2: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid) +{ + s32 dentry; + int ret = FFS_SUCCESS; + struct chain_t dir, clu_to_free; + struct dentry_t *ep; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + /* check the validity of the given file id */ + if (!fid) + return FFS_INVALIDFID; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + dir.dir = fid->dir.dir; + dir.size = fid->dir.size; + dir.flags = fid->dir.flags; + + dentry = fid->entry; + + ep = get_entry_in_dir(sb, &dir, dentry, NULL); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + + if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) { + ret = FFS_PERMISSIONERR; + goto out; + } + fs_set_vol_flags(sb, VOL_DIRTY); + + /* (1) update the directory entry */ + remove_file(inode, &dir, dentry); + + clu_to_free.dir = fid->start_clu; + clu_to_free.size = (s32)((fid->size - 1) >> p_fs->cluster_size_bits) + 1; + clu_to_free.flags = fid->flags; + + /* (2) free the clusters */ + p_fs->fs_func->free_cluster(sb, &clu_to_free, 0); + + fid->size = 0; + fid->start_clu = CLUSTER_32(~0); + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +#if 0 +/* Not currently wired up */ +static int ffsSetAttr(struct inode *inode, u32 attr) +{ + u32 type; + int ret = FFS_SUCCESS; + sector_t sector = 0; + struct dentry_t *ep; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; + struct entry_set_cache_t *es = NULL; + + if (fid->attr == attr) { + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + return FFS_SUCCESS; + } + + if (is_dir) { + if ((fid->dir.dir == p_fs->root_dir) && + (fid->entry == -1)) { + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + return FFS_SUCCESS; + } + } + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* get the directory entry of given file */ + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, + ES_ALL_ENTRIES, &ep); + if (!es) { + ret = FFS_MEDIAERR; + goto out; + } + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + } + + type = p_fs->fs_func->get_entry_type(ep); + + if (((type == TYPE_FILE) && (attr & ATTR_SUBDIR)) || + ((type == TYPE_DIR) && (!(attr & ATTR_SUBDIR)))) { + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + else + ret = FFS_ERROR; + + if (p_fs->vol_type == EXFAT) + release_entry_set(es); + goto out; + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + /* set the file attribute */ + fid->attr = attr; + p_fs->fs_func->set_entry_attr(ep, attr); + + if (p_fs->vol_type != EXFAT) { + buf_modify(sb, sector); + } else { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} +#endif + +static int ffsReadStat(struct inode *inode, struct dir_entry_t *info) +{ + sector_t sector = 0; + s32 count; + int ret = FFS_SUCCESS; + struct chain_t dir; + struct uni_name_t uni_name; + struct timestamp_t tm; + struct dentry_t *ep, *ep2; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + struct entry_set_cache_t *es = NULL; + u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; + + pr_debug("%s entered\n", __func__); + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + if (is_dir) { + if ((fid->dir.dir == p_fs->root_dir) && + (fid->entry == -1)) { + info->Attr = ATTR_SUBDIR; + memset((char *)&info->CreateTimestamp, 0, + sizeof(struct date_time_t)); + memset((char *)&info->ModifyTimestamp, 0, + sizeof(struct date_time_t)); + memset((char *)&info->AccessTimestamp, 0, + sizeof(struct date_time_t)); + strcpy(info->ShortName, "."); + strcpy(info->Name, "."); + + dir.dir = p_fs->root_dir; + dir.flags = 0x01; + + if (p_fs->root_dir == CLUSTER_32(0)) { + /* FAT16 root_dir */ + info->Size = p_fs->dentries_in_root << + DENTRY_SIZE_BITS; + } else { + info->Size = count_num_clusters(sb, &dir) << + p_fs->cluster_size_bits; + } + + count = count_dos_name_entries(sb, &dir, TYPE_DIR); + if (count < 0) { + ret = FFS_MEDIAERR; + goto out; + } + info->NumSubdirs = count; + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + goto out; + } + } + + /* get the directory entry of given file or directory */ + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, + ES_2_ENTRIES, &ep); + if (!es) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep + 1; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep; + buf_lock(sb, sector); + } + + /* set FILE_INFO structure using the acquired struct dentry_t */ + info->Attr = p_fs->fs_func->get_entry_attr(ep); + + p_fs->fs_func->get_entry_time(ep, &tm, TM_CREATE); + info->CreateTimestamp.Year = tm.year; + info->CreateTimestamp.Month = tm.mon; + info->CreateTimestamp.Day = tm.day; + info->CreateTimestamp.Hour = tm.hour; + info->CreateTimestamp.Minute = tm.min; + info->CreateTimestamp.Second = tm.sec; + info->CreateTimestamp.MilliSecond = 0; + + p_fs->fs_func->get_entry_time(ep, &tm, TM_MODIFY); + info->ModifyTimestamp.Year = tm.year; + info->ModifyTimestamp.Month = tm.mon; + info->ModifyTimestamp.Day = tm.day; + info->ModifyTimestamp.Hour = tm.hour; + info->ModifyTimestamp.Minute = tm.min; + info->ModifyTimestamp.Second = tm.sec; + info->ModifyTimestamp.MilliSecond = 0; + + memset((char *)&info->AccessTimestamp, 0, sizeof(struct date_time_t)); + + *(uni_name.name) = 0x0; + /* XXX this is very bad for exfat cuz name is already included in es. + * API should be revised + */ + p_fs->fs_func->get_uni_name_from_ext_entry(sb, &(fid->dir), fid->entry, + uni_name.name); + if (*uni_name.name == 0x0 && p_fs->vol_type != EXFAT) + get_uni_name_from_dos_entry(sb, (struct dos_dentry_t *)ep, + &uni_name, 0x1); + nls_uniname_to_cstring(sb, info->Name, &uni_name); + + if (p_fs->vol_type == EXFAT) { + info->NumSubdirs = 2; + } else { + buf_unlock(sb, sector); + get_uni_name_from_dos_entry(sb, (struct dos_dentry_t *)ep, + &uni_name, 0x0); + nls_uniname_to_cstring(sb, info->ShortName, &uni_name); + info->NumSubdirs = 0; + } + + info->Size = p_fs->fs_func->get_entry_size(ep2); + + if (p_fs->vol_type == EXFAT) + release_entry_set(es); + + if (is_dir) { + dir.dir = fid->start_clu; + dir.flags = 0x01; + + if (info->Size == 0) + info->Size = (u64)count_num_clusters(sb, &dir) << + p_fs->cluster_size_bits; + + count = count_dos_name_entries(sb, &dir, TYPE_DIR); + if (count < 0) { + ret = FFS_MEDIAERR; + goto out; + } + info->NumSubdirs += count; + } + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + pr_debug("%s exited successfully\n", __func__); + return ret; +} + +static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info) +{ + sector_t sector = 0; + int ret = FFS_SUCCESS; + struct timestamp_t tm; + struct dentry_t *ep, *ep2; + struct entry_set_cache_t *es = NULL; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; + + pr_debug("%s entered (inode %p info %p\n", __func__, inode, info); + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + if (is_dir) { + if ((fid->dir.dir == p_fs->root_dir) && + (fid->entry == -1)) { + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + ret = FFS_SUCCESS; + goto out; + } + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + /* get the directory entry of given file or directory */ + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, + ES_ALL_ENTRIES, &ep); + if (!es) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep + 1; + } else { + /* for other than exfat */ + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + ep2 = ep; + } + + p_fs->fs_func->set_entry_attr(ep, info->Attr); + + /* set FILE_INFO structure using the acquired struct dentry_t */ + tm.sec = info->CreateTimestamp.Second; + tm.min = info->CreateTimestamp.Minute; + tm.hour = info->CreateTimestamp.Hour; + tm.day = info->CreateTimestamp.Day; + tm.mon = info->CreateTimestamp.Month; + tm.year = info->CreateTimestamp.Year; + p_fs->fs_func->set_entry_time(ep, &tm, TM_CREATE); + + tm.sec = info->ModifyTimestamp.Second; + tm.min = info->ModifyTimestamp.Minute; + tm.hour = info->ModifyTimestamp.Hour; + tm.day = info->ModifyTimestamp.Day; + tm.mon = info->ModifyTimestamp.Month; + tm.year = info->ModifyTimestamp.Year; + p_fs->fs_func->set_entry_time(ep, &tm, TM_MODIFY); + + p_fs->fs_func->set_entry_size(ep2, info->Size); + + if (p_fs->vol_type != EXFAT) { + buf_modify(sb, sector); + } else { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + pr_debug("%s exited (%d)\n", __func__, ret); + + return ret; +} + +static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu) +{ + s32 num_clusters, num_alloced; + bool modified = false; + u32 last_clu; + int ret = FFS_SUCCESS; + sector_t sector = 0; + struct chain_t new_clu; + struct dentry_t *ep; + struct entry_set_cache_t *es = NULL; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + + /* check the validity of pointer parameters */ + if (!clu) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + fid->rwoffset = (s64)(clu_offset) << p_fs->cluster_size_bits; + + if (EXFAT_I(inode)->mmu_private == 0) + num_clusters = 0; + else + num_clusters = (s32)((EXFAT_I(inode)->mmu_private - 1) >> + p_fs->cluster_size_bits) + 1; + + *clu = last_clu = fid->start_clu; + + if (fid->flags == 0x03) { + if ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) { + last_clu += clu_offset - 1; + + if (clu_offset == num_clusters) + *clu = CLUSTER_32(~0); + else + *clu += clu_offset; + } + } else { + /* hint information */ + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + *clu = fid->hint_last_clu; + } + + while ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) { + last_clu = *clu; + if (FAT_read(sb, *clu, clu) == -1) { + ret = FFS_MEDIAERR; + goto out; + } + clu_offset--; + } + } + + if (*clu == CLUSTER_32(~0)) { + fs_set_vol_flags(sb, VOL_DIRTY); + + new_clu.dir = (last_clu == CLUSTER_32(~0)) ? CLUSTER_32(~0) : + last_clu + 1; + new_clu.size = 0; + new_clu.flags = fid->flags; + + /* (1) allocate a cluster */ + num_alloced = p_fs->fs_func->alloc_cluster(sb, 1, &new_clu); + if (num_alloced < 0) { + ret = FFS_MEDIAERR; + goto out; + } else if (num_alloced == 0) { + ret = FFS_FULL; + goto out; + } + + /* (2) append to the FAT chain */ + if (last_clu == CLUSTER_32(~0)) { + if (new_clu.flags == 0x01) + fid->flags = 0x01; + fid->start_clu = new_clu.dir; + modified = true; + } else { + if (new_clu.flags != fid->flags) { + exfat_chain_cont_cluster(sb, fid->start_clu, + num_clusters); + fid->flags = 0x01; + modified = true; + } + if (new_clu.flags == 0x01) + FAT_write(sb, last_clu, new_clu.dir); + } + + num_clusters += num_alloced; + *clu = new_clu.dir; + + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &fid->dir, fid->entry, + ES_ALL_ENTRIES, &ep); + if (!es) { + ret = FFS_MEDIAERR; + goto out; + } + /* get stream entry */ + ep++; + } + + /* (3) update directory entry */ + if (modified) { + if (p_fs->vol_type != EXFAT) { + ep = get_entry_in_dir(sb, &(fid->dir), + fid->entry, §or); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + } + + if (p_fs->fs_func->get_entry_flag(ep) != fid->flags) + p_fs->fs_func->set_entry_flag(ep, fid->flags); + + if (p_fs->fs_func->get_entry_clu0(ep) != fid->start_clu) + p_fs->fs_func->set_entry_clu0(ep, + fid->start_clu); + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + } + + if (p_fs->vol_type == EXFAT) { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + + /* add number of new blocks to inode */ + inode->i_blocks += num_alloced << (p_fs->cluster_size_bits - 9); + } + + /* hint information */ + fid->hint_last_off = (s32)(fid->rwoffset >> p_fs->cluster_size_bits); + fid->hint_last_clu = *clu; + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +/*----------------------------------------------------------------------*/ +/* Directory Operation Functions */ +/*----------------------------------------------------------------------*/ + +static int ffsCreateDir(struct inode *inode, char *path, struct file_id_t *fid) +{ + int ret = FFS_SUCCESS; + struct chain_t dir; + struct uni_name_t uni_name; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + pr_debug("%s entered\n", __func__); + + /* check the validity of pointer parameters */ + if (!fid || !path || (*path == '\0')) + return FFS_ERROR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + /* check the validity of directory name in the given old pathname */ + ret = resolve_path(inode, path, &dir, &uni_name); + if (ret) + goto out; + + fs_set_vol_flags(sb, VOL_DIRTY); + + ret = create_dir(inode, &dir, &uni_name, fid); + +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry) +{ + int i, dentry, clu_offset; + int ret = FFS_SUCCESS; + s32 dentries_per_clu, dentries_per_clu_bits = 0; + u32 type; + sector_t sector; + struct chain_t dir, clu; + struct uni_name_t uni_name; + struct timestamp_t tm; + struct dentry_t *ep; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct fs_func *fs_func = p_fs->fs_func; + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + + /* check the validity of pointer parameters */ + if (!dir_entry) + return FFS_ERROR; + + /* check if the given file ID is opened */ + if (fid->type != TYPE_DIR) + return FFS_PERMISSIONERR; + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + if (fid->entry == -1) { + dir.dir = p_fs->root_dir; + dir.flags = 0x01; + } else { + dir.dir = fid->start_clu; + dir.size = (s32)(fid->size >> p_fs->cluster_size_bits); + dir.flags = fid->flags; + } + + dentry = (s32)fid->rwoffset; + + if (dir.dir == CLUSTER_32(0)) { + /* FAT16 root_dir */ + dentries_per_clu = p_fs->dentries_in_root; + + if (dentry == dentries_per_clu) { + clu.dir = CLUSTER_32(~0); + } else { + clu.dir = dir.dir; + clu.size = dir.size; + clu.flags = dir.flags; + } + } else { + dentries_per_clu = p_fs->dentries_per_clu; + dentries_per_clu_bits = ilog2(dentries_per_clu); + + clu_offset = dentry >> dentries_per_clu_bits; + clu.dir = dir.dir; + clu.size = dir.size; + clu.flags = dir.flags; + + if (clu.flags == 0x03) { + clu.dir += clu_offset; + clu.size -= clu_offset; + } else { + /* hint_information */ + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + clu.dir = fid->hint_last_clu; + } + + while (clu_offset > 0) { + /* clu.dir = FAT_read(sb, clu.dir); */ + if (FAT_read(sb, clu.dir, &clu.dir) == -1) { + ret = FFS_MEDIAERR; + goto out; + } + clu_offset--; + } + } + } + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + if (dir.dir == CLUSTER_32(0)) /* FAT16 root_dir */ + i = dentry % dentries_per_clu; + else + i = dentry & (dentries_per_clu - 1); + + for ( ; i < dentries_per_clu; i++, dentry++) { + ep = get_entry_in_dir(sb, &clu, i, §or); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + type = fs_func->get_entry_type(ep); + + if (type == TYPE_UNUSED) + break; + + if ((type != TYPE_FILE) && (type != TYPE_DIR)) + continue; + + buf_lock(sb, sector); + dir_entry->Attr = fs_func->get_entry_attr(ep); + + fs_func->get_entry_time(ep, &tm, TM_CREATE); + dir_entry->CreateTimestamp.Year = tm.year; + dir_entry->CreateTimestamp.Month = tm.mon; + dir_entry->CreateTimestamp.Day = tm.day; + dir_entry->CreateTimestamp.Hour = tm.hour; + dir_entry->CreateTimestamp.Minute = tm.min; + dir_entry->CreateTimestamp.Second = tm.sec; + dir_entry->CreateTimestamp.MilliSecond = 0; + + fs_func->get_entry_time(ep, &tm, TM_MODIFY); + dir_entry->ModifyTimestamp.Year = tm.year; + dir_entry->ModifyTimestamp.Month = tm.mon; + dir_entry->ModifyTimestamp.Day = tm.day; + dir_entry->ModifyTimestamp.Hour = tm.hour; + dir_entry->ModifyTimestamp.Minute = tm.min; + dir_entry->ModifyTimestamp.Second = tm.sec; + dir_entry->ModifyTimestamp.MilliSecond = 0; + + memset((char *)&dir_entry->AccessTimestamp, 0, + sizeof(struct date_time_t)); + + *(uni_name.name) = 0x0; + fs_func->get_uni_name_from_ext_entry(sb, &dir, dentry, + uni_name.name); + if (*uni_name.name == 0x0 && p_fs->vol_type != EXFAT) + get_uni_name_from_dos_entry(sb, + (struct dos_dentry_t *)ep, + &uni_name, 0x1); + nls_uniname_to_cstring(sb, dir_entry->Name, &uni_name); + buf_unlock(sb, sector); + + if (p_fs->vol_type == EXFAT) { + ep = get_entry_in_dir(sb, &clu, i + 1, NULL); + if (!ep) { + ret = FFS_MEDIAERR; + goto out; + } + } else { + get_uni_name_from_dos_entry(sb, + (struct dos_dentry_t *)ep, + &uni_name, 0x0); + nls_uniname_to_cstring(sb, dir_entry->ShortName, + &uni_name); + } + + dir_entry->Size = fs_func->get_entry_size(ep); + + /* hint information */ + if (dir.dir == CLUSTER_32(0)) { /* FAT16 root_dir */ + } else { + fid->hint_last_off = dentry >> + dentries_per_clu_bits; + fid->hint_last_clu = clu.dir; + } + + fid->rwoffset = (s64)(++dentry); + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + goto out; + } + + if (dir.dir == CLUSTER_32(0)) + break; /* FAT16 root_dir */ + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + /* clu.dir = FAT_read(sb, clu.dir); */ + if (FAT_read(sb, clu.dir, &clu.dir) == -1) { + ret = FFS_MEDIAERR; + goto out; + } + } + } + + *(dir_entry->Name) = '\0'; + + fid->rwoffset = (s64)(++dentry); + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +static int ffsRemoveDir(struct inode *inode, struct file_id_t *fid) +{ + s32 dentry; + int ret = FFS_SUCCESS; + struct chain_t dir, clu_to_free; + struct super_block *sb = inode->i_sb; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + /* check the validity of the given file id */ + if (!fid) + return FFS_INVALIDFID; + + dir.dir = fid->dir.dir; + dir.size = fid->dir.size; + dir.flags = fid->dir.flags; + + dentry = fid->entry; + + /* check if the file is "." or ".." */ + if (p_fs->vol_type != EXFAT) { + if ((dir.dir != p_fs->root_dir) && (dentry < 2)) + return FFS_PERMISSIONERR; + } + + /* acquire the lock for file system critical section */ + down(&p_fs->v_sem); + + clu_to_free.dir = fid->start_clu; + clu_to_free.size = (s32)((fid->size - 1) >> p_fs->cluster_size_bits) + 1; + clu_to_free.flags = fid->flags; + + if (!is_dir_empty(sb, &clu_to_free)) { + ret = FFS_FILEEXIST; + goto out; + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + /* (1) update the directory entry */ + remove_file(inode, &dir, dentry); + + /* (2) free the clusters */ + p_fs->fs_func->free_cluster(sb, &clu_to_free, 1); + + fid->size = 0; + fid->start_clu = CLUSTER_32(~0); + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + +#ifdef CONFIG_EXFAT_DELAYED_SYNC + fs_sync(sb, false); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + ret = FFS_MEDIAERR; + +out: + /* release the lock for file system critical section */ + up(&p_fs->v_sem); + + return ret; +} + +/*======================================================================*/ +/* Directory Entry Operations */ +/*======================================================================*/ + +static int exfat_readdir(struct file *filp, struct dir_context *ctx) +{ + struct inode *inode = file_inode(filp); + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct fs_info_t *p_fs = &(sbi->fs_info); + struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info); + struct dir_entry_t de; + unsigned long inum; + loff_t cpos; + int err = 0; + + __lock_super(sb); + + cpos = ctx->pos; + /* Fake . and .. for the root directory. */ + if ((p_fs->vol_type == EXFAT) || (inode->i_ino == EXFAT_ROOT_INO)) { + while (cpos < 2) { + if (inode->i_ino == EXFAT_ROOT_INO) + inum = EXFAT_ROOT_INO; + else if (cpos == 0) + inum = inode->i_ino; + else /* (cpos == 1) */ + inum = parent_ino(filp->f_path.dentry); + + if (!dir_emit_dots(filp, ctx)) + goto out; + cpos++; + ctx->pos++; + } + if (cpos == 2) + cpos = 0; + } + if (cpos & (DENTRY_SIZE - 1)) { + err = -ENOENT; + goto out; + } + +get_new: + EXFAT_I(inode)->fid.size = i_size_read(inode); + EXFAT_I(inode)->fid.rwoffset = cpos >> DENTRY_SIZE_BITS; + + err = ffsReadDir(inode, &de); + if (err) { + /* at least we tried to read a sector + * move cpos to next sector position (should be aligned) + */ + if (err == FFS_MEDIAERR) { + cpos += 1 << p_bd->sector_size_bits; + cpos &= ~((1 << p_bd->sector_size_bits) - 1); + } + + err = -EIO; + goto end_of_dir; + } + + cpos = EXFAT_I(inode)->fid.rwoffset << DENTRY_SIZE_BITS; + + if (!de.Name[0]) + goto end_of_dir; + + if (!memcmp(de.ShortName, DOS_CUR_DIR_NAME, DOS_NAME_LENGTH)) { + inum = inode->i_ino; + } else if (!memcmp(de.ShortName, DOS_PAR_DIR_NAME, DOS_NAME_LENGTH)) { + inum = parent_ino(filp->f_path.dentry); + } else { + loff_t i_pos = ((loff_t)EXFAT_I(inode)->fid.start_clu << 32) | + ((EXFAT_I(inode)->fid.rwoffset - 1) & 0xffffffff); + struct inode *tmp = exfat_iget(sb, i_pos); + + if (tmp) { + inum = tmp->i_ino; + iput(tmp); + } else { + inum = iunique(sb, EXFAT_ROOT_INO); + } + } + + if (!dir_emit(ctx, de.Name, strlen(de.Name), inum, + (de.Attr & ATTR_SUBDIR) ? DT_DIR : DT_REG)) + goto out; + + ctx->pos = cpos; + goto get_new; + +end_of_dir: + ctx->pos = cpos; +out: + __unlock_super(sb); + return err; +} + +static int exfat_ioctl_volume_id(struct inode *dir) +{ + struct super_block *sb = dir->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct fs_info_t *p_fs = &(sbi->fs_info); + + return p_fs->vol_id; +} + +static long exfat_generic_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ +struct inode *inode = filp->f_path.dentry->d_inode; +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + unsigned int flags; +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + + switch (cmd) { + case EXFAT_IOCTL_GET_VOLUME_ID: + return exfat_ioctl_volume_id(inode); +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + case EXFAT_IOC_GET_DEBUGFLAGS: { + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + flags = sbi->debug_flags; + return put_user(flags, (int __user *)arg); + } + case EXFAT_IOC_SET_DEBUGFLAGS: { + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (get_user(flags, (int __user *)arg)) + return -EFAULT; + + __lock_super(sb); + sbi->debug_flags = flags; + __unlock_super(sb); + + return 0; + } +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + default: + return -ENOTTY; /* Inappropriate ioctl for device */ + } +} + +static const struct file_operations exfat_dir_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .iterate = exfat_readdir, + .unlocked_ioctl = exfat_generic_ioctl, + .fsync = generic_file_fsync, +}; + +static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, + bool excl) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct file_id_t fid; + loff_t i_pos; + int err; + + __lock_super(sb); + + pr_debug("%s entered\n", __func__); + + err = ffsCreateFile(dir, (u8 *)dentry->d_name.name, FM_REGULAR, &fid); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_FULL) + err = -ENOSPC; + else if (err == FFS_NAMETOOLONG) + err = -ENAMETOOLONG; + else + err = -EIO; + goto out; + } + INC_IVERSION(dir); + dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir); + if (IS_DIRSYNC(dir)) + (void)exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + i_pos = ((loff_t)fid.dir.dir << 32) | (fid.entry & 0xffffffff); + + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + INC_IVERSION(inode); + inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); + /* + * timestamp is already written, so mark_inode_dirty() is unnecessary. + */ + + dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); + d_instantiate(dentry, inode); + +out: + __unlock_super(sb); + pr_debug("%s exited\n", __func__); + return err; +} + +static int exfat_find(struct inode *dir, struct qstr *qname, + struct file_id_t *fid) +{ + int err; + + if (qname->len == 0) + return -ENOENT; + + err = ffsLookupFile(dir, (u8 *)qname->name, fid); + if (err) + return -ENOENT; + + return 0; +} + +static int exfat_d_anon_disconn(struct dentry *dentry) +{ + return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED); +} + +static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry, + unsigned int flags) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct dentry *alias; + int err; + struct file_id_t fid; + loff_t i_pos; + u64 ret; + mode_t i_mode; + + __lock_super(sb); + pr_debug("%s entered\n", __func__); + err = exfat_find(dir, &dentry->d_name, &fid); + if (err) { + if (err == -ENOENT) { + inode = NULL; + goto out; + } + goto error; + } + + i_pos = ((loff_t)fid.dir.dir << 32) | (fid.entry & 0xffffffff); + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto error; + } + + i_mode = inode->i_mode; + if (S_ISLNK(i_mode) && !EXFAT_I(inode)->target) { + EXFAT_I(inode)->target = kmalloc(i_size_read(inode) + 1, + GFP_KERNEL); + if (!EXFAT_I(inode)->target) { + err = -ENOMEM; + goto error; + } + ffsReadFile(dir, &fid, EXFAT_I(inode)->target, + i_size_read(inode), &ret); + *(EXFAT_I(inode)->target + i_size_read(inode)) = '\0'; + } + + alias = d_find_alias(inode); + if (alias && !exfat_d_anon_disconn(alias)) { + BUG_ON(d_unhashed(alias)); + if (!S_ISDIR(i_mode)) + d_move(alias, dentry); + iput(inode); + __unlock_super(sb); + pr_debug("%s exited 1\n", __func__); + return alias; + } + dput(alias); +out: + __unlock_super(sb); + dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); + dentry = d_splice_alias(inode, dentry); + if (dentry) + dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); + pr_debug("%s exited 2\n", __func__); + return dentry; + +error: + __unlock_super(sb); + pr_debug("%s exited 3\n", __func__); + return ERR_PTR(err); +} + +static inline unsigned long exfat_hash(loff_t i_pos) +{ + return hash_32(i_pos, EXFAT_HASH_BITS); +} + +static void exfat_attach(struct inode *inode, loff_t i_pos) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); + + spin_lock(&sbi->inode_hash_lock); + EXFAT_I(inode)->i_pos = i_pos; + hlist_add_head(&EXFAT_I(inode)->i_hash_fat, head); + spin_unlock(&sbi->inode_hash_lock); +} + +static void exfat_detach(struct inode *inode) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + + spin_lock(&sbi->inode_hash_lock); + hlist_del_init(&EXFAT_I(inode)->i_hash_fat); + EXFAT_I(inode)->i_pos = 0; + spin_unlock(&sbi->inode_hash_lock); +} + +static int exfat_unlink(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct super_block *sb = dir->i_sb; + int err; + + __lock_super(sb); + + pr_debug("%s entered\n", __func__); + + EXFAT_I(inode)->fid.size = i_size_read(inode); + + err = ffsRemoveFile(dir, &(EXFAT_I(inode)->fid)); + if (err) { + if (err == FFS_PERMISSIONERR) + err = -EPERM; + else + err = -EIO; + goto out; + } + INC_IVERSION(dir); + dir->i_mtime = dir->i_atime = current_time(dir); + if (IS_DIRSYNC(dir)) + (void)exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + clear_nlink(inode); + inode->i_mtime = inode->i_atime = current_time(inode); + exfat_detach(inode); + remove_inode_hash(inode); + +out: + __unlock_super(sb); + pr_debug("%s exited\n", __func__); + return err; +} + +static int exfat_symlink(struct inode *dir, struct dentry *dentry, + const char *target) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct file_id_t fid; + loff_t i_pos; + int err; + u64 len = (u64)strlen(target); + u64 ret; + + __lock_super(sb); + + pr_debug("%s entered\n", __func__); + + err = ffsCreateFile(dir, (u8 *)dentry->d_name.name, FM_SYMLINK, &fid); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_FULL) + err = -ENOSPC; + else + err = -EIO; + goto out; + } + + err = ffsWriteFile(dir, &fid, (char *)target, len, &ret); + + if (err) { + ffsRemoveFile(dir, &fid); + + if (err == FFS_FULL) + err = -ENOSPC; + else + err = -EIO; + goto out; + } + + INC_IVERSION(dir); + dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir); + if (IS_DIRSYNC(dir)) + (void)exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + i_pos = ((loff_t)fid.dir.dir << 32) | (fid.entry & 0xffffffff); + + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + INC_IVERSION(inode); + inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); + /* timestamp is already written, so mark_inode_dirty() is unneeded. */ + + EXFAT_I(inode)->target = kmemdup(target, len + 1, GFP_KERNEL); + if (!EXFAT_I(inode)->target) { + err = -ENOMEM; + goto out; + } + + dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); + d_instantiate(dentry, inode); + +out: + __unlock_super(sb); + pr_debug("%s exited\n", __func__); + return err; +} + +static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct file_id_t fid; + loff_t i_pos; + int err; + + __lock_super(sb); + + pr_debug("%s entered\n", __func__); + + err = ffsCreateDir(dir, (u8 *)dentry->d_name.name, &fid); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_FULL) + err = -ENOSPC; + else if (err == FFS_NAMETOOLONG) + err = -ENAMETOOLONG; + else + err = -EIO; + goto out; + } + INC_IVERSION(dir); + dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir); + if (IS_DIRSYNC(dir)) + (void)exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + inc_nlink(dir); + + i_pos = ((loff_t)fid.dir.dir << 32) | (fid.entry & 0xffffffff); + + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + INC_IVERSION(inode); + inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); + /* timestamp is already written, so mark_inode_dirty() is unneeded. */ + + dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode); + d_instantiate(dentry, inode); + +out: + __unlock_super(sb); + pr_debug("%s exited\n", __func__); + return err; +} + +static int exfat_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct super_block *sb = dir->i_sb; + int err; + + __lock_super(sb); + + pr_debug("%s entered\n", __func__); + + EXFAT_I(inode)->fid.size = i_size_read(inode); + + err = ffsRemoveDir(dir, &(EXFAT_I(inode)->fid)); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -ENOTEMPTY; + else if (err == FFS_NOTFOUND) + err = -ENOENT; + else if (err == FFS_DIRBUSY) + err = -EBUSY; + else + err = -EIO; + goto out; + } + INC_IVERSION(dir); + dir->i_mtime = dir->i_atime = current_time(dir); + if (IS_DIRSYNC(dir)) + (void)exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + drop_nlink(dir); + + clear_nlink(inode); + inode->i_mtime = inode->i_atime = current_time(inode); + exfat_detach(inode); + remove_inode_hash(inode); + +out: + __unlock_super(sb); + pr_debug("%s exited\n", __func__); + return err; +} + +static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) +{ + struct inode *old_inode, *new_inode; + struct super_block *sb = old_dir->i_sb; + loff_t i_pos; + int err; + + if (flags) + return -EINVAL; + + __lock_super(sb); + + pr_debug("%s entered\n", __func__); + + old_inode = old_dentry->d_inode; + new_inode = new_dentry->d_inode; + + EXFAT_I(old_inode)->fid.size = i_size_read(old_inode); + + err = ffsMoveFile(old_dir, &(EXFAT_I(old_inode)->fid), new_dir, + new_dentry); + if (err) { + if (err == FFS_PERMISSIONERR) + err = -EPERM; + else if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_NOTFOUND) + err = -ENOENT; + else if (err == FFS_FULL) + err = -ENOSPC; + else + err = -EIO; + goto out; + } + INC_IVERSION(new_dir); + new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime = + current_time(new_dir); + if (IS_DIRSYNC(new_dir)) + (void)exfat_sync_inode(new_dir); + else + mark_inode_dirty(new_dir); + + i_pos = ((loff_t)EXFAT_I(old_inode)->fid.dir.dir << 32) | + (EXFAT_I(old_inode)->fid.entry & 0xffffffff); + + exfat_detach(old_inode); + exfat_attach(old_inode, i_pos); + if (IS_DIRSYNC(new_dir)) + (void)exfat_sync_inode(old_inode); + else + mark_inode_dirty(old_inode); + + if ((S_ISDIR(old_inode->i_mode)) && (old_dir != new_dir)) { + drop_nlink(old_dir); + if (!new_inode) + inc_nlink(new_dir); + } + INC_IVERSION(old_dir); + old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir); + if (IS_DIRSYNC(old_dir)) + (void)exfat_sync_inode(old_dir); + else + mark_inode_dirty(old_dir); + + if (new_inode) { + exfat_detach(new_inode); + drop_nlink(new_inode); + if (S_ISDIR(new_inode->i_mode)) + drop_nlink(new_inode); + new_inode->i_ctime = current_time(new_inode); + } + +out: + __unlock_super(sb); + pr_debug("%s exited\n", __func__); + return err; +} + +static int exfat_cont_expand(struct inode *inode, loff_t size) +{ + struct address_space *mapping = inode->i_mapping; + loff_t start = i_size_read(inode), count = size - i_size_read(inode); + int err, err2; + + err = generic_cont_expand_simple(inode, size); + if (err != 0) + return err; + + inode->i_ctime = inode->i_mtime = current_time(inode); + mark_inode_dirty(inode); + + if (IS_SYNC(inode)) { + err = filemap_fdatawrite_range(mapping, start, + start + count - 1); + err2 = sync_mapping_buffers(mapping); + err = (err) ? (err) : (err2); + err2 = write_inode_now(inode, 1); + err = (err) ? (err) : (err2); + if (!err) + err = filemap_fdatawait_range(mapping, start, + start + count - 1); + } + return err; +} + +static int exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode) +{ + mode_t allow_utime = sbi->options.allow_utime; + + if (!uid_eq(current_fsuid(), inode->i_uid)) { + if (in_group_p(inode->i_gid)) + allow_utime >>= 3; + if (allow_utime & MAY_WRITE) + return 1; + } + + /* use a default check */ + return 0; +} + +static int exfat_sanitize_mode(const struct exfat_sb_info *sbi, + struct inode *inode, umode_t *mode_ptr) +{ + mode_t i_mode, mask, perm; + + i_mode = inode->i_mode; + + if (S_ISREG(i_mode) || S_ISLNK(i_mode)) + mask = sbi->options.fs_fmask; + else + mask = sbi->options.fs_dmask; + + perm = *mode_ptr & ~(S_IFMT | mask); + + /* Of the r and x bits, all (subject to umask) must be present.*/ + if ((perm & 0555) != (i_mode & 0555)) + return -EPERM; + + if (exfat_mode_can_hold_ro(inode)) { + /* + * Of the w bits, either all (subject to umask) or none must be + * present. + */ + if ((perm & 0222) && ((perm & 0222) != (0222 & ~mask))) + return -EPERM; + } else { + /* + * If exfat_mode_can_hold_ro(inode) is false, can't change w + * bits. + */ + if ((perm & 0222) != (0222 & ~mask)) + return -EPERM; + } + + *mode_ptr &= S_IFMT | perm; + + return 0; +} + +static void exfat_truncate(struct inode *inode, loff_t old_size) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct fs_info_t *p_fs = &(sbi->fs_info); + int err; + + __lock_super(sb); + + /* + * This protects against truncating a file bigger than it was then + * trying to write into the hole. + */ + if (EXFAT_I(inode)->mmu_private > i_size_read(inode)) + EXFAT_I(inode)->mmu_private = i_size_read(inode); + + if (EXFAT_I(inode)->fid.start_clu == 0) + goto out; + + err = ffsTruncateFile(inode, old_size, i_size_read(inode)); + if (err) + goto out; + + inode->i_ctime = inode->i_mtime = current_time(inode); + if (IS_DIRSYNC(inode)) + (void)exfat_sync_inode(inode); + else + mark_inode_dirty(inode); + + inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) & + ~((loff_t)p_fs->cluster_size - 1)) >> 9; +out: + __unlock_super(sb); +} + +static int exfat_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb); + struct inode *inode = dentry->d_inode; + unsigned int ia_valid; + int error; + loff_t old_size; + + pr_debug("%s entered\n", __func__); + + if ((attr->ia_valid & ATTR_SIZE) + && (attr->ia_size > i_size_read(inode))) { + error = exfat_cont_expand(inode, attr->ia_size); + if (error || attr->ia_valid == ATTR_SIZE) + return error; + attr->ia_valid &= ~ATTR_SIZE; + } + + ia_valid = attr->ia_valid; + + if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) + && exfat_allow_set_time(sbi, inode)) { + attr->ia_valid &= ~(ATTR_MTIME_SET | + ATTR_ATIME_SET | + ATTR_TIMES_SET); + } + + error = setattr_prepare(dentry, attr); + attr->ia_valid = ia_valid; + if (error) + return error; + + if (((attr->ia_valid & ATTR_UID) && + (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) || + ((attr->ia_valid & ATTR_GID) && + (!gid_eq(attr->ia_gid, sbi->options.fs_gid))) || + ((attr->ia_valid & ATTR_MODE) && + (attr->ia_mode & ~(S_IFREG | S_IFLNK | S_IFDIR | 0777)))) { + return -EPERM; + } + + /* + * We don't return -EPERM here. Yes, strange, but this is too + * old behavior. + */ + if (attr->ia_valid & ATTR_MODE) { + if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) + attr->ia_valid &= ~ATTR_MODE; + } + + EXFAT_I(inode)->fid.size = i_size_read(inode); + + if (attr->ia_valid & ATTR_SIZE) { + old_size = i_size_read(inode); + down_write(&EXFAT_I(inode)->truncate_lock); + truncate_setsize(inode, attr->ia_size); + exfat_truncate(inode, old_size); + up_write(&EXFAT_I(inode)->truncate_lock); + } + setattr_copy(inode, attr); + mark_inode_dirty(inode); + + pr_debug("%s exited\n", __func__); + return error; +} + +static int exfat_getattr(const struct path *path, struct kstat *stat, + u32 request_mask, unsigned int flags) +{ + struct inode *inode = path->dentry->d_inode; + + pr_debug("%s entered\n", __func__); + + generic_fillattr(inode, stat); + stat->blksize = EXFAT_SB(inode->i_sb)->fs_info.cluster_size; + + pr_debug("%s exited\n", __func__); + return 0; +} + +static const struct inode_operations exfat_dir_inode_operations = { + .create = exfat_create, + .lookup = exfat_lookup, + .unlink = exfat_unlink, + .symlink = exfat_symlink, + .mkdir = exfat_mkdir, + .rmdir = exfat_rmdir, + .rename = exfat_rename, + .setattr = exfat_setattr, + .getattr = exfat_getattr, +}; + +/*======================================================================*/ +/* File Operations */ +/*======================================================================*/ +static const char *exfat_get_link(struct dentry *dentry, struct inode *inode, + struct delayed_call *done) +{ + struct exfat_inode_info *ei = EXFAT_I(inode); + + if (ei->target) { + char *cookie = ei->target; + + if (cookie) + return (char *)(ei->target); + } + return NULL; +} + +static const struct inode_operations exfat_symlink_inode_operations = { + .get_link = exfat_get_link, +}; + +static int exfat_file_release(struct inode *inode, struct file *filp) +{ + struct super_block *sb = inode->i_sb; + + EXFAT_I(inode)->fid.size = i_size_read(inode); + ffsSyncVol(sb, false); + return 0; +} + +static const struct file_operations exfat_file_operations = { + .llseek = generic_file_llseek, + .read_iter = generic_file_read_iter, + .write_iter = generic_file_write_iter, + .mmap = generic_file_mmap, + .release = exfat_file_release, + .unlocked_ioctl = exfat_generic_ioctl, + .fsync = generic_file_fsync, + .splice_read = generic_file_splice_read, +}; + +static const struct inode_operations exfat_file_inode_operations = { + .setattr = exfat_setattr, + .getattr = exfat_getattr, +}; + +/*======================================================================*/ +/* Address Space Operations */ +/*======================================================================*/ + +static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys, + unsigned long *mapped_blocks, int *create) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct fs_info_t *p_fs = &(sbi->fs_info); + struct bd_info_t *p_bd = &(sbi->bd_info); + const unsigned long blocksize = sb->s_blocksize; + const unsigned char blocksize_bits = sb->s_blocksize_bits; + sector_t last_block; + int err, clu_offset, sec_offset; + unsigned int cluster; + + *phys = 0; + *mapped_blocks = 0; + + if ((p_fs->vol_type == FAT12) || (p_fs->vol_type == FAT16)) { + if (inode->i_ino == EXFAT_ROOT_INO) { + if (sector < + (p_fs->dentries_in_root >> + (p_bd->sector_size_bits - DENTRY_SIZE_BITS))) { + *phys = sector + p_fs->root_start_sector; + *mapped_blocks = 1; + } + return 0; + } + } + + last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits; + if (sector >= last_block) { + if (*create == 0) + return 0; + } else { + *create = 0; + } + + /* cluster offset */ + clu_offset = sector >> p_fs->sectors_per_clu_bits; + + /* sector offset in cluster */ + sec_offset = sector & (p_fs->sectors_per_clu - 1); + + EXFAT_I(inode)->fid.size = i_size_read(inode); + + err = ffsMapCluster(inode, clu_offset, &cluster); + + if (err) { + if (err == FFS_FULL) + return -ENOSPC; + else + return -EIO; + } else if (cluster != CLUSTER_32(~0)) { + *phys = START_SECTOR(cluster) + sec_offset; + *mapped_blocks = p_fs->sectors_per_clu - sec_offset; + } + + return 0; +} + +static int exfat_get_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + struct super_block *sb = inode->i_sb; + unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; + int err; + unsigned long mapped_blocks; + sector_t phys; + + __lock_super(sb); + + err = exfat_bmap(inode, iblock, &phys, &mapped_blocks, &create); + if (err) { + __unlock_super(sb); + return err; + } + + if (phys) { + max_blocks = min(mapped_blocks, max_blocks); + if (create) { + EXFAT_I(inode)->mmu_private += max_blocks << + sb->s_blocksize_bits; + set_buffer_new(bh_result); + } + map_bh(bh_result, sb, phys); + } + + bh_result->b_size = max_blocks << sb->s_blocksize_bits; + __unlock_super(sb); + + return 0; +} + +static int exfat_readpage(struct file *file, struct page *page) +{ + return mpage_readpage(page, exfat_get_block); +} + +static int exfat_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned int nr_pages) +{ + return mpage_readpages(mapping, pages, nr_pages, exfat_get_block); +} + +static int exfat_writepage(struct page *page, struct writeback_control *wbc) +{ + return block_write_full_page(page, exfat_get_block, wbc); +} + +static int exfat_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + return mpage_writepages(mapping, wbc, exfat_get_block); +} + +static void exfat_write_failed(struct address_space *mapping, loff_t to) +{ + struct inode *inode = mapping->host; + + if (to > i_size_read(inode)) { + truncate_pagecache(inode, i_size_read(inode)); + EXFAT_I(inode)->fid.size = i_size_read(inode); + exfat_truncate(inode, i_size_read(inode)); + } +} + +static int exfat_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned int len, unsigned int flags, + struct page **pagep, void **fsdata) +{ + int ret; + + *pagep = NULL; + ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, + exfat_get_block, + &EXFAT_I(mapping->host)->mmu_private); + + if (ret < 0) + exfat_write_failed(mapping, pos + len); + return ret; +} + +static int exfat_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned int len, unsigned int copied, + struct page *pagep, void *fsdata) +{ + struct inode *inode = mapping->host; + struct file_id_t *fid = &(EXFAT_I(inode)->fid); + int err; + + err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); + + if (err < len) + exfat_write_failed(mapping, pos + len); + + if (!(err < 0) && !(fid->attr & ATTR_ARCHIVE)) { + inode->i_mtime = inode->i_ctime = current_time(inode); + fid->attr |= ATTR_ARCHIVE; + mark_inode_dirty(inode); + } + return err; +} + +static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) +{ + struct inode *inode = iocb->ki_filp->f_mapping->host; + struct address_space *mapping = iocb->ki_filp->f_mapping; + ssize_t ret; + int rw; + + rw = iov_iter_rw(iter); + + if (rw == WRITE) { + if (EXFAT_I(inode)->mmu_private < iov_iter_count(iter)) + return 0; + } + ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block); + + if ((ret < 0) && (rw & WRITE)) + exfat_write_failed(mapping, iov_iter_count(iter)); + return ret; +} + +static sector_t _exfat_bmap(struct address_space *mapping, sector_t block) +{ + sector_t blocknr; + + /* exfat_get_cluster() assumes the requested blocknr isn't truncated. */ + down_read(&EXFAT_I(mapping->host)->truncate_lock); + blocknr = generic_block_bmap(mapping, block, exfat_get_block); + up_read(&EXFAT_I(mapping->host)->truncate_lock); + + return blocknr; +} + +static const struct address_space_operations exfat_aops = { + .readpage = exfat_readpage, + .readpages = exfat_readpages, + .writepage = exfat_writepage, + .writepages = exfat_writepages, + .write_begin = exfat_write_begin, + .write_end = exfat_write_end, + .direct_IO = exfat_direct_IO, + .bmap = _exfat_bmap +}; + +/*======================================================================*/ +/* Super Operations */ +/*======================================================================*/ + +static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *info; + struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); + struct inode *inode = NULL; + + spin_lock(&sbi->inode_hash_lock); + hlist_for_each_entry(info, head, i_hash_fat) { + BUG_ON(info->vfs_inode.i_sb != sb); + + if (i_pos != info->i_pos) + continue; + inode = igrab(&info->vfs_inode); + if (inode) + break; + } + spin_unlock(&sbi->inode_hash_lock); + return inode; +} + +/* doesn't deal with root inode */ +static int exfat_fill_inode(struct inode *inode, struct file_id_t *fid) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + struct fs_info_t *p_fs = &(sbi->fs_info); + struct dir_entry_t info; + + memcpy(&(EXFAT_I(inode)->fid), fid, sizeof(struct file_id_t)); + + ffsReadStat(inode, &info); + + EXFAT_I(inode)->i_pos = 0; + EXFAT_I(inode)->target = NULL; + inode->i_uid = sbi->options.fs_uid; + inode->i_gid = sbi->options.fs_gid; + INC_IVERSION(inode); + inode->i_generation = get_seconds(); + + if (info.Attr & ATTR_SUBDIR) { /* directory */ + inode->i_generation &= ~1; + inode->i_mode = exfat_make_mode(sbi, info.Attr, 0777); + inode->i_op = &exfat_dir_inode_operations; + inode->i_fop = &exfat_dir_operations; + + i_size_write(inode, info.Size); + EXFAT_I(inode)->mmu_private = i_size_read(inode); + set_nlink(inode, info.NumSubdirs); + } else if (info.Attr & ATTR_SYMLINK) { /* symbolic link */ + inode->i_generation |= 1; + inode->i_mode = exfat_make_mode(sbi, info.Attr, 0777); + inode->i_op = &exfat_symlink_inode_operations; + + i_size_write(inode, info.Size); + EXFAT_I(inode)->mmu_private = i_size_read(inode); + } else { /* regular file */ + inode->i_generation |= 1; + inode->i_mode = exfat_make_mode(sbi, info.Attr, 0777); + inode->i_op = &exfat_file_inode_operations; + inode->i_fop = &exfat_file_operations; + inode->i_mapping->a_ops = &exfat_aops; + inode->i_mapping->nrpages = 0; + + i_size_write(inode, info.Size); + EXFAT_I(inode)->mmu_private = i_size_read(inode); + } + exfat_save_attr(inode, info.Attr); + + inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) + & ~((loff_t)p_fs->cluster_size - 1)) >> 9; + + exfat_time_fat2unix(&inode->i_mtime, &info.ModifyTimestamp); + exfat_time_fat2unix(&inode->i_ctime, &info.CreateTimestamp); + exfat_time_fat2unix(&inode->i_atime, &info.AccessTimestamp); + + return 0; +} + +static struct inode *exfat_build_inode(struct super_block *sb, + struct file_id_t *fid, loff_t i_pos) +{ + struct inode *inode; + int err; + + inode = exfat_iget(sb, i_pos); + if (inode) + goto out; + inode = new_inode(sb); + if (!inode) { + inode = ERR_PTR(-ENOMEM); + goto out; + } + inode->i_ino = iunique(sb, EXFAT_ROOT_INO); + SET_IVERSION(inode, 1); + err = exfat_fill_inode(inode, fid); + if (err) { + iput(inode); + inode = ERR_PTR(err); + goto out; + } + exfat_attach(inode, i_pos); + insert_inode_hash(inode); +out: + return inode; +} + +static int exfat_sync_inode(struct inode *inode) +{ + return exfat_write_inode(inode, NULL); +} + +static struct inode *exfat_alloc_inode(struct super_block *sb) +{ + struct exfat_inode_info *ei; + + ei = kmem_cache_alloc(exfat_inode_cachep, GFP_NOFS); + if (!ei) + return NULL; + + init_rwsem(&ei->truncate_lock); + + return &ei->vfs_inode; +} + +static void exfat_destroy_inode(struct inode *inode) +{ + kfree(EXFAT_I(inode)->target); + EXFAT_I(inode)->target = NULL; + + kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode)); +} + +static int exfat_write_inode(struct inode *inode, struct writeback_control *wbc) +{ + struct dir_entry_t info; + + if (inode->i_ino == EXFAT_ROOT_INO) + return 0; + + info.Attr = exfat_make_attr(inode); + info.Size = i_size_read(inode); + + exfat_time_unix2fat(&inode->i_mtime, &info.ModifyTimestamp); + exfat_time_unix2fat(&inode->i_ctime, &info.CreateTimestamp); + exfat_time_unix2fat(&inode->i_atime, &info.AccessTimestamp); + + ffsWriteStat(inode, &info); + + return 0; +} + +static void exfat_evict_inode(struct inode *inode) +{ + truncate_inode_pages(&inode->i_data, 0); + + if (!inode->i_nlink) + i_size_write(inode, 0); + invalidate_inode_buffers(inode); + clear_inode(inode); + exfat_detach(inode); + + remove_inode_hash(inode); +} + +static void exfat_free_super(struct exfat_sb_info *sbi) +{ + if (sbi->nls_disk) + unload_nls(sbi->nls_disk); + if (sbi->nls_io) + unload_nls(sbi->nls_io); + if (sbi->options.iocharset != exfat_default_iocharset) + kfree(sbi->options.iocharset); + /* mutex_init is in exfat_fill_super function. only for 3.7+ */ + mutex_destroy(&sbi->s_lock); + kfree(sbi); +} + +static void exfat_put_super(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + if (__is_sb_dirty(sb)) + exfat_write_super(sb); + + ffsUmountVol(sb); + + sb->s_fs_info = NULL; + exfat_free_super(sbi); +} + +static void exfat_write_super(struct super_block *sb) +{ + __lock_super(sb); + + __set_sb_clean(sb); + + if (!sb_rdonly(sb)) + ffsSyncVol(sb, true); + + __unlock_super(sb); +} + +static int exfat_sync_fs(struct super_block *sb, int wait) +{ + int err = 0; + + if (__is_sb_dirty(sb)) { + __lock_super(sb); + __set_sb_clean(sb); + err = ffsSyncVol(sb, true); + __unlock_super(sb); + } + + return err; +} + +static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct super_block *sb = dentry->d_sb; + u64 id = huge_encode_dev(sb->s_bdev->bd_dev); + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + struct vol_info_t info; + + if (p_fs->used_clusters == UINT_MAX) { + if (ffsGetVolInfo(sb, &info) == FFS_MEDIAERR) + return -EIO; + + } else { + info.FatType = p_fs->vol_type; + info.ClusterSize = p_fs->cluster_size; + info.NumClusters = p_fs->num_clusters - 2; + info.UsedClusters = p_fs->used_clusters; + info.FreeClusters = info.NumClusters - info.UsedClusters; + + if (p_fs->dev_ejected) + pr_info("[EXFAT] statfs on device that is ejected\n"); + } + + buf->f_type = sb->s_magic; + buf->f_bsize = info.ClusterSize; + buf->f_blocks = info.NumClusters; + buf->f_bfree = info.FreeClusters; + buf->f_bavail = info.FreeClusters; + buf->f_fsid.val[0] = (u32)id; + buf->f_fsid.val[1] = (u32)(id >> 32); + buf->f_namelen = 260; + + return 0; +} + +static int exfat_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= SB_NODIRATIME; + return 0; +} + +static int exfat_show_options(struct seq_file *m, struct dentry *root) +{ + struct exfat_sb_info *sbi = EXFAT_SB(root->d_sb); + struct exfat_mount_options *opts = &sbi->options; + + if (__kuid_val(opts->fs_uid)) + seq_printf(m, ",uid=%u", __kuid_val(opts->fs_uid)); + if (__kgid_val(opts->fs_gid)) + seq_printf(m, ",gid=%u", __kgid_val(opts->fs_gid)); + seq_printf(m, ",fmask=%04o", opts->fs_fmask); + seq_printf(m, ",dmask=%04o", opts->fs_dmask); + if (opts->allow_utime) + seq_printf(m, ",allow_utime=%04o", opts->allow_utime); + if (sbi->nls_disk) + seq_printf(m, ",codepage=%s", sbi->nls_disk->charset); + if (sbi->nls_io) + seq_printf(m, ",iocharset=%s", sbi->nls_io->charset); + seq_printf(m, ",namecase=%u", opts->casesensitive); + if (opts->errors == EXFAT_ERRORS_CONT) + seq_puts(m, ",errors=continue"); + else if (opts->errors == EXFAT_ERRORS_PANIC) + seq_puts(m, ",errors=panic"); + else + seq_puts(m, ",errors=remount-ro"); +#ifdef CONFIG_EXFAT_DISCARD + if (opts->discard) + seq_puts(m, ",discard"); +#endif + return 0; +} + +static const struct super_operations exfat_sops = { + .alloc_inode = exfat_alloc_inode, + .destroy_inode = exfat_destroy_inode, + .write_inode = exfat_write_inode, + .evict_inode = exfat_evict_inode, + .put_super = exfat_put_super, + .sync_fs = exfat_sync_fs, + .statfs = exfat_statfs, + .remount_fs = exfat_remount, + .show_options = exfat_show_options, +}; + +/*======================================================================*/ +/* Export Operations */ +/*======================================================================*/ + +static struct inode *exfat_nfs_get_inode(struct super_block *sb, u64 ino, + u32 generation) +{ + struct inode *inode = NULL; + + if (ino < EXFAT_ROOT_INO) + return inode; + inode = ilookup(sb, ino); + + if (inode && generation && (inode->i_generation != generation)) { + iput(inode); + inode = NULL; + } + + return inode; +} + +static struct dentry *exfat_fh_to_dentry(struct super_block *sb, + struct fid *fid, int fh_len, + int fh_type) +{ + return generic_fh_to_dentry(sb, fid, fh_len, fh_type, + exfat_nfs_get_inode); +} + +static struct dentry *exfat_fh_to_parent(struct super_block *sb, + struct fid *fid, int fh_len, + int fh_type) +{ + return generic_fh_to_parent(sb, fid, fh_len, fh_type, + exfat_nfs_get_inode); +} + +static const struct export_operations exfat_export_ops = { + .fh_to_dentry = exfat_fh_to_dentry, + .fh_to_parent = exfat_fh_to_parent, +}; + +/*======================================================================*/ +/* Super Block Read Operations */ +/*======================================================================*/ + +enum { + Opt_uid, + Opt_gid, + Opt_umask, + Opt_dmask, + Opt_fmask, + Opt_allow_utime, + Opt_codepage, + Opt_charset, + Opt_namecase, + Opt_debug, + Opt_err_cont, + Opt_err_panic, + Opt_err_ro, + Opt_utf8_hack, + Opt_err, +#ifdef CONFIG_EXFAT_DISCARD + Opt_discard, +#endif /* EXFAT_CONFIG_DISCARD */ +}; + +static const match_table_t exfat_tokens = { + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_umask, "umask=%o"}, + {Opt_dmask, "dmask=%o"}, + {Opt_fmask, "fmask=%o"}, + {Opt_allow_utime, "allow_utime=%o"}, + {Opt_codepage, "codepage=%u"}, + {Opt_charset, "iocharset=%s"}, + {Opt_namecase, "namecase=%u"}, + {Opt_debug, "debug"}, + {Opt_err_cont, "errors=continue"}, + {Opt_err_panic, "errors=panic"}, + {Opt_err_ro, "errors=remount-ro"}, + {Opt_utf8_hack, "utf8"}, +#ifdef CONFIG_EXFAT_DISCARD + {Opt_discard, "discard"}, +#endif /* CONFIG_EXFAT_DISCARD */ + {Opt_err, NULL} +}; + +static int parse_options(char *options, int silent, int *debug, + struct exfat_mount_options *opts) +{ + char *p; + substring_t args[MAX_OPT_ARGS]; + int option; + char *iocharset; + + opts->fs_uid = current_uid(); + opts->fs_gid = current_gid(); + opts->fs_fmask = opts->fs_dmask = current->fs->umask; + opts->allow_utime = U16_MAX; + opts->codepage = exfat_default_codepage; + opts->iocharset = exfat_default_iocharset; + opts->casesensitive = 0; + opts->errors = EXFAT_ERRORS_RO; +#ifdef CONFIG_EXFAT_DISCARD + opts->discard = 0; +#endif + *debug = 0; + + if (!options) + goto out; + + while ((p = strsep(&options, ","))) { + int token; + + if (!*p) + continue; + + token = match_token(p, exfat_tokens, args); + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + return 0; + opts->fs_uid = KUIDT_INIT(option); + break; + case Opt_gid: + if (match_int(&args[0], &option)) + return 0; + opts->fs_gid = KGIDT_INIT(option); + break; + case Opt_umask: + case Opt_dmask: + case Opt_fmask: + if (match_octal(&args[0], &option)) + return 0; + if (token != Opt_dmask) + opts->fs_fmask = option; + if (token != Opt_fmask) + opts->fs_dmask = option; + break; + case Opt_allow_utime: + if (match_octal(&args[0], &option)) + return 0; + opts->allow_utime = option & 0022; + break; + case Opt_codepage: + if (match_int(&args[0], &option)) + return 0; + opts->codepage = option; + break; + case Opt_charset: + if (opts->iocharset != exfat_default_iocharset) + kfree(opts->iocharset); + iocharset = match_strdup(&args[0]); + if (!iocharset) + return -ENOMEM; + opts->iocharset = iocharset; + break; + case Opt_namecase: + if (match_int(&args[0], &option)) + return 0; + opts->casesensitive = option; + break; + case Opt_err_cont: + opts->errors = EXFAT_ERRORS_CONT; + break; + case Opt_err_panic: + opts->errors = EXFAT_ERRORS_PANIC; + break; + case Opt_err_ro: + opts->errors = EXFAT_ERRORS_RO; + break; + case Opt_debug: + *debug = 1; + break; +#ifdef CONFIG_EXFAT_DISCARD + case Opt_discard: + opts->discard = 1; + break; +#endif /* CONFIG_EXFAT_DISCARD */ + case Opt_utf8_hack: + break; + default: + if (!silent) + pr_err("[EXFAT] Unrecognized mount option %s or missing value\n", + p); + return -EINVAL; + } + } + +out: + if (opts->allow_utime == U16_MAX) + opts->allow_utime = ~opts->fs_dmask & 0022; + + return 0; +} + +static void exfat_hash_init(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + int i; + + spin_lock_init(&sbi->inode_hash_lock); + for (i = 0; i < EXFAT_HASH_SIZE; i++) + INIT_HLIST_HEAD(&sbi->inode_hashtable[i]); +} + +static int exfat_read_root(struct inode *inode) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct fs_info_t *p_fs = &(sbi->fs_info); + struct dir_entry_t info; + + EXFAT_I(inode)->fid.dir.dir = p_fs->root_dir; + EXFAT_I(inode)->fid.dir.flags = 0x01; + EXFAT_I(inode)->fid.entry = -1; + EXFAT_I(inode)->fid.start_clu = p_fs->root_dir; + EXFAT_I(inode)->fid.flags = 0x01; + EXFAT_I(inode)->fid.type = TYPE_DIR; + EXFAT_I(inode)->fid.rwoffset = 0; + EXFAT_I(inode)->fid.hint_last_off = -1; + + EXFAT_I(inode)->target = NULL; + + ffsReadStat(inode, &info); + + inode->i_uid = sbi->options.fs_uid; + inode->i_gid = sbi->options.fs_gid; + INC_IVERSION(inode); + inode->i_generation = 0; + inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, 0777); + inode->i_op = &exfat_dir_inode_operations; + inode->i_fop = &exfat_dir_operations; + + i_size_write(inode, info.Size); + inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) + & ~((loff_t)p_fs->cluster_size - 1)) >> 9; + EXFAT_I(inode)->i_pos = ((loff_t)p_fs->root_dir << 32) | 0xffffffff; + EXFAT_I(inode)->mmu_private = i_size_read(inode); + + exfat_save_attr(inode, ATTR_SUBDIR); + inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); + set_nlink(inode, info.NumSubdirs + 2); + + return 0; +} + +static void setup_dops(struct super_block *sb) +{ + if (EXFAT_SB(sb)->options.casesensitive == 0) + sb->s_d_op = &exfat_ci_dentry_ops; + else + sb->s_d_op = &exfat_dentry_ops; +} + +static int exfat_fill_super(struct super_block *sb, void *data, int silent) +{ + struct inode *root_inode = NULL; + struct exfat_sb_info *sbi; + int debug, ret; + long error; + char buf[50]; + + /* + * GFP_KERNEL is ok here, because while we do hold the + * supeblock lock, memory pressure can't call back into + * the filesystem, since we're only just about to mount + * it and have no inodes etc active! + */ + sbi = kzalloc(sizeof(struct exfat_sb_info), GFP_KERNEL); + if (!sbi) + return -ENOMEM; + mutex_init(&sbi->s_lock); + sb->s_fs_info = sbi; + sb->s_flags |= SB_NODIRATIME; + sb->s_magic = EXFAT_SUPER_MAGIC; + sb->s_op = &exfat_sops; + sb->s_export_op = &exfat_export_ops; + + error = parse_options(data, silent, &debug, &sbi->options); + if (error) + goto out_fail; + + setup_dops(sb); + + error = -EIO; + sb_min_blocksize(sb, 512); + sb->s_maxbytes = 0x7fffffffffffffffLL; /* maximum file size */ + + ret = ffsMountVol(sb); + if (ret) { + if (!silent) + pr_err("[EXFAT] ffsMountVol failed\n"); + + goto out_fail; + } + + /* set up enough so that it can read an inode */ + exfat_hash_init(sb); + + /* + * The low byte of FAT's first entry must have same value with + * media-field. But in real world, too many devices is + * writing wrong value. So, removed that validity check. + * + * if (FAT_FIRST_ENT(sb, media) != first) + */ + + /* codepage is not meaningful in exfat */ + if (sbi->fs_info.vol_type != EXFAT) { + error = -EINVAL; + sprintf(buf, "cp%d", sbi->options.codepage); + sbi->nls_disk = load_nls(buf); + if (!sbi->nls_disk) { + pr_err("[EXFAT] Codepage %s not found\n", buf); + goto out_fail2; + } + } + + sbi->nls_io = load_nls(sbi->options.iocharset); + + error = -ENOMEM; + root_inode = new_inode(sb); + if (!root_inode) + goto out_fail2; + root_inode->i_ino = EXFAT_ROOT_INO; + SET_IVERSION(root_inode, 1); + + error = exfat_read_root(root_inode); + if (error < 0) + goto out_fail2; + error = -ENOMEM; + exfat_attach(root_inode, EXFAT_I(root_inode)->i_pos); + insert_inode_hash(root_inode); + sb->s_root = d_make_root(root_inode); + if (!sb->s_root) { + pr_err("[EXFAT] Getting the root inode failed\n"); + goto out_fail2; + } + + return 0; + +out_fail2: + ffsUmountVol(sb); +out_fail: + if (root_inode) + iput(root_inode); + sb->s_fs_info = NULL; + exfat_free_super(sbi); + return error; +} + +static struct dentry *exfat_fs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data) +{ + return mount_bdev(fs_type, flags, dev_name, data, exfat_fill_super); +} + +static void init_once(void *foo) +{ + struct exfat_inode_info *ei = (struct exfat_inode_info *)foo; + + INIT_HLIST_NODE(&ei->i_hash_fat); + inode_init_once(&ei->vfs_inode); +} + +static int __init exfat_init_inodecache(void) +{ + exfat_inode_cachep = kmem_cache_create("exfat_inode_cache", + sizeof(struct exfat_inode_info), + 0, + (SLAB_RECLAIM_ACCOUNT | + SLAB_MEM_SPREAD), + init_once); + if (!exfat_inode_cachep) + return -ENOMEM; + return 0; +} + +static void __exit exfat_destroy_inodecache(void) +{ + /* + * Make sure all delayed rcu free inodes are flushed before we + * destroy cache. + */ + rcu_barrier(); + kmem_cache_destroy(exfat_inode_cachep); +} + +#ifdef CONFIG_EXFAT_KERNEL_DEBUG +static void exfat_debug_kill_sb(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct block_device *bdev = sb->s_bdev; + struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info); + + long flags; + + if (sbi) { + flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_INVALID_UMOUNT) { + /* + * invalidate_bdev drops all device cache include + * dirty. We use this to simulate device removal. + */ + down(&p_fs->v_sem); + FAT_release_all(sb); + buf_release_all(sb); + up(&p_fs->v_sem); + + invalidate_bdev(bdev); + } + } + + kill_block_super(sb); +} +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + +static struct file_system_type exfat_fs_type = { + .owner = THIS_MODULE, + .name = "exfat", + .mount = exfat_fs_mount, +#ifdef CONFIG_EXFAT_KERNEL_DEBUG + .kill_sb = exfat_debug_kill_sb, +#else + .kill_sb = kill_block_super, +#endif /* CONFIG_EXFAT_KERNEL_DEBUG */ + .fs_flags = FS_REQUIRES_DEV, +}; + +static int __init init_exfat(void) +{ + int err; + + BUILD_BUG_ON(sizeof(struct dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct dos_dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct ext_dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct file_dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct strm_dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct name_dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct bmap_dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct case_dentry_t) != DENTRY_SIZE); + BUILD_BUG_ON(sizeof(struct volm_dentry_t) != DENTRY_SIZE); + + pr_info("exFAT: Version %s\n", EXFAT_VERSION); + + err = exfat_init_inodecache(); + if (err) + return err; + + err = register_filesystem(&exfat_fs_type); + if (err) + return err; + + return 0; +} + +static void __exit exit_exfat(void) +{ + exfat_destroy_inodecache(); + unregister_filesystem(&exfat_fs_type); +} + +module_init(init_exfat); +module_exit(exit_exfat); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("exFAT Filesystem Driver"); +MODULE_ALIAS_FS("exfat"); diff --git a/drivers/staging/exfat/exfat_upcase.c b/drivers/staging/exfat/exfat_upcase.c new file mode 100644 index 000000000000..366082fb3dab --- /dev/null +++ b/drivers/staging/exfat/exfat_upcase.c @@ -0,0 +1,740 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + */ + +#include <linux/types.h> +#include "exfat.h" + +const u8 uni_upcase[NUM_UPCASE << 1] = { + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, + 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, + 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, + 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, + 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, + 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00, + 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, + 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, + 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, 0x00, + 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, 0x00, + 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, + 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, + 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, 0x00, + 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, + 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, + 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, + 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, + 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, 0x00, + 0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, + 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, + 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x7B, 0x00, + 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, 0x00, + 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, + 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, + 0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, + 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00, + 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, + 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, + 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, + 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, + 0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, 0x00, + 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, 0x00, + 0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, 0x00, + 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, 0x00, + 0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, 0x00, + 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, 0x00, + 0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, 0x00, + 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0x00, + 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, + 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, + 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, + 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, + 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, + 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, 0x00, + 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, + 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0xDF, 0x00, + 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, + 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, + 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, + 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, + 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, + 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xF7, 0x00, + 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, + 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0x78, 0x01, + 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, + 0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01, + 0x08, 0x01, 0x08, 0x01, 0x0A, 0x01, 0x0A, 0x01, + 0x0C, 0x01, 0x0C, 0x01, 0x0E, 0x01, 0x0E, 0x01, + 0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01, + 0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01, + 0x18, 0x01, 0x18, 0x01, 0x1A, 0x01, 0x1A, 0x01, + 0x1C, 0x01, 0x1C, 0x01, 0x1E, 0x01, 0x1E, 0x01, + 0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01, + 0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01, + 0x28, 0x01, 0x28, 0x01, 0x2A, 0x01, 0x2A, 0x01, + 0x2C, 0x01, 0x2C, 0x01, 0x2E, 0x01, 0x2E, 0x01, + 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01, + 0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01, + 0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3B, 0x01, + 0x3B, 0x01, 0x3D, 0x01, 0x3D, 0x01, 0x3F, 0x01, + 0x3F, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01, + 0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01, + 0x47, 0x01, 0x49, 0x01, 0x4A, 0x01, 0x4A, 0x01, + 0x4C, 0x01, 0x4C, 0x01, 0x4E, 0x01, 0x4E, 0x01, + 0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01, + 0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01, + 0x58, 0x01, 0x58, 0x01, 0x5A, 0x01, 0x5A, 0x01, + 0x5C, 0x01, 0x5C, 0x01, 0x5E, 0x01, 0x5E, 0x01, + 0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01, + 0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01, + 0x68, 0x01, 0x68, 0x01, 0x6A, 0x01, 0x6A, 0x01, + 0x6C, 0x01, 0x6C, 0x01, 0x6E, 0x01, 0x6E, 0x01, + 0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01, + 0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01, + 0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7B, 0x01, + 0x7B, 0x01, 0x7D, 0x01, 0x7D, 0x01, 0x7F, 0x01, + 0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01, + 0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01, + 0x87, 0x01, 0x89, 0x01, 0x8A, 0x01, 0x8B, 0x01, + 0x8B, 0x01, 0x8D, 0x01, 0x8E, 0x01, 0x8F, 0x01, + 0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01, + 0x94, 0x01, 0xF6, 0x01, 0x96, 0x01, 0x97, 0x01, + 0x98, 0x01, 0x98, 0x01, 0x3D, 0x02, 0x9B, 0x01, + 0x9C, 0x01, 0x9D, 0x01, 0x20, 0x02, 0x9F, 0x01, + 0xA0, 0x01, 0xA0, 0x01, 0xA2, 0x01, 0xA2, 0x01, + 0xA4, 0x01, 0xA4, 0x01, 0xA6, 0x01, 0xA7, 0x01, + 0xA7, 0x01, 0xA9, 0x01, 0xAA, 0x01, 0xAB, 0x01, + 0xAC, 0x01, 0xAC, 0x01, 0xAE, 0x01, 0xAF, 0x01, + 0xAF, 0x01, 0xB1, 0x01, 0xB2, 0x01, 0xB3, 0x01, + 0xB3, 0x01, 0xB5, 0x01, 0xB5, 0x01, 0xB7, 0x01, + 0xB8, 0x01, 0xB8, 0x01, 0xBA, 0x01, 0xBB, 0x01, + 0xBC, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xF7, 0x01, + 0xC0, 0x01, 0xC1, 0x01, 0xC2, 0x01, 0xC3, 0x01, + 0xC4, 0x01, 0xC5, 0x01, 0xC4, 0x01, 0xC7, 0x01, + 0xC8, 0x01, 0xC7, 0x01, 0xCA, 0x01, 0xCB, 0x01, + 0xCA, 0x01, 0xCD, 0x01, 0xCD, 0x01, 0xCF, 0x01, + 0xCF, 0x01, 0xD1, 0x01, 0xD1, 0x01, 0xD3, 0x01, + 0xD3, 0x01, 0xD5, 0x01, 0xD5, 0x01, 0xD7, 0x01, + 0xD7, 0x01, 0xD9, 0x01, 0xD9, 0x01, 0xDB, 0x01, + 0xDB, 0x01, 0x8E, 0x01, 0xDE, 0x01, 0xDE, 0x01, + 0xE0, 0x01, 0xE0, 0x01, 0xE2, 0x01, 0xE2, 0x01, + 0xE4, 0x01, 0xE4, 0x01, 0xE6, 0x01, 0xE6, 0x01, + 0xE8, 0x01, 0xE8, 0x01, 0xEA, 0x01, 0xEA, 0x01, + 0xEC, 0x01, 0xEC, 0x01, 0xEE, 0x01, 0xEE, 0x01, + 0xF0, 0x01, 0xF1, 0x01, 0xF2, 0x01, 0xF1, 0x01, + 0xF4, 0x01, 0xF4, 0x01, 0xF6, 0x01, 0xF7, 0x01, + 0xF8, 0x01, 0xF8, 0x01, 0xFA, 0x01, 0xFA, 0x01, + 0xFC, 0x01, 0xFC, 0x01, 0xFE, 0x01, 0xFE, 0x01, + 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02, + 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x0A, 0x02, + 0x0C, 0x02, 0x0C, 0x02, 0x0E, 0x02, 0x0E, 0x02, + 0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02, + 0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02, + 0x18, 0x02, 0x18, 0x02, 0x1A, 0x02, 0x1A, 0x02, + 0x1C, 0x02, 0x1C, 0x02, 0x1E, 0x02, 0x1E, 0x02, + 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02, + 0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02, + 0x28, 0x02, 0x28, 0x02, 0x2A, 0x02, 0x2A, 0x02, + 0x2C, 0x02, 0x2C, 0x02, 0x2E, 0x02, 0x2E, 0x02, + 0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02, + 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, + 0x38, 0x02, 0x39, 0x02, 0x65, 0x2C, 0x3B, 0x02, + 0x3B, 0x02, 0x3D, 0x02, 0x66, 0x2C, 0x3F, 0x02, + 0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02, + 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02, + 0x48, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x4A, 0x02, + 0x4C, 0x02, 0x4C, 0x02, 0x4E, 0x02, 0x4E, 0x02, + 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01, + 0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8A, 0x01, + 0x58, 0x02, 0x8F, 0x01, 0x5A, 0x02, 0x90, 0x01, + 0x5C, 0x02, 0x5D, 0x02, 0x5E, 0x02, 0x5F, 0x02, + 0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01, + 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02, + 0x97, 0x01, 0x96, 0x01, 0x6A, 0x02, 0x62, 0x2C, + 0x6C, 0x02, 0x6D, 0x02, 0x6E, 0x02, 0x9C, 0x01, + 0x70, 0x02, 0x71, 0x02, 0x9D, 0x01, 0x73, 0x02, + 0x74, 0x02, 0x9F, 0x01, 0x76, 0x02, 0x77, 0x02, + 0x78, 0x02, 0x79, 0x02, 0x7A, 0x02, 0x7B, 0x02, + 0x7C, 0x02, 0x64, 0x2C, 0x7E, 0x02, 0x7F, 0x02, + 0xA6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xA9, 0x01, + 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, + 0xAE, 0x01, 0x44, 0x02, 0xB1, 0x01, 0xB2, 0x01, + 0x45, 0x02, 0x8D, 0x02, 0x8E, 0x02, 0x8F, 0x02, + 0x90, 0x02, 0x91, 0x02, 0xB7, 0x01, 0x93, 0x02, + 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02, + 0x98, 0x02, 0x99, 0x02, 0x9A, 0x02, 0x9B, 0x02, + 0x9C, 0x02, 0x9D, 0x02, 0x9E, 0x02, 0x9F, 0x02, + 0xA0, 0x02, 0xA1, 0x02, 0xA2, 0x02, 0xA3, 0x02, + 0xA4, 0x02, 0xA5, 0x02, 0xA6, 0x02, 0xA7, 0x02, + 0xA8, 0x02, 0xA9, 0x02, 0xAA, 0x02, 0xAB, 0x02, + 0xAC, 0x02, 0xAD, 0x02, 0xAE, 0x02, 0xAF, 0x02, + 0xB0, 0x02, 0xB1, 0x02, 0xB2, 0x02, 0xB3, 0x02, + 0xB4, 0x02, 0xB5, 0x02, 0xB6, 0x02, 0xB7, 0x02, + 0xB8, 0x02, 0xB9, 0x02, 0xBA, 0x02, 0xBB, 0x02, + 0xBC, 0x02, 0xBD, 0x02, 0xBE, 0x02, 0xBF, 0x02, + 0xC0, 0x02, 0xC1, 0x02, 0xC2, 0x02, 0xC3, 0x02, + 0xC4, 0x02, 0xC5, 0x02, 0xC6, 0x02, 0xC7, 0x02, + 0xC8, 0x02, 0xC9, 0x02, 0xCA, 0x02, 0xCB, 0x02, + 0xCC, 0x02, 0xCD, 0x02, 0xCE, 0x02, 0xCF, 0x02, + 0xD0, 0x02, 0xD1, 0x02, 0xD2, 0x02, 0xD3, 0x02, + 0xD4, 0x02, 0xD5, 0x02, 0xD6, 0x02, 0xD7, 0x02, + 0xD8, 0x02, 0xD9, 0x02, 0xDA, 0x02, 0xDB, 0x02, + 0xDC, 0x02, 0xDD, 0x02, 0xDE, 0x02, 0xDF, 0x02, + 0xE0, 0x02, 0xE1, 0x02, 0xE2, 0x02, 0xE3, 0x02, + 0xE4, 0x02, 0xE5, 0x02, 0xE6, 0x02, 0xE7, 0x02, + 0xE8, 0x02, 0xE9, 0x02, 0xEA, 0x02, 0xEB, 0x02, + 0xEC, 0x02, 0xED, 0x02, 0xEE, 0x02, 0xEF, 0x02, + 0xF0, 0x02, 0xF1, 0x02, 0xF2, 0x02, 0xF3, 0x02, + 0xF4, 0x02, 0xF5, 0x02, 0xF6, 0x02, 0xF7, 0x02, + 0xF8, 0x02, 0xF9, 0x02, 0xFA, 0x02, 0xFB, 0x02, + 0xFC, 0x02, 0xFD, 0x02, 0xFE, 0x02, 0xFF, 0x02, + 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, + 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03, + 0x08, 0x03, 0x09, 0x03, 0x0A, 0x03, 0x0B, 0x03, + 0x0C, 0x03, 0x0D, 0x03, 0x0E, 0x03, 0x0F, 0x03, + 0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, + 0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03, + 0x18, 0x03, 0x19, 0x03, 0x1A, 0x03, 0x1B, 0x03, + 0x1C, 0x03, 0x1D, 0x03, 0x1E, 0x03, 0x1F, 0x03, + 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03, + 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, + 0x28, 0x03, 0x29, 0x03, 0x2A, 0x03, 0x2B, 0x03, + 0x2C, 0x03, 0x2D, 0x03, 0x2E, 0x03, 0x2F, 0x03, + 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, + 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, + 0x38, 0x03, 0x39, 0x03, 0x3A, 0x03, 0x3B, 0x03, + 0x3C, 0x03, 0x3D, 0x03, 0x3E, 0x03, 0x3F, 0x03, + 0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, + 0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03, + 0x48, 0x03, 0x49, 0x03, 0x4A, 0x03, 0x4B, 0x03, + 0x4C, 0x03, 0x4D, 0x03, 0x4E, 0x03, 0x4F, 0x03, + 0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, + 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03, + 0x58, 0x03, 0x59, 0x03, 0x5A, 0x03, 0x5B, 0x03, + 0x5C, 0x03, 0x5D, 0x03, 0x5E, 0x03, 0x5F, 0x03, + 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, + 0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, + 0x68, 0x03, 0x69, 0x03, 0x6A, 0x03, 0x6B, 0x03, + 0x6C, 0x03, 0x6D, 0x03, 0x6E, 0x03, 0x6F, 0x03, + 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, + 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, + 0x78, 0x03, 0x79, 0x03, 0x7A, 0x03, 0xFD, 0x03, + 0xFE, 0x03, 0xFF, 0x03, 0x7E, 0x03, 0x7F, 0x03, + 0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03, + 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03, + 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, 0x8B, 0x03, + 0x8C, 0x03, 0x8D, 0x03, 0x8E, 0x03, 0x8F, 0x03, + 0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, + 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, + 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, + 0xA0, 0x03, 0xA1, 0x03, 0xA2, 0x03, 0xA3, 0x03, + 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, + 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, + 0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, + 0xB0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, + 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, + 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, + 0xA0, 0x03, 0xA1, 0x03, 0xA3, 0x03, 0xA3, 0x03, + 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, + 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, + 0x8C, 0x03, 0x8E, 0x03, 0x8F, 0x03, 0xCF, 0x03, + 0xD0, 0x03, 0xD1, 0x03, 0xD2, 0x03, 0xD3, 0x03, + 0xD4, 0x03, 0xD5, 0x03, 0xD6, 0x03, 0xD7, 0x03, + 0xD8, 0x03, 0xD8, 0x03, 0xDA, 0x03, 0xDA, 0x03, + 0xDC, 0x03, 0xDC, 0x03, 0xDE, 0x03, 0xDE, 0x03, + 0xE0, 0x03, 0xE0, 0x03, 0xE2, 0x03, 0xE2, 0x03, + 0xE4, 0x03, 0xE4, 0x03, 0xE6, 0x03, 0xE6, 0x03, + 0xE8, 0x03, 0xE8, 0x03, 0xEA, 0x03, 0xEA, 0x03, + 0xEC, 0x03, 0xEC, 0x03, 0xEE, 0x03, 0xEE, 0x03, + 0xF0, 0x03, 0xF1, 0x03, 0xF9, 0x03, 0xF3, 0x03, + 0xF4, 0x03, 0xF5, 0x03, 0xF6, 0x03, 0xF7, 0x03, + 0xF7, 0x03, 0xF9, 0x03, 0xFA, 0x03, 0xFA, 0x03, + 0xFC, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, + 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, + 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, + 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, + 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, + 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, + 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, + 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, + 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, + 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, + 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, + 0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04, + 0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04, + 0x68, 0x04, 0x68, 0x04, 0x6A, 0x04, 0x6A, 0x04, + 0x6C, 0x04, 0x6C, 0x04, 0x6E, 0x04, 0x6E, 0x04, + 0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04, + 0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04, + 0x78, 0x04, 0x78, 0x04, 0x7A, 0x04, 0x7A, 0x04, + 0x7C, 0x04, 0x7C, 0x04, 0x7E, 0x04, 0x7E, 0x04, + 0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04, + 0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, + 0x88, 0x04, 0x89, 0x04, 0x8A, 0x04, 0x8A, 0x04, + 0x8C, 0x04, 0x8C, 0x04, 0x8E, 0x04, 0x8E, 0x04, + 0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04, + 0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04, + 0x98, 0x04, 0x98, 0x04, 0x9A, 0x04, 0x9A, 0x04, + 0x9C, 0x04, 0x9C, 0x04, 0x9E, 0x04, 0x9E, 0x04, + 0xA0, 0x04, 0xA0, 0x04, 0xA2, 0x04, 0xA2, 0x04, + 0xA4, 0x04, 0xA4, 0x04, 0xA6, 0x04, 0xA6, 0x04, + 0xA8, 0x04, 0xA8, 0x04, 0xAA, 0x04, 0xAA, 0x04, + 0xAC, 0x04, 0xAC, 0x04, 0xAE, 0x04, 0xAE, 0x04, + 0xB0, 0x04, 0xB0, 0x04, 0xB2, 0x04, 0xB2, 0x04, + 0xB4, 0x04, 0xB4, 0x04, 0xB6, 0x04, 0xB6, 0x04, + 0xB8, 0x04, 0xB8, 0x04, 0xBA, 0x04, 0xBA, 0x04, + 0xBC, 0x04, 0xBC, 0x04, 0xBE, 0x04, 0xBE, 0x04, + 0xC0, 0x04, 0xC1, 0x04, 0xC1, 0x04, 0xC3, 0x04, + 0xC3, 0x04, 0xC5, 0x04, 0xC5, 0x04, 0xC7, 0x04, + 0xC7, 0x04, 0xC9, 0x04, 0xC9, 0x04, 0xCB, 0x04, + 0xCB, 0x04, 0xCD, 0x04, 0xCD, 0x04, 0xC0, 0x04, + 0xD0, 0x04, 0xD0, 0x04, 0xD2, 0x04, 0xD2, 0x04, + 0xD4, 0x04, 0xD4, 0x04, 0xD6, 0x04, 0xD6, 0x04, + 0xD8, 0x04, 0xD8, 0x04, 0xDA, 0x04, 0xDA, 0x04, + 0xDC, 0x04, 0xDC, 0x04, 0xDE, 0x04, 0xDE, 0x04, + 0xE0, 0x04, 0xE0, 0x04, 0xE2, 0x04, 0xE2, 0x04, + 0xE4, 0x04, 0xE4, 0x04, 0xE6, 0x04, 0xE6, 0x04, + 0xE8, 0x04, 0xE8, 0x04, 0xEA, 0x04, 0xEA, 0x04, + 0xEC, 0x04, 0xEC, 0x04, 0xEE, 0x04, 0xEE, 0x04, + 0xF0, 0x04, 0xF0, 0x04, 0xF2, 0x04, 0xF2, 0x04, + 0xF4, 0x04, 0xF4, 0x04, 0xF6, 0x04, 0xF6, 0x04, + 0xF8, 0x04, 0xF8, 0x04, 0xFA, 0x04, 0xFA, 0x04, + 0xFC, 0x04, 0xFC, 0x04, 0xFE, 0x04, 0xFE, 0x04, + 0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05, + 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05, + 0x08, 0x05, 0x08, 0x05, 0x0A, 0x05, 0x0A, 0x05, + 0x0C, 0x05, 0x0C, 0x05, 0x0E, 0x05, 0x0E, 0x05, + 0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05, + 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, + 0x18, 0x05, 0x19, 0x05, 0x1A, 0x05, 0x1B, 0x05, + 0x1C, 0x05, 0x1D, 0x05, 0x1E, 0x05, 0x1F, 0x05, + 0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, + 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05, + 0x28, 0x05, 0x29, 0x05, 0x2A, 0x05, 0x2B, 0x05, + 0x2C, 0x05, 0x2D, 0x05, 0x2E, 0x05, 0x2F, 0x05, + 0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, + 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, + 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, + 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, + 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, + 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05, + 0x58, 0x05, 0x59, 0x05, 0x5A, 0x05, 0x5B, 0x05, + 0x5C, 0x05, 0x5D, 0x05, 0x5E, 0x05, 0x5F, 0x05, + 0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, + 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, + 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, + 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, + 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, + 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xFF, 0xFF, + 0xF6, 0x17, 0x63, 0x2C, 0x7E, 0x1D, 0x7F, 0x1D, + 0x80, 0x1D, 0x81, 0x1D, 0x82, 0x1D, 0x83, 0x1D, + 0x84, 0x1D, 0x85, 0x1D, 0x86, 0x1D, 0x87, 0x1D, + 0x88, 0x1D, 0x89, 0x1D, 0x8A, 0x1D, 0x8B, 0x1D, + 0x8C, 0x1D, 0x8D, 0x1D, 0x8E, 0x1D, 0x8F, 0x1D, + 0x90, 0x1D, 0x91, 0x1D, 0x92, 0x1D, 0x93, 0x1D, + 0x94, 0x1D, 0x95, 0x1D, 0x96, 0x1D, 0x97, 0x1D, + 0x98, 0x1D, 0x99, 0x1D, 0x9A, 0x1D, 0x9B, 0x1D, + 0x9C, 0x1D, 0x9D, 0x1D, 0x9E, 0x1D, 0x9F, 0x1D, + 0xA0, 0x1D, 0xA1, 0x1D, 0xA2, 0x1D, 0xA3, 0x1D, + 0xA4, 0x1D, 0xA5, 0x1D, 0xA6, 0x1D, 0xA7, 0x1D, + 0xA8, 0x1D, 0xA9, 0x1D, 0xAA, 0x1D, 0xAB, 0x1D, + 0xAC, 0x1D, 0xAD, 0x1D, 0xAE, 0x1D, 0xAF, 0x1D, + 0xB0, 0x1D, 0xB1, 0x1D, 0xB2, 0x1D, 0xB3, 0x1D, + 0xB4, 0x1D, 0xB5, 0x1D, 0xB6, 0x1D, 0xB7, 0x1D, + 0xB8, 0x1D, 0xB9, 0x1D, 0xBA, 0x1D, 0xBB, 0x1D, + 0xBC, 0x1D, 0xBD, 0x1D, 0xBE, 0x1D, 0xBF, 0x1D, + 0xC0, 0x1D, 0xC1, 0x1D, 0xC2, 0x1D, 0xC3, 0x1D, + 0xC4, 0x1D, 0xC5, 0x1D, 0xC6, 0x1D, 0xC7, 0x1D, + 0xC8, 0x1D, 0xC9, 0x1D, 0xCA, 0x1D, 0xCB, 0x1D, + 0xCC, 0x1D, 0xCD, 0x1D, 0xCE, 0x1D, 0xCF, 0x1D, + 0xD0, 0x1D, 0xD1, 0x1D, 0xD2, 0x1D, 0xD3, 0x1D, + 0xD4, 0x1D, 0xD5, 0x1D, 0xD6, 0x1D, 0xD7, 0x1D, + 0xD8, 0x1D, 0xD9, 0x1D, 0xDA, 0x1D, 0xDB, 0x1D, + 0xDC, 0x1D, 0xDD, 0x1D, 0xDE, 0x1D, 0xDF, 0x1D, + 0xE0, 0x1D, 0xE1, 0x1D, 0xE2, 0x1D, 0xE3, 0x1D, + 0xE4, 0x1D, 0xE5, 0x1D, 0xE6, 0x1D, 0xE7, 0x1D, + 0xE8, 0x1D, 0xE9, 0x1D, 0xEA, 0x1D, 0xEB, 0x1D, + 0xEC, 0x1D, 0xED, 0x1D, 0xEE, 0x1D, 0xEF, 0x1D, + 0xF0, 0x1D, 0xF1, 0x1D, 0xF2, 0x1D, 0xF3, 0x1D, + 0xF4, 0x1D, 0xF5, 0x1D, 0xF6, 0x1D, 0xF7, 0x1D, + 0xF8, 0x1D, 0xF9, 0x1D, 0xFA, 0x1D, 0xFB, 0x1D, + 0xFC, 0x1D, 0xFD, 0x1D, 0xFE, 0x1D, 0xFF, 0x1D, + 0x00, 0x1E, 0x00, 0x1E, 0x02, 0x1E, 0x02, 0x1E, + 0x04, 0x1E, 0x04, 0x1E, 0x06, 0x1E, 0x06, 0x1E, + 0x08, 0x1E, 0x08, 0x1E, 0x0A, 0x1E, 0x0A, 0x1E, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0E, 0x1E, 0x0E, 0x1E, + 0x10, 0x1E, 0x10, 0x1E, 0x12, 0x1E, 0x12, 0x1E, + 0x14, 0x1E, 0x14, 0x1E, 0x16, 0x1E, 0x16, 0x1E, + 0x18, 0x1E, 0x18, 0x1E, 0x1A, 0x1E, 0x1A, 0x1E, + 0x1C, 0x1E, 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x20, 0x1E, 0x20, 0x1E, 0x22, 0x1E, 0x22, 0x1E, + 0x24, 0x1E, 0x24, 0x1E, 0x26, 0x1E, 0x26, 0x1E, + 0x28, 0x1E, 0x28, 0x1E, 0x2A, 0x1E, 0x2A, 0x1E, + 0x2C, 0x1E, 0x2C, 0x1E, 0x2E, 0x1E, 0x2E, 0x1E, + 0x30, 0x1E, 0x30, 0x1E, 0x32, 0x1E, 0x32, 0x1E, + 0x34, 0x1E, 0x34, 0x1E, 0x36, 0x1E, 0x36, 0x1E, + 0x38, 0x1E, 0x38, 0x1E, 0x3A, 0x1E, 0x3A, 0x1E, + 0x3C, 0x1E, 0x3C, 0x1E, 0x3E, 0x1E, 0x3E, 0x1E, + 0x40, 0x1E, 0x40, 0x1E, 0x42, 0x1E, 0x42, 0x1E, + 0x44, 0x1E, 0x44, 0x1E, 0x46, 0x1E, 0x46, 0x1E, + 0x48, 0x1E, 0x48, 0x1E, 0x4A, 0x1E, 0x4A, 0x1E, + 0x4C, 0x1E, 0x4C, 0x1E, 0x4E, 0x1E, 0x4E, 0x1E, + 0x50, 0x1E, 0x50, 0x1E, 0x52, 0x1E, 0x52, 0x1E, + 0x54, 0x1E, 0x54, 0x1E, 0x56, 0x1E, 0x56, 0x1E, + 0x58, 0x1E, 0x58, 0x1E, 0x5A, 0x1E, 0x5A, 0x1E, + 0x5C, 0x1E, 0x5C, 0x1E, 0x5E, 0x1E, 0x5E, 0x1E, + 0x60, 0x1E, 0x60, 0x1E, 0x62, 0x1E, 0x62, 0x1E, + 0x64, 0x1E, 0x64, 0x1E, 0x66, 0x1E, 0x66, 0x1E, + 0x68, 0x1E, 0x68, 0x1E, 0x6A, 0x1E, 0x6A, 0x1E, + 0x6C, 0x1E, 0x6C, 0x1E, 0x6E, 0x1E, 0x6E, 0x1E, + 0x70, 0x1E, 0x70, 0x1E, 0x72, 0x1E, 0x72, 0x1E, + 0x74, 0x1E, 0x74, 0x1E, 0x76, 0x1E, 0x76, 0x1E, + 0x78, 0x1E, 0x78, 0x1E, 0x7A, 0x1E, 0x7A, 0x1E, + 0x7C, 0x1E, 0x7C, 0x1E, 0x7E, 0x1E, 0x7E, 0x1E, + 0x80, 0x1E, 0x80, 0x1E, 0x82, 0x1E, 0x82, 0x1E, + 0x84, 0x1E, 0x84, 0x1E, 0x86, 0x1E, 0x86, 0x1E, + 0x88, 0x1E, 0x88, 0x1E, 0x8A, 0x1E, 0x8A, 0x1E, + 0x8C, 0x1E, 0x8C, 0x1E, 0x8E, 0x1E, 0x8E, 0x1E, + 0x90, 0x1E, 0x90, 0x1E, 0x92, 0x1E, 0x92, 0x1E, + 0x94, 0x1E, 0x94, 0x1E, 0x96, 0x1E, 0x97, 0x1E, + 0x98, 0x1E, 0x99, 0x1E, 0x9A, 0x1E, 0x9B, 0x1E, + 0x9C, 0x1E, 0x9D, 0x1E, 0x9E, 0x1E, 0x9F, 0x1E, + 0xA0, 0x1E, 0xA0, 0x1E, 0xA2, 0x1E, 0xA2, 0x1E, + 0xA4, 0x1E, 0xA4, 0x1E, 0xA6, 0x1E, 0xA6, 0x1E, + 0xA8, 0x1E, 0xA8, 0x1E, 0xAA, 0x1E, 0xAA, 0x1E, + 0xAC, 0x1E, 0xAC, 0x1E, 0xAE, 0x1E, 0xAE, 0x1E, + 0xB0, 0x1E, 0xB0, 0x1E, 0xB2, 0x1E, 0xB2, 0x1E, + 0xB4, 0x1E, 0xB4, 0x1E, 0xB6, 0x1E, 0xB6, 0x1E, + 0xB8, 0x1E, 0xB8, 0x1E, 0xBA, 0x1E, 0xBA, 0x1E, + 0xBC, 0x1E, 0xBC, 0x1E, 0xBE, 0x1E, 0xBE, 0x1E, + 0xC0, 0x1E, 0xC0, 0x1E, 0xC2, 0x1E, 0xC2, 0x1E, + 0xC4, 0x1E, 0xC4, 0x1E, 0xC6, 0x1E, 0xC6, 0x1E, + 0xC8, 0x1E, 0xC8, 0x1E, 0xCA, 0x1E, 0xCA, 0x1E, + 0xCC, 0x1E, 0xCC, 0x1E, 0xCE, 0x1E, 0xCE, 0x1E, + 0xD0, 0x1E, 0xD0, 0x1E, 0xD2, 0x1E, 0xD2, 0x1E, + 0xD4, 0x1E, 0xD4, 0x1E, 0xD6, 0x1E, 0xD6, 0x1E, + 0xD8, 0x1E, 0xD8, 0x1E, 0xDA, 0x1E, 0xDA, 0x1E, + 0xDC, 0x1E, 0xDC, 0x1E, 0xDE, 0x1E, 0xDE, 0x1E, + 0xE0, 0x1E, 0xE0, 0x1E, 0xE2, 0x1E, 0xE2, 0x1E, + 0xE4, 0x1E, 0xE4, 0x1E, 0xE6, 0x1E, 0xE6, 0x1E, + 0xE8, 0x1E, 0xE8, 0x1E, 0xEA, 0x1E, 0xEA, 0x1E, + 0xEC, 0x1E, 0xEC, 0x1E, 0xEE, 0x1E, 0xEE, 0x1E, + 0xF0, 0x1E, 0xF0, 0x1E, 0xF2, 0x1E, 0xF2, 0x1E, + 0xF4, 0x1E, 0xF4, 0x1E, 0xF6, 0x1E, 0xF6, 0x1E, + 0xF8, 0x1E, 0xF8, 0x1E, 0xFA, 0x1E, 0xFB, 0x1E, + 0xFC, 0x1E, 0xFD, 0x1E, 0xFE, 0x1E, 0xFF, 0x1E, + 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, + 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, + 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, + 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, + 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, + 0x1C, 0x1F, 0x1D, 0x1F, 0x16, 0x1F, 0x17, 0x1F, + 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, + 0x1C, 0x1F, 0x1D, 0x1F, 0x1E, 0x1F, 0x1F, 0x1F, + 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, + 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, + 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, + 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, + 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, + 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, + 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, + 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, + 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, + 0x4C, 0x1F, 0x4D, 0x1F, 0x46, 0x1F, 0x47, 0x1F, + 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, + 0x4C, 0x1F, 0x4D, 0x1F, 0x4E, 0x1F, 0x4F, 0x1F, + 0x50, 0x1F, 0x59, 0x1F, 0x52, 0x1F, 0x5B, 0x1F, + 0x54, 0x1F, 0x5D, 0x1F, 0x56, 0x1F, 0x5F, 0x1F, + 0x58, 0x1F, 0x59, 0x1F, 0x5A, 0x1F, 0x5B, 0x1F, + 0x5C, 0x1F, 0x5D, 0x1F, 0x5E, 0x1F, 0x5F, 0x1F, + 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, + 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, + 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, + 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, + 0xBA, 0x1F, 0xBB, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F, + 0xCA, 0x1F, 0xCB, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, + 0xF8, 0x1F, 0xF9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, + 0xFA, 0x1F, 0xFB, 0x1F, 0x7E, 0x1F, 0x7F, 0x1F, + 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, + 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, + 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, + 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, + 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, + 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, + 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, + 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, + 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, + 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, + 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, + 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, + 0xB8, 0x1F, 0xB9, 0x1F, 0xB2, 0x1F, 0xBC, 0x1F, + 0xB4, 0x1F, 0xB5, 0x1F, 0xB6, 0x1F, 0xB7, 0x1F, + 0xB8, 0x1F, 0xB9, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F, + 0xBC, 0x1F, 0xBD, 0x1F, 0xBE, 0x1F, 0xBF, 0x1F, + 0xC0, 0x1F, 0xC1, 0x1F, 0xC2, 0x1F, 0xC3, 0x1F, + 0xC4, 0x1F, 0xC5, 0x1F, 0xC6, 0x1F, 0xC7, 0x1F, + 0xC8, 0x1F, 0xC9, 0x1F, 0xCA, 0x1F, 0xCB, 0x1F, + 0xC3, 0x1F, 0xCD, 0x1F, 0xCE, 0x1F, 0xCF, 0x1F, + 0xD8, 0x1F, 0xD9, 0x1F, 0xD2, 0x1F, 0xD3, 0x1F, + 0xD4, 0x1F, 0xD5, 0x1F, 0xD6, 0x1F, 0xD7, 0x1F, + 0xD8, 0x1F, 0xD9, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, + 0xDC, 0x1F, 0xDD, 0x1F, 0xDE, 0x1F, 0xDF, 0x1F, + 0xE8, 0x1F, 0xE9, 0x1F, 0xE2, 0x1F, 0xE3, 0x1F, + 0xE4, 0x1F, 0xEC, 0x1F, 0xE6, 0x1F, 0xE7, 0x1F, + 0xE8, 0x1F, 0xE9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, + 0xEC, 0x1F, 0xED, 0x1F, 0xEE, 0x1F, 0xEF, 0x1F, + 0xF0, 0x1F, 0xF1, 0x1F, 0xF2, 0x1F, 0xF3, 0x1F, + 0xF4, 0x1F, 0xF5, 0x1F, 0xF6, 0x1F, 0xF7, 0x1F, + 0xF8, 0x1F, 0xF9, 0x1F, 0xFA, 0x1F, 0xFB, 0x1F, + 0xF3, 0x1F, 0xFD, 0x1F, 0xFE, 0x1F, 0xFF, 0x1F, + 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20, + 0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, + 0x08, 0x20, 0x09, 0x20, 0x0A, 0x20, 0x0B, 0x20, + 0x0C, 0x20, 0x0D, 0x20, 0x0E, 0x20, 0x0F, 0x20, + 0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20, + 0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20, + 0x18, 0x20, 0x19, 0x20, 0x1A, 0x20, 0x1B, 0x20, + 0x1C, 0x20, 0x1D, 0x20, 0x1E, 0x20, 0x1F, 0x20, + 0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20, + 0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20, + 0x28, 0x20, 0x29, 0x20, 0x2A, 0x20, 0x2B, 0x20, + 0x2C, 0x20, 0x2D, 0x20, 0x2E, 0x20, 0x2F, 0x20, + 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20, + 0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, + 0x38, 0x20, 0x39, 0x20, 0x3A, 0x20, 0x3B, 0x20, + 0x3C, 0x20, 0x3D, 0x20, 0x3E, 0x20, 0x3F, 0x20, + 0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, + 0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, + 0x48, 0x20, 0x49, 0x20, 0x4A, 0x20, 0x4B, 0x20, + 0x4C, 0x20, 0x4D, 0x20, 0x4E, 0x20, 0x4F, 0x20, + 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, + 0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, + 0x58, 0x20, 0x59, 0x20, 0x5A, 0x20, 0x5B, 0x20, + 0x5C, 0x20, 0x5D, 0x20, 0x5E, 0x20, 0x5F, 0x20, + 0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20, + 0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20, + 0x68, 0x20, 0x69, 0x20, 0x6A, 0x20, 0x6B, 0x20, + 0x6C, 0x20, 0x6D, 0x20, 0x6E, 0x20, 0x6F, 0x20, + 0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20, + 0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20, + 0x78, 0x20, 0x79, 0x20, 0x7A, 0x20, 0x7B, 0x20, + 0x7C, 0x20, 0x7D, 0x20, 0x7E, 0x20, 0x7F, 0x20, + 0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20, + 0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20, + 0x88, 0x20, 0x89, 0x20, 0x8A, 0x20, 0x8B, 0x20, + 0x8C, 0x20, 0x8D, 0x20, 0x8E, 0x20, 0x8F, 0x20, + 0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20, + 0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20, + 0x98, 0x20, 0x99, 0x20, 0x9A, 0x20, 0x9B, 0x20, + 0x9C, 0x20, 0x9D, 0x20, 0x9E, 0x20, 0x9F, 0x20, + 0xA0, 0x20, 0xA1, 0x20, 0xA2, 0x20, 0xA3, 0x20, + 0xA4, 0x20, 0xA5, 0x20, 0xA6, 0x20, 0xA7, 0x20, + 0xA8, 0x20, 0xA9, 0x20, 0xAA, 0x20, 0xAB, 0x20, + 0xAC, 0x20, 0xAD, 0x20, 0xAE, 0x20, 0xAF, 0x20, + 0xB0, 0x20, 0xB1, 0x20, 0xB2, 0x20, 0xB3, 0x20, + 0xB4, 0x20, 0xB5, 0x20, 0xB6, 0x20, 0xB7, 0x20, + 0xB8, 0x20, 0xB9, 0x20, 0xBA, 0x20, 0xBB, 0x20, + 0xBC, 0x20, 0xBD, 0x20, 0xBE, 0x20, 0xBF, 0x20, + 0xC0, 0x20, 0xC1, 0x20, 0xC2, 0x20, 0xC3, 0x20, + 0xC4, 0x20, 0xC5, 0x20, 0xC6, 0x20, 0xC7, 0x20, + 0xC8, 0x20, 0xC9, 0x20, 0xCA, 0x20, 0xCB, 0x20, + 0xCC, 0x20, 0xCD, 0x20, 0xCE, 0x20, 0xCF, 0x20, + 0xD0, 0x20, 0xD1, 0x20, 0xD2, 0x20, 0xD3, 0x20, + 0xD4, 0x20, 0xD5, 0x20, 0xD6, 0x20, 0xD7, 0x20, + 0xD8, 0x20, 0xD9, 0x20, 0xDA, 0x20, 0xDB, 0x20, + 0xDC, 0x20, 0xDD, 0x20, 0xDE, 0x20, 0xDF, 0x20, + 0xE0, 0x20, 0xE1, 0x20, 0xE2, 0x20, 0xE3, 0x20, + 0xE4, 0x20, 0xE5, 0x20, 0xE6, 0x20, 0xE7, 0x20, + 0xE8, 0x20, 0xE9, 0x20, 0xEA, 0x20, 0xEB, 0x20, + 0xEC, 0x20, 0xED, 0x20, 0xEE, 0x20, 0xEF, 0x20, + 0xF0, 0x20, 0xF1, 0x20, 0xF2, 0x20, 0xF3, 0x20, + 0xF4, 0x20, 0xF5, 0x20, 0xF6, 0x20, 0xF7, 0x20, + 0xF8, 0x20, 0xF9, 0x20, 0xFA, 0x20, 0xFB, 0x20, + 0xFC, 0x20, 0xFD, 0x20, 0xFE, 0x20, 0xFF, 0x20, + 0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21, + 0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21, + 0x08, 0x21, 0x09, 0x21, 0x0A, 0x21, 0x0B, 0x21, + 0x0C, 0x21, 0x0D, 0x21, 0x0E, 0x21, 0x0F, 0x21, + 0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21, + 0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21, + 0x18, 0x21, 0x19, 0x21, 0x1A, 0x21, 0x1B, 0x21, + 0x1C, 0x21, 0x1D, 0x21, 0x1E, 0x21, 0x1F, 0x21, + 0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21, + 0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21, + 0x28, 0x21, 0x29, 0x21, 0x2A, 0x21, 0x2B, 0x21, + 0x2C, 0x21, 0x2D, 0x21, 0x2E, 0x21, 0x2F, 0x21, + 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21, + 0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21, + 0x38, 0x21, 0x39, 0x21, 0x3A, 0x21, 0x3B, 0x21, + 0x3C, 0x21, 0x3D, 0x21, 0x3E, 0x21, 0x3F, 0x21, + 0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21, + 0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21, + 0x48, 0x21, 0x49, 0x21, 0x4A, 0x21, 0x4B, 0x21, + 0x4C, 0x21, 0x4D, 0x21, 0x32, 0x21, 0x4F, 0x21, + 0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21, + 0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21, + 0x58, 0x21, 0x59, 0x21, 0x5A, 0x21, 0x5B, 0x21, + 0x5C, 0x21, 0x5D, 0x21, 0x5E, 0x21, 0x5F, 0x21, + 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, + 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, + 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, + 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, + 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, + 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, + 0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21, + 0x83, 0x21, 0xFF, 0xFF, 0x4B, 0x03, 0xB6, 0x24, + 0xB7, 0x24, 0xB8, 0x24, 0xB9, 0x24, 0xBA, 0x24, + 0xBB, 0x24, 0xBC, 0x24, 0xBD, 0x24, 0xBE, 0x24, + 0xBF, 0x24, 0xC0, 0x24, 0xC1, 0x24, 0xC2, 0x24, + 0xC3, 0x24, 0xC4, 0x24, 0xC5, 0x24, 0xC6, 0x24, + 0xC7, 0x24, 0xC8, 0x24, 0xC9, 0x24, 0xCA, 0x24, + 0xCB, 0x24, 0xCC, 0x24, 0xCD, 0x24, 0xCE, 0x24, + 0xCF, 0x24, 0xFF, 0xFF, 0x46, 0x07, 0x00, 0x2C, + 0x01, 0x2C, 0x02, 0x2C, 0x03, 0x2C, 0x04, 0x2C, + 0x05, 0x2C, 0x06, 0x2C, 0x07, 0x2C, 0x08, 0x2C, + 0x09, 0x2C, 0x0A, 0x2C, 0x0B, 0x2C, 0x0C, 0x2C, + 0x0D, 0x2C, 0x0E, 0x2C, 0x0F, 0x2C, 0x10, 0x2C, + 0x11, 0x2C, 0x12, 0x2C, 0x13, 0x2C, 0x14, 0x2C, + 0x15, 0x2C, 0x16, 0x2C, 0x17, 0x2C, 0x18, 0x2C, + 0x19, 0x2C, 0x1A, 0x2C, 0x1B, 0x2C, 0x1C, 0x2C, + 0x1D, 0x2C, 0x1E, 0x2C, 0x1F, 0x2C, 0x20, 0x2C, + 0x21, 0x2C, 0x22, 0x2C, 0x23, 0x2C, 0x24, 0x2C, + 0x25, 0x2C, 0x26, 0x2C, 0x27, 0x2C, 0x28, 0x2C, + 0x29, 0x2C, 0x2A, 0x2C, 0x2B, 0x2C, 0x2C, 0x2C, + 0x2D, 0x2C, 0x2E, 0x2C, 0x5F, 0x2C, 0x60, 0x2C, + 0x60, 0x2C, 0x62, 0x2C, 0x63, 0x2C, 0x64, 0x2C, + 0x65, 0x2C, 0x66, 0x2C, 0x67, 0x2C, 0x67, 0x2C, + 0x69, 0x2C, 0x69, 0x2C, 0x6B, 0x2C, 0x6B, 0x2C, + 0x6D, 0x2C, 0x6E, 0x2C, 0x6F, 0x2C, 0x70, 0x2C, + 0x71, 0x2C, 0x72, 0x2C, 0x73, 0x2C, 0x74, 0x2C, + 0x75, 0x2C, 0x75, 0x2C, 0x77, 0x2C, 0x78, 0x2C, + 0x79, 0x2C, 0x7A, 0x2C, 0x7B, 0x2C, 0x7C, 0x2C, + 0x7D, 0x2C, 0x7E, 0x2C, 0x7F, 0x2C, 0x80, 0x2C, + 0x80, 0x2C, 0x82, 0x2C, 0x82, 0x2C, 0x84, 0x2C, + 0x84, 0x2C, 0x86, 0x2C, 0x86, 0x2C, 0x88, 0x2C, + 0x88, 0x2C, 0x8A, 0x2C, 0x8A, 0x2C, 0x8C, 0x2C, + 0x8C, 0x2C, 0x8E, 0x2C, 0x8E, 0x2C, 0x90, 0x2C, + 0x90, 0x2C, 0x92, 0x2C, 0x92, 0x2C, 0x94, 0x2C, + 0x94, 0x2C, 0x96, 0x2C, 0x96, 0x2C, 0x98, 0x2C, + 0x98, 0x2C, 0x9A, 0x2C, 0x9A, 0x2C, 0x9C, 0x2C, + 0x9C, 0x2C, 0x9E, 0x2C, 0x9E, 0x2C, 0xA0, 0x2C, + 0xA0, 0x2C, 0xA2, 0x2C, 0xA2, 0x2C, 0xA4, 0x2C, + 0xA4, 0x2C, 0xA6, 0x2C, 0xA6, 0x2C, 0xA8, 0x2C, + 0xA8, 0x2C, 0xAA, 0x2C, 0xAA, 0x2C, 0xAC, 0x2C, + 0xAC, 0x2C, 0xAE, 0x2C, 0xAE, 0x2C, 0xB0, 0x2C, + 0xB0, 0x2C, 0xB2, 0x2C, 0xB2, 0x2C, 0xB4, 0x2C, + 0xB4, 0x2C, 0xB6, 0x2C, 0xB6, 0x2C, 0xB8, 0x2C, + 0xB8, 0x2C, 0xBA, 0x2C, 0xBA, 0x2C, 0xBC, 0x2C, + 0xBC, 0x2C, 0xBE, 0x2C, 0xBE, 0x2C, 0xC0, 0x2C, + 0xC0, 0x2C, 0xC2, 0x2C, 0xC2, 0x2C, 0xC4, 0x2C, + 0xC4, 0x2C, 0xC6, 0x2C, 0xC6, 0x2C, 0xC8, 0x2C, + 0xC8, 0x2C, 0xCA, 0x2C, 0xCA, 0x2C, 0xCC, 0x2C, + 0xCC, 0x2C, 0xCE, 0x2C, 0xCE, 0x2C, 0xD0, 0x2C, + 0xD0, 0x2C, 0xD2, 0x2C, 0xD2, 0x2C, 0xD4, 0x2C, + 0xD4, 0x2C, 0xD6, 0x2C, 0xD6, 0x2C, 0xD8, 0x2C, + 0xD8, 0x2C, 0xDA, 0x2C, 0xDA, 0x2C, 0xDC, 0x2C, + 0xDC, 0x2C, 0xDE, 0x2C, 0xDE, 0x2C, 0xE0, 0x2C, + 0xE0, 0x2C, 0xE2, 0x2C, 0xE2, 0x2C, 0xE4, 0x2C, + 0xE5, 0x2C, 0xE6, 0x2C, 0xE7, 0x2C, 0xE8, 0x2C, + 0xE9, 0x2C, 0xEA, 0x2C, 0xEB, 0x2C, 0xEC, 0x2C, + 0xED, 0x2C, 0xEE, 0x2C, 0xEF, 0x2C, 0xF0, 0x2C, + 0xF1, 0x2C, 0xF2, 0x2C, 0xF3, 0x2C, 0xF4, 0x2C, + 0xF5, 0x2C, 0xF6, 0x2C, 0xF7, 0x2C, 0xF8, 0x2C, + 0xF9, 0x2C, 0xFA, 0x2C, 0xFB, 0x2C, 0xFC, 0x2C, + 0xFD, 0x2C, 0xFE, 0x2C, 0xFF, 0x2C, 0xA0, 0x10, + 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, + 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10, + 0xA9, 0x10, 0xAA, 0x10, 0xAB, 0x10, 0xAC, 0x10, + 0xAD, 0x10, 0xAE, 0x10, 0xAF, 0x10, 0xB0, 0x10, + 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, + 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10, + 0xB9, 0x10, 0xBA, 0x10, 0xBB, 0x10, 0xBC, 0x10, + 0xBD, 0x10, 0xBE, 0x10, 0xBF, 0x10, 0xC0, 0x10, + 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, + 0xC5, 0x10, 0xFF, 0xFF, 0x1B, 0xD2, 0x21, 0xFF, + 0x22, 0xFF, 0x23, 0xFF, 0x24, 0xFF, 0x25, 0xFF, + 0x26, 0xFF, 0x27, 0xFF, 0x28, 0xFF, 0x29, 0xFF, + 0x2A, 0xFF, 0x2B, 0xFF, 0x2C, 0xFF, 0x2D, 0xFF, + 0x2E, 0xFF, 0x2F, 0xFF, 0x30, 0xFF, 0x31, 0xFF, + 0x32, 0xFF, 0x33, 0xFF, 0x34, 0xFF, 0x35, 0xFF, + 0x36, 0xFF, 0x37, 0xFF, 0x38, 0xFF, 0x39, 0xFF, + 0x3A, 0xFF, 0x5B, 0xFF, 0x5C, 0xFF, 0x5D, 0xFF, + 0x5E, 0xFF, 0x5F, 0xFF, 0x60, 0xFF, 0x61, 0xFF, + 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF, + 0x66, 0xFF, 0x67, 0xFF, 0x68, 0xFF, 0x69, 0xFF, + 0x6A, 0xFF, 0x6B, 0xFF, 0x6C, 0xFF, 0x6D, 0xFF, + 0x6E, 0xFF, 0x6F, 0xFF, 0x70, 0xFF, 0x71, 0xFF, + 0x72, 0xFF, 0x73, 0xFF, 0x74, 0xFF, 0x75, 0xFF, + 0x76, 0xFF, 0x77, 0xFF, 0x78, 0xFF, 0x79, 0xFF, + 0x7A, 0xFF, 0x7B, 0xFF, 0x7C, 0xFF, 0x7D, 0xFF, + 0x7E, 0xFF, 0x7F, 0xFF, 0x80, 0xFF, 0x81, 0xFF, + 0x82, 0xFF, 0x83, 0xFF, 0x84, 0xFF, 0x85, 0xFF, + 0x86, 0xFF, 0x87, 0xFF, 0x88, 0xFF, 0x89, 0xFF, + 0x8A, 0xFF, 0x8B, 0xFF, 0x8C, 0xFF, 0x8D, 0xFF, + 0x8E, 0xFF, 0x8F, 0xFF, 0x90, 0xFF, 0x91, 0xFF, + 0x92, 0xFF, 0x93, 0xFF, 0x94, 0xFF, 0x95, 0xFF, + 0x96, 0xFF, 0x97, 0xFF, 0x98, 0xFF, 0x99, 0xFF, + 0x9A, 0xFF, 0x9B, 0xFF, 0x9C, 0xFF, 0x9D, 0xFF, + 0x9E, 0xFF, 0x9F, 0xFF, 0xA0, 0xFF, 0xA1, 0xFF, + 0xA2, 0xFF, 0xA3, 0xFF, 0xA4, 0xFF, 0xA5, 0xFF, + 0xA6, 0xFF, 0xA7, 0xFF, 0xA8, 0xFF, 0xA9, 0xFF, + 0xAA, 0xFF, 0xAB, 0xFF, 0xAC, 0xFF, 0xAD, 0xFF, + 0xAE, 0xFF, 0xAF, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF, + 0xB2, 0xFF, 0xB3, 0xFF, 0xB4, 0xFF, 0xB5, 0xFF, + 0xB6, 0xFF, 0xB7, 0xFF, 0xB8, 0xFF, 0xB9, 0xFF, + 0xBA, 0xFF, 0xBB, 0xFF, 0xBC, 0xFF, 0xBD, 0xFF, + 0xBE, 0xFF, 0xBF, 0xFF, 0xC0, 0xFF, 0xC1, 0xFF, + 0xC2, 0xFF, 0xC3, 0xFF, 0xC4, 0xFF, 0xC5, 0xFF, + 0xC6, 0xFF, 0xC7, 0xFF, 0xC8, 0xFF, 0xC9, 0xFF, + 0xCA, 0xFF, 0xCB, 0xFF, 0xCC, 0xFF, 0xCD, 0xFF, + 0xCE, 0xFF, 0xCF, 0xFF, 0xD0, 0xFF, 0xD1, 0xFF, + 0xD2, 0xFF, 0xD3, 0xFF, 0xD4, 0xFF, 0xD5, 0xFF, + 0xD6, 0xFF, 0xD7, 0xFF, 0xD8, 0xFF, 0xD9, 0xFF, + 0xDA, 0xFF, 0xDB, 0xFF, 0xDC, 0xFF, 0xDD, 0xFF, + 0xDE, 0xFF, 0xDF, 0xFF, 0xE0, 0xFF, 0xE1, 0xFF, + 0xE2, 0xFF, 0xE3, 0xFF, 0xE4, 0xFF, 0xE5, 0xFF, + 0xE6, 0xFF, 0xE7, 0xFF, 0xE8, 0xFF, 0xE9, 0xFF, + 0xEA, 0xFF, 0xEB, 0xFF, 0xEC, 0xFF, 0xED, 0xFF, + 0xEE, 0xFF, 0xEF, 0xFF, 0xF0, 0xFF, 0xF1, 0xFF, + 0xF2, 0xFF, 0xF3, 0xFF, 0xF4, 0xFF, 0xF5, 0xFF, + 0xF6, 0xFF, 0xF7, 0xFF, 0xF8, 0xFF, 0xF9, 0xFF, + 0xFA, 0xFF, 0xFB, 0xFF, 0xFC, 0xFF, 0xFD, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFF +}; diff --git a/drivers/staging/fbtft/fb_hx8340bn.c b/drivers/staging/fbtft/fb_hx8340bn.c index d47dcf31fffb..2fd7b87ea0ce 100644 --- a/drivers/staging/fbtft/fb_hx8340bn.c +++ b/drivers/staging/fbtft/fb_hx8340bn.c @@ -151,7 +151,7 @@ static int set_var(struct fbtft_par *par) #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)] static int set_gamma(struct fbtft_par *par, u32 *curves) { - unsigned long mask[] = { + static const unsigned long mask[] = { 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, diff --git a/drivers/staging/fbtft/fb_hx8347d.c b/drivers/staging/fbtft/fb_hx8347d.c index 3427a858d17c..37eaf0862c5b 100644 --- a/drivers/staging/fbtft/fb_hx8347d.c +++ b/drivers/staging/fbtft/fb_hx8347d.c @@ -95,7 +95,7 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)] static int set_gamma(struct fbtft_par *par, u32 *curves) { - unsigned long mask[] = { + static const unsigned long mask[] = { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x7f, 0x7f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x0f, }; diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c index fd32376700e2..05648c3ffe47 100644 --- a/drivers/staging/fbtft/fb_ili9163.c +++ b/drivers/staging/fbtft/fb_ili9163.c @@ -195,7 +195,7 @@ static int set_var(struct fbtft_par *par) #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)] static int gamma_adj(struct fbtft_par *par, u32 *curves) { - unsigned long mask[] = { + static const unsigned long mask[] = { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1f, 0x3f, 0x0f, 0x0f, 0x7f, 0x1f, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F}; diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c index ea6e001288ce..f2e72d14431d 100644 --- a/drivers/staging/fbtft/fb_ili9320.c +++ b/drivers/staging/fbtft/fb_ili9320.c @@ -214,7 +214,7 @@ static int set_var(struct fbtft_par *par) #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)] static int set_gamma(struct fbtft_par *par, u32 *curves) { - unsigned long mask[] = { + static const unsigned long mask[] = { 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, }; diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c index 85e54a10ed72..c9aa4cb43123 100644 --- a/drivers/staging/fbtft/fb_ili9325.c +++ b/drivers/staging/fbtft/fb_ili9325.c @@ -208,7 +208,7 @@ static int set_var(struct fbtft_par *par) #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)] static int set_gamma(struct fbtft_par *par, u32 *curves) { - unsigned long mask[] = { + static const unsigned long mask[] = { 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, }; diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c index ad49973ad594..08f8a4bb8772 100644 --- a/drivers/staging/fbtft/fb_pcd8544.c +++ b/drivers/staging/fbtft/fb_pcd8544.c @@ -157,10 +157,10 @@ static struct fbtft_display display = { .backlight = 1, }; -FBTFT_REGISTER_DRIVER(DRVNAME, "philips,pdc8544", &display); +FBTFT_REGISTER_DRIVER(DRVNAME, "philips,pcd8544", &display); MODULE_ALIAS("spi:" DRVNAME); -MODULE_ALIAS("spi:pdc8544"); +MODULE_ALIAS("spi:pcd8544"); MODULE_DESCRIPTION("FB driver for the PCD8544 LCD Controller"); MODULE_AUTHOR("Noralf Tronnes"); diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c index 5a129b1352cc..8c7de3290343 100644 --- a/drivers/staging/fbtft/fb_s6d1121.c +++ b/drivers/staging/fbtft/fb_s6d1121.c @@ -123,7 +123,7 @@ static int set_var(struct fbtft_par *par) #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)] static int set_gamma(struct fbtft_par *par, u32 *curves) { - unsigned long mask[] = { + static const unsigned long mask[] = { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x1f, 0x1f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x1f, 0x1f, diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c index 88a5b6925901..7a3fe022cc69 100644 --- a/drivers/staging/fbtft/fb_ssd1289.c +++ b/drivers/staging/fbtft/fb_ssd1289.c @@ -129,7 +129,7 @@ static int set_var(struct fbtft_par *par) #define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)] static int set_gamma(struct fbtft_par *par, u32 *curves) { - unsigned long mask[] = { + static const unsigned long mask[] = { 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x1f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, }; diff --git a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt new file mode 100644 index 000000000000..b1f9474f36d5 --- /dev/null +++ b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt @@ -0,0 +1,71 @@ +* Arcx Anybus-S controller + +This chip communicates with the SoC over a parallel bus. It is +expected that its Device Tree node is specified as the child of a node +corresponding to the parallel bus used for communication. + +Required properties: +-------------------- + + - compatible : The following chip-specific string: + "arcx,anybus-controller" + + - reg : three areas: + index 0: bus memory area where the cpld registers are located. + index 1: bus memory area of the first host's dual-port ram. + index 2: bus memory area of the second host's dual-port ram. + + - reset-gpios : the GPIO pin connected to the reset line of the controller. + + - interrupts : two interrupts: + index 0: interrupt connected to the first host + index 1: interrupt connected to the second host + Generic interrupt client node bindings are described in + interrupt-controller/interrupts.txt + +Optional: use of subnodes +------------------------- + +The card connected to a host may need additional properties. These can be +specified in subnodes to the controller node. + +The subnodes are identified by the standard 'reg' property. Which information +exactly can be specified depends on the bindings for the function driver +for the subnode. + +Required controller node properties when using subnodes: +- #address-cells: should be one. +- #size-cells: should be zero. + +Required subnode properties: +- reg: Must contain the host index of the card this subnode describes: + <0> for the first host on the controller + <1> for the second host on the controller + Note that only a single card can be plugged into a host, so the host + index uniquely describes the card location. + +Example of usage: +----------------- + +This example places the bridge on top of the i.MX WEIM parallel bus, see: +Documentation/devicetree/bindings/bus/imx-weim.txt + +&weim { + controller@0,0 { + compatible = "arcx,anybus-controller"; + reg = <0 0 0x100>, <0 0x400000 0x800>, <1 0x400000 0x800>; + reset-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; + interrupt-parent = <&gpio1>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>, <5 IRQ_TYPE_LEVEL_LOW>; + /* fsl,weim-cs-timing is a i.MX WEIM bus specific property */ + fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100 + 0x00000000 0xa0000240 0x00000000>; + /* optional subnode for a card plugged into the first host */ + #address-cells = <1>; + #size-cells = <0>; + card@0 { + reg = <0>; + /* card specific properties go here */ + }; + }; +}; diff --git a/drivers/staging/fsl-dpaa2/ethsw/TODO b/drivers/staging/fsl-dpaa2/ethsw/TODO index 24b5e95a96f8..4d46857b0b2b 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/TODO +++ b/drivers/staging/fsl-dpaa2/ethsw/TODO @@ -1,7 +1,6 @@ * Add I/O capabilities on switch port netdevices. This will allow control traffic to reach the CPU. * Add ACL to redirect control traffic to CPU. -* Add support for displaying learned FDB entries * Add support for multiple FDBs and switch port partitioning * MC firmware uprev; the DPAA2 objects used by the Ethernet Switch driver need to be kept in sync with binary interface changes in MC diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h index 14b974defa3a..5e1339daa7c7 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw-cmd.h @@ -10,7 +10,7 @@ /* DPSW Version */ #define DPSW_VER_MAJOR 8 -#define DPSW_VER_MINOR 0 +#define DPSW_VER_MINOR 1 #define DPSW_CMD_BASE_VERSION 1 #define DPSW_CMD_ID_OFFSET 4 @@ -67,6 +67,7 @@ #define DPSW_CMDID_FDB_ADD_MULTICAST DPSW_CMD_ID(0x086) #define DPSW_CMDID_FDB_REMOVE_MULTICAST DPSW_CMD_ID(0x087) #define DPSW_CMDID_FDB_SET_LEARNING_MODE DPSW_CMD_ID(0x088) +#define DPSW_CMDID_FDB_DUMP DPSW_CMD_ID(0x08A) /* Macros for accessing command fields smaller than 1byte */ #define DPSW_MASK(field) \ @@ -351,6 +352,18 @@ struct dpsw_cmd_fdb_set_learning_mode { u8 mode; }; +struct dpsw_cmd_fdb_dump { + __le16 fdb_id; + __le16 pad0; + __le32 pad1; + __le64 iova_addr; + __le32 iova_size; +}; + +struct dpsw_rsp_fdb_dump { + __le16 num_entries; +}; + struct dpsw_rsp_get_api_version { __le16 version_major; __le16 version_minor; diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.c b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c index cabed77b445d..56b0fa789a67 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.c +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.c @@ -981,6 +981,57 @@ int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io, } /** + * dpsw_fdb_dump() - Dump the content of FDB table into memory. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPSW object + * @fdb_id: Forwarding Database Identifier + * @iova_addr: Data will be stored here as an array of struct fdb_dump_entry + * @iova_size: Memory size allocated at iova_addr + * @num_entries:Number of entries written at iova_addr + * + * Return: Completion status. '0' on Success; Error code otherwise. + * + * The memory allocated at iova_addr must be initialized with zero before + * command execution. If the FDB table does not fit into memory MC will stop + * after the memory is filled up. + * The struct fdb_dump_entry array must be parsed until the end of memory + * area or until an entry with mac_addr set to zero is found. + */ +int dpsw_fdb_dump(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u16 fdb_id, + u64 iova_addr, + u32 iova_size, + u16 *num_entries) +{ + struct dpsw_cmd_fdb_dump *cmd_params; + struct dpsw_rsp_fdb_dump *rsp_params; + struct fsl_mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_DUMP, + cmd_flags, + token); + cmd_params = (struct dpsw_cmd_fdb_dump *)cmd.params; + cmd_params->fdb_id = cpu_to_le16(fdb_id); + cmd_params->iova_addr = cpu_to_le64(iova_addr); + cmd_params->iova_size = cpu_to_le32(iova_size); + + /* send command to mc */ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + rsp_params = (struct dpsw_rsp_fdb_dump *)cmd.params; + *num_entries = le16_to_cpu(rsp_params->num_entries); + + return 0; +} + +/** * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' diff --git a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h index 25635259ce44..25b45850925c 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/dpsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/dpsw.h @@ -75,37 +75,6 @@ enum dpsw_component_type { DPSW_COMPONENT_TYPE_S_VLAN }; -/** - * struct dpsw_cfg - DPSW configuration - * @num_ifs: Number of external and internal interfaces - * @adv: Advanced parameters; default is all zeros; - * use this structure to change default settings - * @adv.options: Enable/Disable DPSW features (bitmap) - * @adv.max_vlans: Maximum Number of VLAN's; 0 - indicates default 16 - * @adv.max_meters_per_if: Number of meters per interface - * @adv.max_fdbs: Maximum Number of FDB's; 0 - indicates default 16 - * @adv.max_fdb_entries: Number of FDB entries for default FDB table; - * 0 - indicates default 1024 entries. - * @adv.fdb_aging_time: Default FDB aging time for default FDB table; - * 0 - indicates default 300 seconds - * @adv.max_fdb_mc_groups: Number of multicast groups in each FDB table; - * 0 - indicates default 32 - * @adv.component_type: Indicates the component type of this bridge - */ -struct dpsw_cfg { - u16 num_ifs; - struct { - u64 options; - u16 max_vlans; - u8 max_meters_per_if; - u8 max_fdbs; - u16 max_fdb_entries; - u16 fdb_aging_time; - u16 max_fdb_mc_groups; - enum dpsw_component_type component_type; - } adv; -}; - int dpsw_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); @@ -496,6 +465,31 @@ int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io, u16 fdb_id, const struct dpsw_fdb_unicast_cfg *cfg); +#define DPSW_FDB_ENTRY_TYPE_DYNAMIC BIT(0) +#define DPSW_FDB_ENTRY_TYPE_UNICAST BIT(1) + +/** + * struct fdb_dump_entry - fdb snapshot entry + * @mac_addr: MAC address + * @type: bit0 - DINAMIC(1)/STATIC(0), bit1 - UNICAST(1)/MULTICAST(0) + * @if_info: unicast - egress interface, multicast - number of egress interfaces + * @if_mask: multicast - egress interface mask + */ +struct fdb_dump_entry { + u8 mac_addr[6]; + u8 type; + u8 if_info; + u8 if_mask[8]; +}; + +int dpsw_fdb_dump(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u16 fdb_id, + u64 iova_addr, + u32 iova_size, + u16 *num_entries); + /** * struct dpsw_fdb_multicast_cfg - Multi-cast entry configuration * @type: Select static or dynamic entry diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c index 926a0c053e18..4f0bff86e43e 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw-ethtool.c @@ -65,7 +65,7 @@ ethsw_get_link_ksettings(struct net_device *netdev, port_priv->idx, &state); if (err) { - netdev_err(netdev, "ERROR %d getting link state", err); + netdev_err(netdev, "ERROR %d getting link state\n", err); goto out; } @@ -88,18 +88,21 @@ ethsw_set_link_ksettings(struct net_device *netdev, const struct ethtool_link_ksettings *link_ksettings) { struct ethsw_port_priv *port_priv = netdev_priv(netdev); + struct ethsw_core *ethsw = port_priv->ethsw_data; struct dpsw_link_cfg cfg = {0}; - int err = 0; - - netdev_dbg(netdev, "Setting link parameters..."); - - /* Due to a temporary MC limitation, the DPSW port must be down - * in order to be able to change link settings. Taking steps to let - * the user know that. - */ - if (netif_running(netdev)) { - netdev_info(netdev, "Sorry, interface must be brought down first.\n"); - return -EACCES; + bool if_running; + int err = 0, ret; + + /* Interface needs to be down to change link settings */ + if_running = netif_running(netdev); + if (if_running) { + err = dpsw_if_disable(ethsw->mc_io, 0, + ethsw->dpsw_handle, + port_priv->idx); + if (err) { + netdev_err(netdev, "dpsw_if_disable err %d\n", err); + return err; + } } cfg.rate = link_ksettings->base.speed; @@ -116,12 +119,16 @@ ethsw_set_link_ksettings(struct net_device *netdev, port_priv->ethsw_data->dpsw_handle, port_priv->idx, &cfg); - if (err) - /* ethtool will be loud enough if we return an error; no point - * in putting our own error message on the console by default - */ - netdev_dbg(netdev, "ERROR %d setting link cfg", err); + if (if_running) { + ret = dpsw_if_enable(ethsw->mc_io, 0, + ethsw->dpsw_handle, + port_priv->idx); + if (ret) { + netdev_err(netdev, "dpsw_if_enable err %d\n", ret); + return ret; + } + } return err; } @@ -156,9 +163,6 @@ static void ethsw_ethtool_get_stats(struct net_device *netdev, struct ethsw_port_priv *port_priv = netdev_priv(netdev); int i, err; - memset(data, 0, - sizeof(u64) * ETHSW_NUM_COUNTERS); - for (i = 0; i < ETHSW_NUM_COUNTERS; i++) { err = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0, port_priv->ethsw_data->dpsw_handle, diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c index f73edaf6ce87..14a9eebf687e 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c @@ -22,7 +22,7 @@ static struct workqueue_struct *ethsw_owq; /* Minimal supported DPSW version */ #define DPSW_MIN_VER_MAJOR 8 -#define DPSW_MIN_VER_MINOR 0 +#define DPSW_MIN_VER_MINOR 1 #define DEFAULT_VLAN_ID 1 @@ -34,11 +34,6 @@ static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid) .fdb_id = 0, }; - if (ethsw->vlans[vid]) { - dev_err(ethsw->dev, "VLAN already configured\n"); - return -EEXIST; - } - err = dpsw_vlan_add(ethsw->mc_io, 0, ethsw->dpsw_handle, vid, &vcfg); if (err) { @@ -149,12 +144,12 @@ static int ethsw_port_add_vlan(struct ethsw_port_priv *port_priv, return 0; } -static int ethsw_set_learning(struct ethsw_core *ethsw, u8 flag) +static int ethsw_set_learning(struct ethsw_core *ethsw, bool enable) { enum dpsw_fdb_learning_mode learn_mode; int err; - if (flag) + if (enable) learn_mode = DPSW_FDB_LEARNING_MODE_HW; else learn_mode = DPSW_FDB_LEARNING_MODE_DIS; @@ -165,24 +160,24 @@ static int ethsw_set_learning(struct ethsw_core *ethsw, u8 flag) dev_err(ethsw->dev, "dpsw_fdb_set_learning_mode err %d\n", err); return err; } - ethsw->learning = !!flag; + ethsw->learning = enable; return 0; } -static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, u8 flag) +static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, bool enable) { int err; err = dpsw_if_set_flooding(port_priv->ethsw_data->mc_io, 0, port_priv->ethsw_data->dpsw_handle, - port_priv->idx, flag); + port_priv->idx, enable); if (err) { netdev_err(port_priv->netdev, "dpsw_if_set_flooding err %d\n", err); return err; } - port_priv->flood = !!flag; + port_priv->flood = enable; return 0; } @@ -316,6 +311,31 @@ static int ethsw_port_fdb_del_mc(struct ethsw_port_priv *port_priv, return err; } +static int port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, const unsigned char *addr, + u16 vid, u16 flags, + struct netlink_ext_ack *extack) +{ + if (is_unicast_ether_addr(addr)) + return ethsw_port_fdb_add_uc(netdev_priv(dev), + addr); + else + return ethsw_port_fdb_add_mc(netdev_priv(dev), + addr); +} + +static int port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, u16 vid) +{ + if (is_unicast_ether_addr(addr)) + return ethsw_port_fdb_del_uc(netdev_priv(dev), + addr); + else + return ethsw_port_fdb_del_mc(netdev_priv(dev), + addr); +} + static void port_get_stats(struct net_device *netdev, struct rtnl_link_stats64 *stats) { @@ -516,17 +536,165 @@ static int swdev_get_port_parent_id(struct net_device *dev, return 0; } +static int port_get_phys_name(struct net_device *netdev, char *name, + size_t len) +{ + struct ethsw_port_priv *port_priv = netdev_priv(netdev); + int err; + + err = snprintf(name, len, "p%d", port_priv->idx); + if (err >= len) + return -EINVAL; + + return 0; +} + +struct ethsw_dump_ctx { + struct net_device *dev; + struct sk_buff *skb; + struct netlink_callback *cb; + int idx; +}; + +static int ethsw_fdb_do_dump(struct fdb_dump_entry *entry, + struct ethsw_dump_ctx *dump) +{ + int is_dynamic = entry->type & DPSW_FDB_ENTRY_DINAMIC; + u32 portid = NETLINK_CB(dump->cb->skb).portid; + u32 seq = dump->cb->nlh->nlmsg_seq; + struct nlmsghdr *nlh; + struct ndmsg *ndm; + + if (dump->idx < dump->cb->args[2]) + goto skip; + + nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH, + sizeof(*ndm), NLM_F_MULTI); + if (!nlh) + return -EMSGSIZE; + + ndm = nlmsg_data(nlh); + ndm->ndm_family = AF_BRIDGE; + ndm->ndm_pad1 = 0; + ndm->ndm_pad2 = 0; + ndm->ndm_flags = NTF_SELF; + ndm->ndm_type = 0; + ndm->ndm_ifindex = dump->dev->ifindex; + ndm->ndm_state = is_dynamic ? NUD_REACHABLE : NUD_NOARP; + + if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, entry->mac_addr)) + goto nla_put_failure; + + nlmsg_end(dump->skb, nlh); + +skip: + dump->idx++; + return 0; + +nla_put_failure: + nlmsg_cancel(dump->skb, nlh); + return -EMSGSIZE; +} + +static int port_fdb_valid_entry(struct fdb_dump_entry *entry, + struct ethsw_port_priv *port_priv) +{ + int idx = port_priv->idx; + int valid; + + if (entry->type & DPSW_FDB_ENTRY_TYPE_UNICAST) + valid = entry->if_info == port_priv->idx; + else + valid = entry->if_mask[idx / 8] & BIT(idx % 8); + + return valid; +} + +static int port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, + struct net_device *net_dev, + struct net_device *filter_dev, int *idx) +{ + struct ethsw_port_priv *port_priv = netdev_priv(net_dev); + struct ethsw_core *ethsw = port_priv->ethsw_data; + struct device *dev = net_dev->dev.parent; + struct fdb_dump_entry *fdb_entries; + struct fdb_dump_entry fdb_entry; + struct ethsw_dump_ctx dump = { + .dev = net_dev, + .skb = skb, + .cb = cb, + .idx = *idx, + }; + dma_addr_t fdb_dump_iova; + u16 num_fdb_entries; + u32 fdb_dump_size; + int err = 0, i; + u8 *dma_mem; + + fdb_dump_size = ethsw->sw_attr.max_fdb_entries * sizeof(fdb_entry); + dma_mem = kzalloc(fdb_dump_size, GFP_KERNEL); + if (!dma_mem) + return -ENOMEM; + + fdb_dump_iova = dma_map_single(dev, dma_mem, fdb_dump_size, + DMA_FROM_DEVICE); + if (dma_mapping_error(dev, fdb_dump_iova)) { + netdev_err(net_dev, "dma_map_single() failed\n"); + err = -ENOMEM; + goto err_map; + } + + err = dpsw_fdb_dump(ethsw->mc_io, 0, ethsw->dpsw_handle, 0, + fdb_dump_iova, fdb_dump_size, &num_fdb_entries); + if (err) { + netdev_err(net_dev, "dpsw_fdb_dump() = %d\n", err); + goto err_dump; + } + + dma_unmap_single(dev, fdb_dump_iova, fdb_dump_size, DMA_FROM_DEVICE); + + fdb_entries = (struct fdb_dump_entry *)dma_mem; + for (i = 0; i < num_fdb_entries; i++) { + fdb_entry = fdb_entries[i]; + + if (!port_fdb_valid_entry(&fdb_entry, port_priv)) + continue; + + err = ethsw_fdb_do_dump(&fdb_entry, &dump); + if (err) + goto end; + } + +end: + *idx = dump.idx; + + kfree(dma_mem); + + return 0; + +err_dump: + dma_unmap_single(dev, fdb_dump_iova, fdb_dump_size, DMA_TO_DEVICE); +err_map: + kfree(dma_mem); + return err; +} + static const struct net_device_ops ethsw_port_ops = { .ndo_open = port_open, .ndo_stop = port_stop, .ndo_set_mac_address = eth_mac_addr, + .ndo_get_stats64 = port_get_stats, .ndo_change_mtu = port_change_mtu, .ndo_has_offload_stats = port_has_offload_stats, .ndo_get_offload_stats = port_get_offload_stats, + .ndo_fdb_add = port_fdb_add, + .ndo_fdb_del = port_fdb_del, + .ndo_fdb_dump = port_fdb_dump, .ndo_start_xmit = port_dropframe, .ndo_get_port_parent_id = swdev_get_port_parent_id, + .ndo_get_phys_port_name = port_get_phys_name, }; static void ethsw_links_state_update(struct ethsw_core *ethsw) @@ -549,12 +717,12 @@ static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg) err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle, DPSW_IRQ_INDEX_IF, &status); if (err) { - dev_err(dev, "Can't get irq status (err %d)", err); + dev_err(dev, "Can't get irq status (err %d)\n", err); err = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle, DPSW_IRQ_INDEX_IF, 0xFFFFFFFF); if (err) - dev_err(dev, "Can't clear irq status (err %d)", err); + dev_err(dev, "Can't clear irq status (err %d)\n", err); goto out; } @@ -599,21 +767,21 @@ static int ethsw_setup_irqs(struct fsl_mc_device *sw_dev) IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(dev), dev); if (err) { - dev_err(dev, "devm_request_threaded_irq(): %d", err); + dev_err(dev, "devm_request_threaded_irq(): %d\n", err); goto free_irq; } err = dpsw_set_irq_mask(ethsw->mc_io, 0, ethsw->dpsw_handle, DPSW_IRQ_INDEX_IF, mask); if (err) { - dev_err(dev, "dpsw_set_irq_mask(): %d", err); + dev_err(dev, "dpsw_set_irq_mask(): %d\n", err); goto free_devm_irq; } err = dpsw_set_irq_enable(ethsw->mc_io, 0, ethsw->dpsw_handle, DPSW_IRQ_INDEX_IF, 1); if (err) { - dev_err(dev, "dpsw_set_irq_enable(): %d", err); + dev_err(dev, "dpsw_set_irq_enable(): %d\n", err); goto free_devm_irq; } @@ -673,11 +841,12 @@ static int port_attr_br_flags_set(struct net_device *netdev, return 0; /* Learning is enabled per switch */ - err = ethsw_set_learning(port_priv->ethsw_data, flags & BR_LEARNING); + err = ethsw_set_learning(port_priv->ethsw_data, + !!(flags & BR_LEARNING)); if (err) goto exit; - err = ethsw_port_set_flood(port_priv, flags & BR_FLOOD); + err = ethsw_port_set_flood(port_priv, !!(flags & BR_FLOOD)); exit: return err; @@ -950,8 +1119,7 @@ static int port_bridge_join(struct net_device *netdev, if (ethsw->ports[i]->bridge_dev && (ethsw->ports[i]->bridge_dev != upper_dev)) { netdev_err(netdev, - "Another switch port is connected to %s\n", - ethsw->ports[i]->bridge_dev->name); + "Only one bridge supported per DPSW object!\n"); return -EINVAL; } @@ -1023,18 +1191,30 @@ static void ethsw_switchdev_event_work(struct work_struct *work) container_of(work, struct ethsw_switchdev_event_work, work); struct net_device *dev = switchdev_work->dev; struct switchdev_notifier_fdb_info *fdb_info; + int err; rtnl_lock(); fdb_info = &switchdev_work->fdb_info; switch (switchdev_work->event) { case SWITCHDEV_FDB_ADD_TO_DEVICE: + if (!fdb_info->added_by_user) + break; if (is_unicast_ether_addr(fdb_info->addr)) - ethsw_port_fdb_add_uc(netdev_priv(dev), fdb_info->addr); + err = ethsw_port_fdb_add_uc(netdev_priv(dev), + fdb_info->addr); else - ethsw_port_fdb_add_mc(netdev_priv(dev), fdb_info->addr); + err = ethsw_port_fdb_add_mc(netdev_priv(dev), + fdb_info->addr); + if (err) + break; + fdb_info->offloaded = true; + call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, dev, + &fdb_info->info, NULL); break; case SWITCHDEV_FDB_DEL_TO_DEVICE: + if (!fdb_info->added_by_user) + break; if (is_unicast_ether_addr(fdb_info->addr)) ethsw_port_fdb_del_uc(netdev_priv(dev), fdb_info->addr); else @@ -1177,48 +1357,6 @@ err_switchdev_nb: return err; } -static int ethsw_open(struct ethsw_core *ethsw) -{ - struct ethsw_port_priv *port_priv = NULL; - int i, err; - - err = dpsw_enable(ethsw->mc_io, 0, ethsw->dpsw_handle); - if (err) { - dev_err(ethsw->dev, "dpsw_enable err %d\n", err); - return err; - } - - for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { - port_priv = ethsw->ports[i]; - err = dev_open(port_priv->netdev, NULL); - if (err) { - netdev_err(port_priv->netdev, "dev_open err %d\n", err); - return err; - } - } - - return 0; -} - -static int ethsw_stop(struct ethsw_core *ethsw) -{ - struct ethsw_port_priv *port_priv = NULL; - int i, err; - - for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { - port_priv = ethsw->ports[i]; - dev_close(port_priv->netdev); - } - - err = dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle); - if (err) { - dev_err(ethsw->dev, "dpsw_disable err %d\n", err); - return err; - } - - return 0; -} - static int ethsw_init(struct fsl_mc_device *sw_dev) { struct device *dev = &sw_dev->dev; @@ -1320,7 +1458,6 @@ err_close: static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) { - const char def_mcast[ETH_ALEN] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x01}; struct net_device *netdev = port_priv->netdev; struct ethsw_core *ethsw = port_priv->ethsw_data; struct dpsw_vlan_if_cfg vcfg; @@ -1346,12 +1483,10 @@ static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) err = dpsw_vlan_remove_if(ethsw->mc_io, 0, ethsw->dpsw_handle, DEFAULT_VLAN_ID, &vcfg); - if (err) { + if (err) netdev_err(netdev, "dpsw_vlan_remove_if err %d\n", err); - return err; - } - return ethsw_port_fdb_add_mc(port_priv, def_mcast); + return err; } static void ethsw_unregister_notifier(struct device *dev) @@ -1403,9 +1538,7 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev) destroy_workqueue(ethsw_owq); - rtnl_lock(); - ethsw_stop(ethsw); - rtnl_unlock(); + dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle); for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { port_priv = ethsw->ports[i]; @@ -1455,16 +1588,24 @@ static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx) port_netdev->min_mtu = ETH_MIN_MTU; port_netdev->max_mtu = ETHSW_MAX_FRAME_LENGTH; + err = ethsw_port_init(port_priv, port_idx); + if (err) + goto err_port_probe; + err = register_netdev(port_netdev); if (err < 0) { dev_err(dev, "register_netdev error %d\n", err); - free_netdev(port_netdev); - return err; + goto err_port_probe; } ethsw->ports[port_idx] = port_priv; - return ethsw_port_init(port_priv, port_idx); + return 0; + +err_port_probe: + free_netdev(port_netdev); + + return err; } static int ethsw_probe(struct fsl_mc_device *sw_dev) @@ -1482,7 +1623,8 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) ethsw->dev = dev; dev_set_drvdata(dev, ethsw); - err = fsl_mc_portal_allocate(sw_dev, 0, ðsw->mc_io); + err = fsl_mc_portal_allocate(sw_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, + ðsw->mc_io); if (err) { if (err == -ENXIO) err = -EPROBE_DEFER; @@ -1514,12 +1656,11 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) goto err_free_ports; } - /* Switch starts up enabled */ - rtnl_lock(); - err = ethsw_open(ethsw); - rtnl_unlock(); - if (err) + err = dpsw_enable(ethsw->mc_io, 0, ethsw->dpsw_handle); + if (err) { + dev_err(ethsw->dev, "dpsw_enable err %d\n", err); goto err_free_ports; + } /* Setup IRQs */ err = ethsw_setup_irqs(sw_dev); @@ -1530,9 +1671,7 @@ static int ethsw_probe(struct fsl_mc_device *sw_dev) return 0; err_stop: - rtnl_lock(); - ethsw_stop(ethsw); - rtnl_unlock(); + dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle); err_free_ports: /* Cleanup registered ports only */ diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h index c48783680a05..3ea8a0ad8c10 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h @@ -23,9 +23,13 @@ /* Number of IRQs supported */ #define DPSW_IRQ_NUM 2 +/* Port is member of VLAN */ #define ETHSW_VLAN_MEMBER 1 +/* VLAN to be treated as untagged on egress */ #define ETHSW_VLAN_UNTAGGED 2 +/* Untagged frames will be assigned to this VLAN */ #define ETHSW_VLAN_PVID 4 +/* VLAN configured on the switch */ #define ETHSW_VLAN_GLOBAL 8 /* Maximum Frame Length supported by HW (currently 10k) */ diff --git a/drivers/staging/gasket/apex_driver.c b/drivers/staging/gasket/apex_driver.c index 464648ee2036..46199c8ca441 100644 --- a/drivers/staging/gasket/apex_driver.c +++ b/drivers/staging/gasket/apex_driver.c @@ -509,6 +509,8 @@ static ssize_t sysfs_show(struct device *device, struct device_attribute *attr, struct gasket_dev *gasket_dev; struct gasket_sysfs_attribute *gasket_attr; enum sysfs_attribute_type type; + struct gasket_page_table *gpt; + uint val; gasket_dev = gasket_sysfs_get_device_data(device); if (!gasket_dev) { @@ -524,29 +526,25 @@ static ssize_t sysfs_show(struct device *device, struct device_attribute *attr, } type = (enum sysfs_attribute_type)gasket_attr->data.attr_type; + gpt = gasket_dev->page_table[0]; switch (type) { case ATTR_KERNEL_HIB_PAGE_TABLE_SIZE: - ret = scnprintf(buf, PAGE_SIZE, "%u\n", - gasket_page_table_num_entries( - gasket_dev->page_table[0])); + val = gasket_page_table_num_entries(gpt); break; case ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE: - ret = scnprintf(buf, PAGE_SIZE, "%u\n", - gasket_page_table_num_simple_entries( - gasket_dev->page_table[0])); + val = gasket_page_table_num_simple_entries(gpt); break; case ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES: - ret = scnprintf(buf, PAGE_SIZE, "%u\n", - gasket_page_table_num_active_pages( - gasket_dev->page_table[0])); + val = gasket_page_table_num_active_pages(gpt); break; default: dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n", attr->attr.name); ret = 0; - break; + goto exit; } - + ret = scnprintf(buf, PAGE_SIZE, "%u\n", val); +exit: gasket_sysfs_put_attr(device, gasket_attr); gasket_sysfs_put_device_data(device, gasket_dev); return ret; @@ -659,7 +657,7 @@ static void apex_pci_remove(struct pci_dev *pci_dev) pci_disable_device(pci_dev); } -static struct gasket_driver_desc apex_desc = { +static const struct gasket_driver_desc apex_desc = { .name = "apex", .driver_version = APEX_DRIVER_VERSION, .major = 120, diff --git a/drivers/staging/gasket/gasket_ioctl.c b/drivers/staging/gasket/gasket_ioctl.c index 7ecfba4f2b06..240f9bb10b71 100644 --- a/drivers/staging/gasket/gasket_ioctl.c +++ b/drivers/staging/gasket/gasket_ioctl.c @@ -39,8 +39,7 @@ static int gasket_set_event_fd(struct gasket_dev *gasket_dev, } /* Read the size of the page table. */ -static int gasket_read_page_table_size( - struct gasket_dev *gasket_dev, +static int gasket_read_page_table_size(struct gasket_dev *gasket_dev, struct gasket_page_table_ioctl __user *argp) { int ret = 0; @@ -66,8 +65,7 @@ static int gasket_read_page_table_size( } /* Read the size of the simple page table. */ -static int gasket_read_simple_page_table_size( - struct gasket_dev *gasket_dev, +static int gasket_read_simple_page_table_size(struct gasket_dev *gasket_dev, struct gasket_page_table_ioctl __user *argp) { int ret = 0; @@ -93,8 +91,7 @@ static int gasket_read_simple_page_table_size( } /* Set the boundary between the simple and extended page tables. */ -static int gasket_partition_page_table( - struct gasket_dev *gasket_dev, +static int gasket_partition_page_table(struct gasket_dev *gasket_dev, struct gasket_page_table_ioctl __user *argp) { int ret; @@ -185,8 +182,7 @@ static int gasket_unmap_buffers(struct gasket_dev *gasket_dev, * Reserve structures for coherent allocation, and allocate or free the * corresponding memory. */ -static int gasket_config_coherent_allocator( - struct gasket_dev *gasket_dev, +static int gasket_config_coherent_allocator(struct gasket_dev *gasket_dev, struct gasket_coherent_alloc_config_ioctl __user *argp) { int ret; diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c index 24a738238f9f..0c65a0121dde 100644 --- a/drivers/staging/goldfish/goldfish_audio.c +++ b/drivers/staging/goldfish/goldfish_audio.c @@ -302,10 +302,8 @@ static int goldfish_audio_probe(struct platform_device *pdev) return -ENOMEM; data->irq = platform_get_irq(pdev, 0); - if (data->irq < 0) { - dev_err(&pdev->dev, "platform_get_irq failed\n"); + if (data->irq < 0) return -ENODEV; - } data->buffer_virt = dmam_alloc_coherent(&pdev->dev, COMBINED_BUFFER_SIZE, &buf_addr, GFP_KERNEL); diff --git a/drivers/staging/greybus/Documentation/firmware/authenticate.c b/drivers/staging/greybus/Documentation/firmware/authenticate.c index 806e75b7f405..3d2c6f88a138 100644 --- a/drivers/staging/greybus/Documentation/firmware/authenticate.c +++ b/drivers/staging/greybus/Documentation/firmware/authenticate.c @@ -2,54 +2,8 @@ /* * Sample code to test CAP protocol * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * * Copyright(c) 2016 Google Inc. All rights reserved. * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details. - * - * BSD LICENSE - * - * Copyright(c) 2016 Google Inc. All rights reserved. - * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. or Linaro Ltd. nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR - * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> diff --git a/drivers/staging/greybus/Documentation/firmware/firmware.c b/drivers/staging/greybus/Documentation/firmware/firmware.c index 31d9c23e2eeb..765d69faa9cc 100644 --- a/drivers/staging/greybus/Documentation/firmware/firmware.c +++ b/drivers/staging/greybus/Documentation/firmware/firmware.c @@ -2,54 +2,8 @@ /* * Sample code to test firmware-management protocol * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * * Copyright(c) 2016 Google Inc. All rights reserved. * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details. - * - * BSD LICENSE - * - * Copyright(c) 2016 Google Inc. All rights reserved. - * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. or Linaro Ltd. nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR - * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig index 4894c3514955..d4777f5a8b90 100644 --- a/drivers/staging/greybus/Kconfig +++ b/drivers/staging/greybus/Kconfig @@ -1,33 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -menuconfig GREYBUS - tristate "Greybus support" - depends on SYSFS - ---help--- - This option enables the Greybus driver core. Greybus is an - hardware protocol that was designed to provide Unipro with a - sane application layer. It was originally designed for the - ARA project, a module phone system, but has shown up in other - phones, and can be tunneled over other busses in order to - control hardware devices. - - Say Y here to enable support for these types of drivers. - - To compile this code as a module, chose M here: the module - will be called greybus.ko - if GREYBUS -config GREYBUS_ES2 - tristate "Greybus ES3 USB host controller" - depends on USB - ---help--- - Select this option if you have a Toshiba ES3 USB device that - acts as a Greybus "host controller". This device is a bridge - from a USB device to a Unipro network. - - To compile this code as a module, chose M here: the module - will be called gb-es2.ko - config GREYBUS_AUDIO tristate "Greybus Audio Class driver" depends on SOUND diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile index 2551ed16b742..627e44f2a983 100644 --- a/drivers/staging/greybus/Makefile +++ b/drivers/staging/greybus/Makefile @@ -1,29 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 -# Greybus core -greybus-y := core.o \ - debugfs.o \ - hd.o \ - manifest.o \ - module.o \ - interface.o \ - bundle.o \ - connection.o \ - control.o \ - svc.o \ - svc_watchdog.o \ - operation.o - -obj-$(CONFIG_GREYBUS) += greybus.o - # needed for trace events ccflags-y += -I$(src) - -# Greybus Host controller drivers -gb-es2-y := es2.o - -obj-$(CONFIG_GREYBUS_ES2) += gb-es2.o - # Greybus class drivers gb-bootrom-y := bootrom.o gb-camera-y := camera.o diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index 6eb842040c22..eebf0deb39f5 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -19,8 +19,8 @@ #include <linux/irq.h> #include <linux/suspend.h> #include <linux/time.h> +#include <linux/greybus.h> #include "arche_platform.h" -#include "greybus.h" #if IS_ENABLED(CONFIG_USB_HSIC_USB3613) #include <linux/usb/usb3613.h> diff --git a/drivers/staging/greybus/arpc.h b/drivers/staging/greybus/arpc.h deleted file mode 100644 index 3dab6375909c..000000000000 --- a/drivers/staging/greybus/arpc.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ -/* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2016 Google Inc. All rights reserved. - * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details. - * - * BSD LICENSE - * - * Copyright(c) 2016 Google Inc. All rights reserved. - * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. or Linaro Ltd. nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR - * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __ARPC_H -#define __ARPC_H - -/* APBridgeA RPC (ARPC) */ - -enum arpc_result { - ARPC_SUCCESS = 0x00, - ARPC_NO_MEMORY = 0x01, - ARPC_INVALID = 0x02, - ARPC_TIMEOUT = 0x03, - ARPC_UNKNOWN_ERROR = 0xff, -}; - -struct arpc_request_message { - __le16 id; /* RPC unique id */ - __le16 size; /* Size in bytes of header + payload */ - __u8 type; /* RPC type */ - __u8 data[0]; /* ARPC data */ -} __packed; - -struct arpc_response_message { - __le16 id; /* RPC unique id */ - __u8 result; /* Result of RPC */ -} __packed; - -/* ARPC requests */ -#define ARPC_TYPE_CPORT_CONNECTED 0x01 -#define ARPC_TYPE_CPORT_QUIESCE 0x02 -#define ARPC_TYPE_CPORT_CLEAR 0x03 -#define ARPC_TYPE_CPORT_FLUSH 0x04 -#define ARPC_TYPE_CPORT_SHUTDOWN 0x05 - -struct arpc_cport_connected_req { - __le16 cport_id; -} __packed; - -struct arpc_cport_quiesce_req { - __le16 cport_id; - __le16 peer_space; - __le16 timeout; -} __packed; - -struct arpc_cport_clear_req { - __le16 cport_id; -} __packed; - -struct arpc_cport_flush_req { - __le16 cport_id; -} __packed; - -struct arpc_cport_shutdown_req { - __le16 cport_id; - __le16 timeout; - __u8 phase; -} __packed; - -#endif /* __ARPC_H */ diff --git a/drivers/staging/greybus/audio_apbridgea.c b/drivers/staging/greybus/audio_apbridgea.c index 7ebb1bde5cb7..26117e390deb 100644 --- a/drivers/staging/greybus/audio_apbridgea.c +++ b/drivers/staging/greybus/audio_apbridgea.c @@ -5,8 +5,7 @@ * Copyright 2015-2016 Google Inc. */ -#include "greybus.h" -#include "greybus_protocols.h" +#include <linux/greybus.h> #include "audio_apbridgea.h" #include "audio_codec.h" diff --git a/drivers/staging/greybus/audio_apbridgea.h b/drivers/staging/greybus/audio_apbridgea.h index 330fc7a397eb..3f1f4dd2c61a 100644 --- a/drivers/staging/greybus/audio_apbridgea.h +++ b/drivers/staging/greybus/audio_apbridgea.h @@ -1,30 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/** +/* * Copyright (c) 2015-2016 Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This is a special protocol for configuring communication over the diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h index 9ba09ea9c2fc..cb5d271da1a5 100644 --- a/drivers/staging/greybus/audio_codec.h +++ b/drivers/staging/greybus/audio_codec.h @@ -8,12 +8,10 @@ #ifndef __LINUX_GBAUDIO_CODEC_H #define __LINUX_GBAUDIO_CODEC_H +#include <linux/greybus.h> #include <sound/soc.h> #include <sound/jack.h> -#include "greybus.h" -#include "greybus_protocols.h" - #define NAME_SIZE 32 #define MAX_DAIS 2 /* APB1, APB2 */ diff --git a/drivers/staging/greybus/audio_gb.c b/drivers/staging/greybus/audio_gb.c index 8894f1c87d48..9d8994fdb41a 100644 --- a/drivers/staging/greybus/audio_gb.c +++ b/drivers/staging/greybus/audio_gb.c @@ -5,9 +5,7 @@ * Copyright 2015-2016 Google Inc. */ -#include "greybus.h" -#include "greybus_protocols.h" -#include "operation.h" +#include <linux/greybus.h> #include "audio_codec.h" /* TODO: Split into separate calls */ diff --git a/drivers/staging/greybus/audio_manager.c b/drivers/staging/greybus/audio_manager.c index c2a4af4c1d06..9b19ea9d3fa1 100644 --- a/drivers/staging/greybus/audio_manager.c +++ b/drivers/staging/greybus/audio_manager.c @@ -86,7 +86,7 @@ EXPORT_SYMBOL_GPL(gb_audio_manager_remove); void gb_audio_manager_remove_all(void) { struct gb_audio_manager_module *module, *next; - int is_empty = 1; + int is_empty; down_write(&modules_rwsem); diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index a5d7c53df987..297e69f011c7 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -6,8 +6,7 @@ * Copyright 2016 Linaro Ltd. */ -#include "greybus.h" - +#include <linux/greybus.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/ioctl.h> diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c index 402e6360834f..a8efb86de140 100644 --- a/drivers/staging/greybus/bootrom.c +++ b/drivers/staging/greybus/bootrom.c @@ -10,8 +10,8 @@ #include <linux/jiffies.h> #include <linux/mutex.h> #include <linux/workqueue.h> +#include <linux/greybus.h> -#include "greybus.h" #include "firmware.h" /* Timeout, in jiffies, within which the next request must be received */ diff --git a/drivers/staging/greybus/bundle.c b/drivers/staging/greybus/bundle.c deleted file mode 100644 index 3f702db9e098..000000000000 --- a/drivers/staging/greybus/bundle.c +++ /dev/null @@ -1,252 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus bundles - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#include "greybus.h" -#include "greybus_trace.h" - -static ssize_t bundle_class_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - - return sprintf(buf, "0x%02x\n", bundle->class); -} -static DEVICE_ATTR_RO(bundle_class); - -static ssize_t bundle_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - - return sprintf(buf, "%u\n", bundle->id); -} -static DEVICE_ATTR_RO(bundle_id); - -static ssize_t state_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - - if (!bundle->state) - return sprintf(buf, "\n"); - - return sprintf(buf, "%s\n", bundle->state); -} - -static ssize_t state_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - - kfree(bundle->state); - bundle->state = kstrdup(buf, GFP_KERNEL); - if (!bundle->state) - return -ENOMEM; - - /* Tell userspace that the file contents changed */ - sysfs_notify(&bundle->dev.kobj, NULL, "state"); - - return size; -} -static DEVICE_ATTR_RW(state); - -static struct attribute *bundle_attrs[] = { - &dev_attr_bundle_class.attr, - &dev_attr_bundle_id.attr, - &dev_attr_state.attr, - NULL, -}; - -ATTRIBUTE_GROUPS(bundle); - -static struct gb_bundle *gb_bundle_find(struct gb_interface *intf, - u8 bundle_id) -{ - struct gb_bundle *bundle; - - list_for_each_entry(bundle, &intf->bundles, links) { - if (bundle->id == bundle_id) - return bundle; - } - - return NULL; -} - -static void gb_bundle_release(struct device *dev) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - - trace_gb_bundle_release(bundle); - - kfree(bundle->state); - kfree(bundle->cport_desc); - kfree(bundle); -} - -#ifdef CONFIG_PM -static void gb_bundle_disable_all_connections(struct gb_bundle *bundle) -{ - struct gb_connection *connection; - - list_for_each_entry(connection, &bundle->connections, bundle_links) - gb_connection_disable(connection); -} - -static void gb_bundle_enable_all_connections(struct gb_bundle *bundle) -{ - struct gb_connection *connection; - - list_for_each_entry(connection, &bundle->connections, bundle_links) - gb_connection_enable(connection); -} - -static int gb_bundle_suspend(struct device *dev) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - const struct dev_pm_ops *pm = dev->driver->pm; - int ret; - - if (pm && pm->runtime_suspend) { - ret = pm->runtime_suspend(&bundle->dev); - if (ret) - return ret; - } else { - gb_bundle_disable_all_connections(bundle); - } - - ret = gb_control_bundle_suspend(bundle->intf->control, bundle->id); - if (ret) { - if (pm && pm->runtime_resume) - ret = pm->runtime_resume(dev); - else - gb_bundle_enable_all_connections(bundle); - - return ret; - } - - return 0; -} - -static int gb_bundle_resume(struct device *dev) -{ - struct gb_bundle *bundle = to_gb_bundle(dev); - const struct dev_pm_ops *pm = dev->driver->pm; - int ret; - - ret = gb_control_bundle_resume(bundle->intf->control, bundle->id); - if (ret) - return ret; - - if (pm && pm->runtime_resume) { - ret = pm->runtime_resume(dev); - if (ret) - return ret; - } else { - gb_bundle_enable_all_connections(bundle); - } - - return 0; -} - -static int gb_bundle_idle(struct device *dev) -{ - pm_runtime_mark_last_busy(dev); - pm_request_autosuspend(dev); - - return 0; -} -#endif - -static const struct dev_pm_ops gb_bundle_pm_ops = { - SET_RUNTIME_PM_OPS(gb_bundle_suspend, gb_bundle_resume, gb_bundle_idle) -}; - -struct device_type greybus_bundle_type = { - .name = "greybus_bundle", - .release = gb_bundle_release, - .pm = &gb_bundle_pm_ops, -}; - -/* - * Create a gb_bundle structure to represent a discovered - * bundle. Returns a pointer to the new bundle or a null - * pointer if a failure occurs due to memory exhaustion. - */ -struct gb_bundle *gb_bundle_create(struct gb_interface *intf, u8 bundle_id, - u8 class) -{ - struct gb_bundle *bundle; - - if (bundle_id == BUNDLE_ID_NONE) { - dev_err(&intf->dev, "can't use bundle id %u\n", bundle_id); - return NULL; - } - - /* - * Reject any attempt to reuse a bundle id. We initialize - * these serially, so there's no need to worry about keeping - * the interface bundle list locked here. - */ - if (gb_bundle_find(intf, bundle_id)) { - dev_err(&intf->dev, "duplicate bundle id %u\n", bundle_id); - return NULL; - } - - bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); - if (!bundle) - return NULL; - - bundle->intf = intf; - bundle->id = bundle_id; - bundle->class = class; - INIT_LIST_HEAD(&bundle->connections); - - bundle->dev.parent = &intf->dev; - bundle->dev.bus = &greybus_bus_type; - bundle->dev.type = &greybus_bundle_type; - bundle->dev.groups = bundle_groups; - bundle->dev.dma_mask = intf->dev.dma_mask; - device_initialize(&bundle->dev); - dev_set_name(&bundle->dev, "%s.%d", dev_name(&intf->dev), bundle_id); - - list_add(&bundle->links, &intf->bundles); - - trace_gb_bundle_create(bundle); - - return bundle; -} - -int gb_bundle_add(struct gb_bundle *bundle) -{ - int ret; - - ret = device_add(&bundle->dev); - if (ret) { - dev_err(&bundle->dev, "failed to register bundle: %d\n", ret); - return ret; - } - - trace_gb_bundle_add(bundle); - - return 0; -} - -/* - * Tear down a previously set up bundle. - */ -void gb_bundle_destroy(struct gb_bundle *bundle) -{ - trace_gb_bundle_destroy(bundle); - - if (device_is_registered(&bundle->dev)) - device_del(&bundle->dev); - - list_del(&bundle->links); - - put_device(&bundle->dev); -} diff --git a/drivers/staging/greybus/bundle.h b/drivers/staging/greybus/bundle.h deleted file mode 100644 index 8734d2055657..000000000000 --- a/drivers/staging/greybus/bundle.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Greybus bundles - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#ifndef __BUNDLE_H -#define __BUNDLE_H - -#include <linux/list.h> - -#define BUNDLE_ID_NONE U8_MAX - -/* Greybus "public" definitions" */ -struct gb_bundle { - struct device dev; - struct gb_interface *intf; - - u8 id; - u8 class; - u8 class_major; - u8 class_minor; - - size_t num_cports; - struct greybus_descriptor_cport *cport_desc; - - struct list_head connections; - u8 *state; - - struct list_head links; /* interface->bundles */ -}; -#define to_gb_bundle(d) container_of(d, struct gb_bundle, dev) - -/* Greybus "private" definitions" */ -struct gb_bundle *gb_bundle_create(struct gb_interface *intf, u8 bundle_id, - u8 class); -int gb_bundle_add(struct gb_bundle *bundle); -void gb_bundle_destroy(struct gb_bundle *bundle); - -/* Bundle Runtime PM wrappers */ -#ifdef CONFIG_PM -static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle) -{ - int retval; - - retval = pm_runtime_get_sync(&bundle->dev); - if (retval < 0) { - dev_err(&bundle->dev, - "pm_runtime_get_sync failed: %d\n", retval); - pm_runtime_put_noidle(&bundle->dev); - return retval; - } - - return 0; -} - -static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) -{ - int retval; - - pm_runtime_mark_last_busy(&bundle->dev); - retval = pm_runtime_put_autosuspend(&bundle->dev); - - return retval; -} - -static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) -{ - pm_runtime_get_noresume(&bundle->dev); -} - -static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) -{ - pm_runtime_put_noidle(&bundle->dev); -} - -#else -static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle) -{ return 0; } -static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) -{ return 0; } - -static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) {} -static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) {} -#endif - -#endif /* __BUNDLE_H */ diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index 615c8e7fd51e..b570e13394ac 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -14,9 +14,9 @@ #include <linux/string.h> #include <linux/uaccess.h> #include <linux/vmalloc.h> +#include <linux/greybus.h> #include "gb-camera.h" -#include "greybus.h" #include "greybus_protocols.h" enum gb_camera_debugs_buffer_id { diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c deleted file mode 100644 index eda964208cce..000000000000 --- a/drivers/staging/greybus/connection.c +++ /dev/null @@ -1,942 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus connections - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#include <linux/workqueue.h> - -#include "greybus.h" -#include "greybus_trace.h" - -#define GB_CONNECTION_CPORT_QUIESCE_TIMEOUT 1000 - -static void gb_connection_kref_release(struct kref *kref); - -static DEFINE_SPINLOCK(gb_connections_lock); -static DEFINE_MUTEX(gb_connection_mutex); - -/* Caller holds gb_connection_mutex. */ -static bool gb_connection_cport_in_use(struct gb_interface *intf, u16 cport_id) -{ - struct gb_host_device *hd = intf->hd; - struct gb_connection *connection; - - list_for_each_entry(connection, &hd->connections, hd_links) { - if (connection->intf == intf && - connection->intf_cport_id == cport_id) - return true; - } - - return false; -} - -static void gb_connection_get(struct gb_connection *connection) -{ - kref_get(&connection->kref); - - trace_gb_connection_get(connection); -} - -static void gb_connection_put(struct gb_connection *connection) -{ - trace_gb_connection_put(connection); - - kref_put(&connection->kref, gb_connection_kref_release); -} - -/* - * Returns a reference-counted pointer to the connection if found. - */ -static struct gb_connection * -gb_connection_hd_find(struct gb_host_device *hd, u16 cport_id) -{ - struct gb_connection *connection; - unsigned long flags; - - spin_lock_irqsave(&gb_connections_lock, flags); - list_for_each_entry(connection, &hd->connections, hd_links) - if (connection->hd_cport_id == cport_id) { - gb_connection_get(connection); - goto found; - } - connection = NULL; -found: - spin_unlock_irqrestore(&gb_connections_lock, flags); - - return connection; -} - -/* - * Callback from the host driver to let us know that data has been - * received on the bundle. - */ -void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id, - u8 *data, size_t length) -{ - struct gb_connection *connection; - - trace_gb_hd_in(hd); - - connection = gb_connection_hd_find(hd, cport_id); - if (!connection) { - dev_err(&hd->dev, - "nonexistent connection (%zu bytes dropped)\n", length); - return; - } - gb_connection_recv(connection, data, length); - gb_connection_put(connection); -} -EXPORT_SYMBOL_GPL(greybus_data_rcvd); - -static void gb_connection_kref_release(struct kref *kref) -{ - struct gb_connection *connection; - - connection = container_of(kref, struct gb_connection, kref); - - trace_gb_connection_release(connection); - - kfree(connection); -} - -static void gb_connection_init_name(struct gb_connection *connection) -{ - u16 hd_cport_id = connection->hd_cport_id; - u16 cport_id = 0; - u8 intf_id = 0; - - if (connection->intf) { - intf_id = connection->intf->interface_id; - cport_id = connection->intf_cport_id; - } - - snprintf(connection->name, sizeof(connection->name), - "%u/%u:%u", hd_cport_id, intf_id, cport_id); -} - -/* - * _gb_connection_create() - create a Greybus connection - * @hd: host device of the connection - * @hd_cport_id: host-device cport id, or -1 for dynamic allocation - * @intf: remote interface, or NULL for static connections - * @bundle: remote-interface bundle (may be NULL) - * @cport_id: remote-interface cport id, or 0 for static connections - * @handler: request handler (may be NULL) - * @flags: connection flags - * - * Create a Greybus connection, representing the bidirectional link - * between a CPort on a (local) Greybus host device and a CPort on - * another Greybus interface. - * - * A connection also maintains the state of operations sent over the - * connection. - * - * Serialised against concurrent create and destroy using the - * gb_connection_mutex. - * - * Return: A pointer to the new connection if successful, or an ERR_PTR - * otherwise. - */ -static struct gb_connection * -_gb_connection_create(struct gb_host_device *hd, int hd_cport_id, - struct gb_interface *intf, - struct gb_bundle *bundle, int cport_id, - gb_request_handler_t handler, - unsigned long flags) -{ - struct gb_connection *connection; - int ret; - - mutex_lock(&gb_connection_mutex); - - if (intf && gb_connection_cport_in_use(intf, cport_id)) { - dev_err(&intf->dev, "cport %u already in use\n", cport_id); - ret = -EBUSY; - goto err_unlock; - } - - ret = gb_hd_cport_allocate(hd, hd_cport_id, flags); - if (ret < 0) { - dev_err(&hd->dev, "failed to allocate cport: %d\n", ret); - goto err_unlock; - } - hd_cport_id = ret; - - connection = kzalloc(sizeof(*connection), GFP_KERNEL); - if (!connection) { - ret = -ENOMEM; - goto err_hd_cport_release; - } - - connection->hd_cport_id = hd_cport_id; - connection->intf_cport_id = cport_id; - connection->hd = hd; - connection->intf = intf; - connection->bundle = bundle; - connection->handler = handler; - connection->flags = flags; - if (intf && (intf->quirks & GB_INTERFACE_QUIRK_NO_CPORT_FEATURES)) - connection->flags |= GB_CONNECTION_FLAG_NO_FLOWCTRL; - connection->state = GB_CONNECTION_STATE_DISABLED; - - atomic_set(&connection->op_cycle, 0); - mutex_init(&connection->mutex); - spin_lock_init(&connection->lock); - INIT_LIST_HEAD(&connection->operations); - - connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1, - dev_name(&hd->dev), hd_cport_id); - if (!connection->wq) { - ret = -ENOMEM; - goto err_free_connection; - } - - kref_init(&connection->kref); - - gb_connection_init_name(connection); - - spin_lock_irq(&gb_connections_lock); - list_add(&connection->hd_links, &hd->connections); - - if (bundle) - list_add(&connection->bundle_links, &bundle->connections); - else - INIT_LIST_HEAD(&connection->bundle_links); - - spin_unlock_irq(&gb_connections_lock); - - mutex_unlock(&gb_connection_mutex); - - trace_gb_connection_create(connection); - - return connection; - -err_free_connection: - kfree(connection); -err_hd_cport_release: - gb_hd_cport_release(hd, hd_cport_id); -err_unlock: - mutex_unlock(&gb_connection_mutex); - - return ERR_PTR(ret); -} - -struct gb_connection * -gb_connection_create_static(struct gb_host_device *hd, u16 hd_cport_id, - gb_request_handler_t handler) -{ - return _gb_connection_create(hd, hd_cport_id, NULL, NULL, 0, handler, - GB_CONNECTION_FLAG_HIGH_PRIO); -} - -struct gb_connection * -gb_connection_create_control(struct gb_interface *intf) -{ - return _gb_connection_create(intf->hd, -1, intf, NULL, 0, NULL, - GB_CONNECTION_FLAG_CONTROL | - GB_CONNECTION_FLAG_HIGH_PRIO); -} - -struct gb_connection * -gb_connection_create(struct gb_bundle *bundle, u16 cport_id, - gb_request_handler_t handler) -{ - struct gb_interface *intf = bundle->intf; - - return _gb_connection_create(intf->hd, -1, intf, bundle, cport_id, - handler, 0); -} -EXPORT_SYMBOL_GPL(gb_connection_create); - -struct gb_connection * -gb_connection_create_flags(struct gb_bundle *bundle, u16 cport_id, - gb_request_handler_t handler, - unsigned long flags) -{ - struct gb_interface *intf = bundle->intf; - - if (WARN_ON_ONCE(flags & GB_CONNECTION_FLAG_CORE_MASK)) - flags &= ~GB_CONNECTION_FLAG_CORE_MASK; - - return _gb_connection_create(intf->hd, -1, intf, bundle, cport_id, - handler, flags); -} -EXPORT_SYMBOL_GPL(gb_connection_create_flags); - -struct gb_connection * -gb_connection_create_offloaded(struct gb_bundle *bundle, u16 cport_id, - unsigned long flags) -{ - flags |= GB_CONNECTION_FLAG_OFFLOADED; - - return gb_connection_create_flags(bundle, cport_id, NULL, flags); -} -EXPORT_SYMBOL_GPL(gb_connection_create_offloaded); - -static int gb_connection_hd_cport_enable(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - int ret; - - if (!hd->driver->cport_enable) - return 0; - - ret = hd->driver->cport_enable(hd, connection->hd_cport_id, - connection->flags); - if (ret) { - dev_err(&hd->dev, "%s: failed to enable host cport: %d\n", - connection->name, ret); - return ret; - } - - return 0; -} - -static void gb_connection_hd_cport_disable(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - int ret; - - if (!hd->driver->cport_disable) - return; - - ret = hd->driver->cport_disable(hd, connection->hd_cport_id); - if (ret) { - dev_err(&hd->dev, "%s: failed to disable host cport: %d\n", - connection->name, ret); - } -} - -static int gb_connection_hd_cport_connected(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - int ret; - - if (!hd->driver->cport_connected) - return 0; - - ret = hd->driver->cport_connected(hd, connection->hd_cport_id); - if (ret) { - dev_err(&hd->dev, "%s: failed to set connected state: %d\n", - connection->name, ret); - return ret; - } - - return 0; -} - -static int gb_connection_hd_cport_flush(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - int ret; - - if (!hd->driver->cport_flush) - return 0; - - ret = hd->driver->cport_flush(hd, connection->hd_cport_id); - if (ret) { - dev_err(&hd->dev, "%s: failed to flush host cport: %d\n", - connection->name, ret); - return ret; - } - - return 0; -} - -static int gb_connection_hd_cport_quiesce(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - size_t peer_space; - int ret; - - if (!hd->driver->cport_quiesce) - return 0; - - peer_space = sizeof(struct gb_operation_msg_hdr) + - sizeof(struct gb_cport_shutdown_request); - - if (connection->mode_switch) - peer_space += sizeof(struct gb_operation_msg_hdr); - - if (!hd->driver->cport_quiesce) - return 0; - - ret = hd->driver->cport_quiesce(hd, connection->hd_cport_id, - peer_space, - GB_CONNECTION_CPORT_QUIESCE_TIMEOUT); - if (ret) { - dev_err(&hd->dev, "%s: failed to quiesce host cport: %d\n", - connection->name, ret); - return ret; - } - - return 0; -} - -static int gb_connection_hd_cport_clear(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - int ret; - - if (!hd->driver->cport_clear) - return 0; - - ret = hd->driver->cport_clear(hd, connection->hd_cport_id); - if (ret) { - dev_err(&hd->dev, "%s: failed to clear host cport: %d\n", - connection->name, ret); - return ret; - } - - return 0; -} - -/* - * Request the SVC to create a connection from AP's cport to interface's - * cport. - */ -static int -gb_connection_svc_connection_create(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - struct gb_interface *intf; - u8 cport_flags; - int ret; - - if (gb_connection_is_static(connection)) - return 0; - - intf = connection->intf; - - /* - * Enable either E2EFC or CSD, unless no flow control is requested. - */ - cport_flags = GB_SVC_CPORT_FLAG_CSV_N; - if (gb_connection_flow_control_disabled(connection)) { - cport_flags |= GB_SVC_CPORT_FLAG_CSD_N; - } else if (gb_connection_e2efc_enabled(connection)) { - cport_flags |= GB_SVC_CPORT_FLAG_CSD_N | - GB_SVC_CPORT_FLAG_E2EFC; - } - - ret = gb_svc_connection_create(hd->svc, - hd->svc->ap_intf_id, - connection->hd_cport_id, - intf->interface_id, - connection->intf_cport_id, - cport_flags); - if (ret) { - dev_err(&connection->hd->dev, - "%s: failed to create svc connection: %d\n", - connection->name, ret); - return ret; - } - - return 0; -} - -static void -gb_connection_svc_connection_destroy(struct gb_connection *connection) -{ - if (gb_connection_is_static(connection)) - return; - - gb_svc_connection_destroy(connection->hd->svc, - connection->hd->svc->ap_intf_id, - connection->hd_cport_id, - connection->intf->interface_id, - connection->intf_cport_id); -} - -/* Inform Interface about active CPorts */ -static int gb_connection_control_connected(struct gb_connection *connection) -{ - struct gb_control *control; - u16 cport_id = connection->intf_cport_id; - int ret; - - if (gb_connection_is_static(connection)) - return 0; - - if (gb_connection_is_control(connection)) - return 0; - - control = connection->intf->control; - - ret = gb_control_connected_operation(control, cport_id); - if (ret) { - dev_err(&connection->bundle->dev, - "failed to connect cport: %d\n", ret); - return ret; - } - - return 0; -} - -static void -gb_connection_control_disconnecting(struct gb_connection *connection) -{ - struct gb_control *control; - u16 cport_id = connection->intf_cport_id; - int ret; - - if (gb_connection_is_static(connection)) - return; - - control = connection->intf->control; - - ret = gb_control_disconnecting_operation(control, cport_id); - if (ret) { - dev_err(&connection->hd->dev, - "%s: failed to send disconnecting: %d\n", - connection->name, ret); - } -} - -static void -gb_connection_control_disconnected(struct gb_connection *connection) -{ - struct gb_control *control; - u16 cport_id = connection->intf_cport_id; - int ret; - - if (gb_connection_is_static(connection)) - return; - - control = connection->intf->control; - - if (gb_connection_is_control(connection)) { - if (connection->mode_switch) { - ret = gb_control_mode_switch_operation(control); - if (ret) { - /* - * Allow mode switch to time out waiting for - * mailbox event. - */ - return; - } - } - - return; - } - - ret = gb_control_disconnected_operation(control, cport_id); - if (ret) { - dev_warn(&connection->bundle->dev, - "failed to disconnect cport: %d\n", ret); - } -} - -static int gb_connection_shutdown_operation(struct gb_connection *connection, - u8 phase) -{ - struct gb_cport_shutdown_request *req; - struct gb_operation *operation; - int ret; - - operation = gb_operation_create_core(connection, - GB_REQUEST_TYPE_CPORT_SHUTDOWN, - sizeof(*req), 0, 0, - GFP_KERNEL); - if (!operation) - return -ENOMEM; - - req = operation->request->payload; - req->phase = phase; - - ret = gb_operation_request_send_sync(operation); - - gb_operation_put(operation); - - return ret; -} - -static int gb_connection_cport_shutdown(struct gb_connection *connection, - u8 phase) -{ - struct gb_host_device *hd = connection->hd; - const struct gb_hd_driver *drv = hd->driver; - int ret; - - if (gb_connection_is_static(connection)) - return 0; - - if (gb_connection_is_offloaded(connection)) { - if (!drv->cport_shutdown) - return 0; - - ret = drv->cport_shutdown(hd, connection->hd_cport_id, phase, - GB_OPERATION_TIMEOUT_DEFAULT); - } else { - ret = gb_connection_shutdown_operation(connection, phase); - } - - if (ret) { - dev_err(&hd->dev, "%s: failed to send cport shutdown (phase %d): %d\n", - connection->name, phase, ret); - return ret; - } - - return 0; -} - -static int -gb_connection_cport_shutdown_phase_1(struct gb_connection *connection) -{ - return gb_connection_cport_shutdown(connection, 1); -} - -static int -gb_connection_cport_shutdown_phase_2(struct gb_connection *connection) -{ - return gb_connection_cport_shutdown(connection, 2); -} - -/* - * Cancel all active operations on a connection. - * - * Locking: Called with connection lock held and state set to DISABLED or - * DISCONNECTING. - */ -static void gb_connection_cancel_operations(struct gb_connection *connection, - int errno) - __must_hold(&connection->lock) -{ - struct gb_operation *operation; - - while (!list_empty(&connection->operations)) { - operation = list_last_entry(&connection->operations, - struct gb_operation, links); - gb_operation_get(operation); - spin_unlock_irq(&connection->lock); - - if (gb_operation_is_incoming(operation)) - gb_operation_cancel_incoming(operation, errno); - else - gb_operation_cancel(operation, errno); - - gb_operation_put(operation); - - spin_lock_irq(&connection->lock); - } -} - -/* - * Cancel all active incoming operations on a connection. - * - * Locking: Called with connection lock held and state set to ENABLED_TX. - */ -static void -gb_connection_flush_incoming_operations(struct gb_connection *connection, - int errno) - __must_hold(&connection->lock) -{ - struct gb_operation *operation; - bool incoming; - - while (!list_empty(&connection->operations)) { - incoming = false; - list_for_each_entry(operation, &connection->operations, - links) { - if (gb_operation_is_incoming(operation)) { - gb_operation_get(operation); - incoming = true; - break; - } - } - - if (!incoming) - break; - - spin_unlock_irq(&connection->lock); - - /* FIXME: flush, not cancel? */ - gb_operation_cancel_incoming(operation, errno); - gb_operation_put(operation); - - spin_lock_irq(&connection->lock); - } -} - -/* - * _gb_connection_enable() - enable a connection - * @connection: connection to enable - * @rx: whether to enable incoming requests - * - * Connection-enable helper for DISABLED->ENABLED, DISABLED->ENABLED_TX, and - * ENABLED_TX->ENABLED state transitions. - * - * Locking: Caller holds connection->mutex. - */ -static int _gb_connection_enable(struct gb_connection *connection, bool rx) -{ - int ret; - - /* Handle ENABLED_TX -> ENABLED transitions. */ - if (connection->state == GB_CONNECTION_STATE_ENABLED_TX) { - if (!(connection->handler && rx)) - return 0; - - spin_lock_irq(&connection->lock); - connection->state = GB_CONNECTION_STATE_ENABLED; - spin_unlock_irq(&connection->lock); - - return 0; - } - - ret = gb_connection_hd_cport_enable(connection); - if (ret) - return ret; - - ret = gb_connection_svc_connection_create(connection); - if (ret) - goto err_hd_cport_clear; - - ret = gb_connection_hd_cport_connected(connection); - if (ret) - goto err_svc_connection_destroy; - - spin_lock_irq(&connection->lock); - if (connection->handler && rx) - connection->state = GB_CONNECTION_STATE_ENABLED; - else - connection->state = GB_CONNECTION_STATE_ENABLED_TX; - spin_unlock_irq(&connection->lock); - - ret = gb_connection_control_connected(connection); - if (ret) - goto err_control_disconnecting; - - return 0; - -err_control_disconnecting: - spin_lock_irq(&connection->lock); - connection->state = GB_CONNECTION_STATE_DISCONNECTING; - gb_connection_cancel_operations(connection, -ESHUTDOWN); - spin_unlock_irq(&connection->lock); - - /* Transmit queue should already be empty. */ - gb_connection_hd_cport_flush(connection); - - gb_connection_control_disconnecting(connection); - gb_connection_cport_shutdown_phase_1(connection); - gb_connection_hd_cport_quiesce(connection); - gb_connection_cport_shutdown_phase_2(connection); - gb_connection_control_disconnected(connection); - connection->state = GB_CONNECTION_STATE_DISABLED; -err_svc_connection_destroy: - gb_connection_svc_connection_destroy(connection); -err_hd_cport_clear: - gb_connection_hd_cport_clear(connection); - - gb_connection_hd_cport_disable(connection); - - return ret; -} - -int gb_connection_enable(struct gb_connection *connection) -{ - int ret = 0; - - mutex_lock(&connection->mutex); - - if (connection->state == GB_CONNECTION_STATE_ENABLED) - goto out_unlock; - - ret = _gb_connection_enable(connection, true); - if (!ret) - trace_gb_connection_enable(connection); - -out_unlock: - mutex_unlock(&connection->mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(gb_connection_enable); - -int gb_connection_enable_tx(struct gb_connection *connection) -{ - int ret = 0; - - mutex_lock(&connection->mutex); - - if (connection->state == GB_CONNECTION_STATE_ENABLED) { - ret = -EINVAL; - goto out_unlock; - } - - if (connection->state == GB_CONNECTION_STATE_ENABLED_TX) - goto out_unlock; - - ret = _gb_connection_enable(connection, false); - if (!ret) - trace_gb_connection_enable(connection); - -out_unlock: - mutex_unlock(&connection->mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(gb_connection_enable_tx); - -void gb_connection_disable_rx(struct gb_connection *connection) -{ - mutex_lock(&connection->mutex); - - spin_lock_irq(&connection->lock); - if (connection->state != GB_CONNECTION_STATE_ENABLED) { - spin_unlock_irq(&connection->lock); - goto out_unlock; - } - connection->state = GB_CONNECTION_STATE_ENABLED_TX; - gb_connection_flush_incoming_operations(connection, -ESHUTDOWN); - spin_unlock_irq(&connection->lock); - - trace_gb_connection_disable(connection); - -out_unlock: - mutex_unlock(&connection->mutex); -} -EXPORT_SYMBOL_GPL(gb_connection_disable_rx); - -void gb_connection_mode_switch_prepare(struct gb_connection *connection) -{ - connection->mode_switch = true; -} - -void gb_connection_mode_switch_complete(struct gb_connection *connection) -{ - gb_connection_svc_connection_destroy(connection); - gb_connection_hd_cport_clear(connection); - - gb_connection_hd_cport_disable(connection); - - connection->mode_switch = false; -} - -void gb_connection_disable(struct gb_connection *connection) -{ - mutex_lock(&connection->mutex); - - if (connection->state == GB_CONNECTION_STATE_DISABLED) - goto out_unlock; - - trace_gb_connection_disable(connection); - - spin_lock_irq(&connection->lock); - connection->state = GB_CONNECTION_STATE_DISCONNECTING; - gb_connection_cancel_operations(connection, -ESHUTDOWN); - spin_unlock_irq(&connection->lock); - - gb_connection_hd_cport_flush(connection); - - gb_connection_control_disconnecting(connection); - gb_connection_cport_shutdown_phase_1(connection); - gb_connection_hd_cport_quiesce(connection); - gb_connection_cport_shutdown_phase_2(connection); - gb_connection_control_disconnected(connection); - - connection->state = GB_CONNECTION_STATE_DISABLED; - - /* control-connection tear down is deferred when mode switching */ - if (!connection->mode_switch) { - gb_connection_svc_connection_destroy(connection); - gb_connection_hd_cport_clear(connection); - - gb_connection_hd_cport_disable(connection); - } - -out_unlock: - mutex_unlock(&connection->mutex); -} -EXPORT_SYMBOL_GPL(gb_connection_disable); - -/* Disable a connection without communicating with the remote end. */ -void gb_connection_disable_forced(struct gb_connection *connection) -{ - mutex_lock(&connection->mutex); - - if (connection->state == GB_CONNECTION_STATE_DISABLED) - goto out_unlock; - - trace_gb_connection_disable(connection); - - spin_lock_irq(&connection->lock); - connection->state = GB_CONNECTION_STATE_DISABLED; - gb_connection_cancel_operations(connection, -ESHUTDOWN); - spin_unlock_irq(&connection->lock); - - gb_connection_hd_cport_flush(connection); - - gb_connection_svc_connection_destroy(connection); - gb_connection_hd_cport_clear(connection); - - gb_connection_hd_cport_disable(connection); -out_unlock: - mutex_unlock(&connection->mutex); -} -EXPORT_SYMBOL_GPL(gb_connection_disable_forced); - -/* Caller must have disabled the connection before destroying it. */ -void gb_connection_destroy(struct gb_connection *connection) -{ - if (!connection) - return; - - if (WARN_ON(connection->state != GB_CONNECTION_STATE_DISABLED)) - gb_connection_disable(connection); - - mutex_lock(&gb_connection_mutex); - - spin_lock_irq(&gb_connections_lock); - list_del(&connection->bundle_links); - list_del(&connection->hd_links); - spin_unlock_irq(&gb_connections_lock); - - destroy_workqueue(connection->wq); - - gb_hd_cport_release(connection->hd, connection->hd_cport_id); - connection->hd_cport_id = CPORT_ID_BAD; - - mutex_unlock(&gb_connection_mutex); - - gb_connection_put(connection); -} -EXPORT_SYMBOL_GPL(gb_connection_destroy); - -void gb_connection_latency_tag_enable(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - int ret; - - if (!hd->driver->latency_tag_enable) - return; - - ret = hd->driver->latency_tag_enable(hd, connection->hd_cport_id); - if (ret) { - dev_err(&connection->hd->dev, - "%s: failed to enable latency tag: %d\n", - connection->name, ret); - } -} -EXPORT_SYMBOL_GPL(gb_connection_latency_tag_enable); - -void gb_connection_latency_tag_disable(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - int ret; - - if (!hd->driver->latency_tag_disable) - return; - - ret = hd->driver->latency_tag_disable(hd, connection->hd_cport_id); - if (ret) { - dev_err(&connection->hd->dev, - "%s: failed to disable latency tag: %d\n", - connection->name, ret); - } -} -EXPORT_SYMBOL_GPL(gb_connection_latency_tag_disable); diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h deleted file mode 100644 index 5ca3befc0636..000000000000 --- a/drivers/staging/greybus/connection.h +++ /dev/null @@ -1,128 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Greybus connections - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#ifndef __CONNECTION_H -#define __CONNECTION_H - -#include <linux/list.h> -#include <linux/kfifo.h> - -#define GB_CONNECTION_FLAG_CSD BIT(0) -#define GB_CONNECTION_FLAG_NO_FLOWCTRL BIT(1) -#define GB_CONNECTION_FLAG_OFFLOADED BIT(2) -#define GB_CONNECTION_FLAG_CDSI1 BIT(3) -#define GB_CONNECTION_FLAG_CONTROL BIT(4) -#define GB_CONNECTION_FLAG_HIGH_PRIO BIT(5) - -#define GB_CONNECTION_FLAG_CORE_MASK GB_CONNECTION_FLAG_CONTROL - -enum gb_connection_state { - GB_CONNECTION_STATE_DISABLED = 0, - GB_CONNECTION_STATE_ENABLED_TX = 1, - GB_CONNECTION_STATE_ENABLED = 2, - GB_CONNECTION_STATE_DISCONNECTING = 3, -}; - -struct gb_operation; - -typedef int (*gb_request_handler_t)(struct gb_operation *); - -struct gb_connection { - struct gb_host_device *hd; - struct gb_interface *intf; - struct gb_bundle *bundle; - struct kref kref; - u16 hd_cport_id; - u16 intf_cport_id; - - struct list_head hd_links; - struct list_head bundle_links; - - gb_request_handler_t handler; - unsigned long flags; - - struct mutex mutex; - spinlock_t lock; - enum gb_connection_state state; - struct list_head operations; - - char name[16]; - struct workqueue_struct *wq; - - atomic_t op_cycle; - - void *private; - - bool mode_switch; -}; - -struct gb_connection *gb_connection_create_static(struct gb_host_device *hd, - u16 hd_cport_id, gb_request_handler_t handler); -struct gb_connection *gb_connection_create_control(struct gb_interface *intf); -struct gb_connection *gb_connection_create(struct gb_bundle *bundle, - u16 cport_id, gb_request_handler_t handler); -struct gb_connection *gb_connection_create_flags(struct gb_bundle *bundle, - u16 cport_id, gb_request_handler_t handler, - unsigned long flags); -struct gb_connection *gb_connection_create_offloaded(struct gb_bundle *bundle, - u16 cport_id, unsigned long flags); -void gb_connection_destroy(struct gb_connection *connection); - -static inline bool gb_connection_is_static(struct gb_connection *connection) -{ - return !connection->intf; -} - -int gb_connection_enable(struct gb_connection *connection); -int gb_connection_enable_tx(struct gb_connection *connection); -void gb_connection_disable_rx(struct gb_connection *connection); -void gb_connection_disable(struct gb_connection *connection); -void gb_connection_disable_forced(struct gb_connection *connection); - -void gb_connection_mode_switch_prepare(struct gb_connection *connection); -void gb_connection_mode_switch_complete(struct gb_connection *connection); - -void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id, - u8 *data, size_t length); - -void gb_connection_latency_tag_enable(struct gb_connection *connection); -void gb_connection_latency_tag_disable(struct gb_connection *connection); - -static inline bool gb_connection_e2efc_enabled(struct gb_connection *connection) -{ - return !(connection->flags & GB_CONNECTION_FLAG_CSD); -} - -static inline bool -gb_connection_flow_control_disabled(struct gb_connection *connection) -{ - return connection->flags & GB_CONNECTION_FLAG_NO_FLOWCTRL; -} - -static inline bool gb_connection_is_offloaded(struct gb_connection *connection) -{ - return connection->flags & GB_CONNECTION_FLAG_OFFLOADED; -} - -static inline bool gb_connection_is_control(struct gb_connection *connection) -{ - return connection->flags & GB_CONNECTION_FLAG_CONTROL; -} - -static inline void *gb_connection_get_data(struct gb_connection *connection) -{ - return connection->private; -} - -static inline void gb_connection_set_data(struct gb_connection *connection, - void *data) -{ - connection->private = data; -} - -#endif /* __CONNECTION_H */ diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c deleted file mode 100644 index a9e8b6036cac..000000000000 --- a/drivers/staging/greybus/control.c +++ /dev/null @@ -1,584 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus CPort control protocol. - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include "greybus.h" - -/* Highest control-protocol version supported */ -#define GB_CONTROL_VERSION_MAJOR 0 -#define GB_CONTROL_VERSION_MINOR 1 - -static int gb_control_get_version(struct gb_control *control) -{ - struct gb_interface *intf = control->connection->intf; - struct gb_control_version_request request; - struct gb_control_version_response response; - int ret; - - request.major = GB_CONTROL_VERSION_MAJOR; - request.minor = GB_CONTROL_VERSION_MINOR; - - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_VERSION, - &request, sizeof(request), &response, - sizeof(response)); - if (ret) { - dev_err(&intf->dev, - "failed to get control-protocol version: %d\n", - ret); - return ret; - } - - if (response.major > request.major) { - dev_err(&intf->dev, - "unsupported major control-protocol version (%u > %u)\n", - response.major, request.major); - return -ENOTSUPP; - } - - control->protocol_major = response.major; - control->protocol_minor = response.minor; - - dev_dbg(&intf->dev, "%s - %u.%u\n", __func__, response.major, - response.minor); - - return 0; -} - -static int gb_control_get_bundle_version(struct gb_control *control, - struct gb_bundle *bundle) -{ - struct gb_interface *intf = control->connection->intf; - struct gb_control_bundle_version_request request; - struct gb_control_bundle_version_response response; - int ret; - - request.bundle_id = bundle->id; - - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_BUNDLE_VERSION, - &request, sizeof(request), - &response, sizeof(response)); - if (ret) { - dev_err(&intf->dev, - "failed to get bundle %u class version: %d\n", - bundle->id, ret); - return ret; - } - - bundle->class_major = response.major; - bundle->class_minor = response.minor; - - dev_dbg(&intf->dev, "%s - %u: %u.%u\n", __func__, bundle->id, - response.major, response.minor); - - return 0; -} - -int gb_control_get_bundle_versions(struct gb_control *control) -{ - struct gb_interface *intf = control->connection->intf; - struct gb_bundle *bundle; - int ret; - - if (!control->has_bundle_version) - return 0; - - list_for_each_entry(bundle, &intf->bundles, links) { - ret = gb_control_get_bundle_version(control, bundle); - if (ret) - return ret; - } - - return 0; -} - -/* Get Manifest's size from the interface */ -int gb_control_get_manifest_size_operation(struct gb_interface *intf) -{ - struct gb_control_get_manifest_size_response response; - struct gb_connection *connection = intf->control->connection; - int ret; - - ret = gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST_SIZE, - NULL, 0, &response, sizeof(response)); - if (ret) { - dev_err(&connection->intf->dev, - "failed to get manifest size: %d\n", ret); - return ret; - } - - return le16_to_cpu(response.size); -} - -/* Reads Manifest from the interface */ -int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest, - size_t size) -{ - struct gb_connection *connection = intf->control->connection; - - return gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST, - NULL, 0, manifest, size); -} - -int gb_control_connected_operation(struct gb_control *control, u16 cport_id) -{ - struct gb_control_connected_request request; - - request.cport_id = cpu_to_le16(cport_id); - return gb_operation_sync(control->connection, GB_CONTROL_TYPE_CONNECTED, - &request, sizeof(request), NULL, 0); -} - -int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id) -{ - struct gb_control_disconnected_request request; - - request.cport_id = cpu_to_le16(cport_id); - return gb_operation_sync(control->connection, - GB_CONTROL_TYPE_DISCONNECTED, &request, - sizeof(request), NULL, 0); -} - -int gb_control_disconnecting_operation(struct gb_control *control, - u16 cport_id) -{ - struct gb_control_disconnecting_request *request; - struct gb_operation *operation; - int ret; - - operation = gb_operation_create_core(control->connection, - GB_CONTROL_TYPE_DISCONNECTING, - sizeof(*request), 0, 0, - GFP_KERNEL); - if (!operation) - return -ENOMEM; - - request = operation->request->payload; - request->cport_id = cpu_to_le16(cport_id); - - ret = gb_operation_request_send_sync(operation); - if (ret) { - dev_err(&control->dev, "failed to send disconnecting: %d\n", - ret); - } - - gb_operation_put(operation); - - return ret; -} - -int gb_control_mode_switch_operation(struct gb_control *control) -{ - struct gb_operation *operation; - int ret; - - operation = gb_operation_create_core(control->connection, - GB_CONTROL_TYPE_MODE_SWITCH, - 0, 0, - GB_OPERATION_FLAG_UNIDIRECTIONAL, - GFP_KERNEL); - if (!operation) - return -ENOMEM; - - ret = gb_operation_request_send_sync(operation); - if (ret) - dev_err(&control->dev, "failed to send mode switch: %d\n", ret); - - gb_operation_put(operation); - - return ret; -} - -static int gb_control_bundle_pm_status_map(u8 status) -{ - switch (status) { - case GB_CONTROL_BUNDLE_PM_INVAL: - return -EINVAL; - case GB_CONTROL_BUNDLE_PM_BUSY: - return -EBUSY; - case GB_CONTROL_BUNDLE_PM_NA: - return -ENOMSG; - case GB_CONTROL_BUNDLE_PM_FAIL: - default: - return -EREMOTEIO; - } -} - -int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id) -{ - struct gb_control_bundle_pm_request request; - struct gb_control_bundle_pm_response response; - int ret; - - request.bundle_id = bundle_id; - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_BUNDLE_SUSPEND, &request, - sizeof(request), &response, sizeof(response)); - if (ret) { - dev_err(&control->dev, "failed to send bundle %u suspend: %d\n", - bundle_id, ret); - return ret; - } - - if (response.status != GB_CONTROL_BUNDLE_PM_OK) { - dev_err(&control->dev, "failed to suspend bundle %u: %d\n", - bundle_id, response.status); - return gb_control_bundle_pm_status_map(response.status); - } - - return 0; -} - -int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id) -{ - struct gb_control_bundle_pm_request request; - struct gb_control_bundle_pm_response response; - int ret; - - request.bundle_id = bundle_id; - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_BUNDLE_RESUME, &request, - sizeof(request), &response, sizeof(response)); - if (ret) { - dev_err(&control->dev, "failed to send bundle %u resume: %d\n", - bundle_id, ret); - return ret; - } - - if (response.status != GB_CONTROL_BUNDLE_PM_OK) { - dev_err(&control->dev, "failed to resume bundle %u: %d\n", - bundle_id, response.status); - return gb_control_bundle_pm_status_map(response.status); - } - - return 0; -} - -int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id) -{ - struct gb_control_bundle_pm_request request; - struct gb_control_bundle_pm_response response; - int ret; - - request.bundle_id = bundle_id; - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_BUNDLE_DEACTIVATE, &request, - sizeof(request), &response, sizeof(response)); - if (ret) { - dev_err(&control->dev, - "failed to send bundle %u deactivate: %d\n", bundle_id, - ret); - return ret; - } - - if (response.status != GB_CONTROL_BUNDLE_PM_OK) { - dev_err(&control->dev, "failed to deactivate bundle %u: %d\n", - bundle_id, response.status); - return gb_control_bundle_pm_status_map(response.status); - } - - return 0; -} - -int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id) -{ - struct gb_control_bundle_pm_request request; - struct gb_control_bundle_pm_response response; - int ret; - - if (!control->has_bundle_activate) - return 0; - - request.bundle_id = bundle_id; - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_BUNDLE_ACTIVATE, &request, - sizeof(request), &response, sizeof(response)); - if (ret) { - dev_err(&control->dev, - "failed to send bundle %u activate: %d\n", bundle_id, - ret); - return ret; - } - - if (response.status != GB_CONTROL_BUNDLE_PM_OK) { - dev_err(&control->dev, "failed to activate bundle %u: %d\n", - bundle_id, response.status); - return gb_control_bundle_pm_status_map(response.status); - } - - return 0; -} - -static int gb_control_interface_pm_status_map(u8 status) -{ - switch (status) { - case GB_CONTROL_INTF_PM_BUSY: - return -EBUSY; - case GB_CONTROL_INTF_PM_NA: - return -ENOMSG; - default: - return -EREMOTEIO; - } -} - -int gb_control_interface_suspend_prepare(struct gb_control *control) -{ - struct gb_control_intf_pm_response response; - int ret; - - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE, NULL, 0, - &response, sizeof(response)); - if (ret) { - dev_err(&control->dev, - "failed to send interface suspend prepare: %d\n", ret); - return ret; - } - - if (response.status != GB_CONTROL_INTF_PM_OK) { - dev_err(&control->dev, "interface error while preparing suspend: %d\n", - response.status); - return gb_control_interface_pm_status_map(response.status); - } - - return 0; -} - -int gb_control_interface_deactivate_prepare(struct gb_control *control) -{ - struct gb_control_intf_pm_response response; - int ret; - - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_INTF_DEACTIVATE_PREPARE, NULL, - 0, &response, sizeof(response)); - if (ret) { - dev_err(&control->dev, "failed to send interface deactivate prepare: %d\n", - ret); - return ret; - } - - if (response.status != GB_CONTROL_INTF_PM_OK) { - dev_err(&control->dev, "interface error while preparing deactivate: %d\n", - response.status); - return gb_control_interface_pm_status_map(response.status); - } - - return 0; -} - -int gb_control_interface_hibernate_abort(struct gb_control *control) -{ - struct gb_control_intf_pm_response response; - int ret; - - ret = gb_operation_sync(control->connection, - GB_CONTROL_TYPE_INTF_HIBERNATE_ABORT, NULL, 0, - &response, sizeof(response)); - if (ret) { - dev_err(&control->dev, - "failed to send interface aborting hibernate: %d\n", - ret); - return ret; - } - - if (response.status != GB_CONTROL_INTF_PM_OK) { - dev_err(&control->dev, "interface error while aborting hibernate: %d\n", - response.status); - return gb_control_interface_pm_status_map(response.status); - } - - return 0; -} - -static ssize_t vendor_string_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_control *control = to_gb_control(dev); - - return scnprintf(buf, PAGE_SIZE, "%s\n", control->vendor_string); -} -static DEVICE_ATTR_RO(vendor_string); - -static ssize_t product_string_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_control *control = to_gb_control(dev); - - return scnprintf(buf, PAGE_SIZE, "%s\n", control->product_string); -} -static DEVICE_ATTR_RO(product_string); - -static struct attribute *control_attrs[] = { - &dev_attr_vendor_string.attr, - &dev_attr_product_string.attr, - NULL, -}; -ATTRIBUTE_GROUPS(control); - -static void gb_control_release(struct device *dev) -{ - struct gb_control *control = to_gb_control(dev); - - gb_connection_destroy(control->connection); - - kfree(control->vendor_string); - kfree(control->product_string); - - kfree(control); -} - -struct device_type greybus_control_type = { - .name = "greybus_control", - .release = gb_control_release, -}; - -struct gb_control *gb_control_create(struct gb_interface *intf) -{ - struct gb_connection *connection; - struct gb_control *control; - - control = kzalloc(sizeof(*control), GFP_KERNEL); - if (!control) - return ERR_PTR(-ENOMEM); - - control->intf = intf; - - connection = gb_connection_create_control(intf); - if (IS_ERR(connection)) { - dev_err(&intf->dev, - "failed to create control connection: %ld\n", - PTR_ERR(connection)); - kfree(control); - return ERR_CAST(connection); - } - - control->connection = connection; - - control->dev.parent = &intf->dev; - control->dev.bus = &greybus_bus_type; - control->dev.type = &greybus_control_type; - control->dev.groups = control_groups; - control->dev.dma_mask = intf->dev.dma_mask; - device_initialize(&control->dev); - dev_set_name(&control->dev, "%s.ctrl", dev_name(&intf->dev)); - - gb_connection_set_data(control->connection, control); - - return control; -} - -int gb_control_enable(struct gb_control *control) -{ - int ret; - - dev_dbg(&control->connection->intf->dev, "%s\n", __func__); - - ret = gb_connection_enable_tx(control->connection); - if (ret) { - dev_err(&control->connection->intf->dev, - "failed to enable control connection: %d\n", - ret); - return ret; - } - - ret = gb_control_get_version(control); - if (ret) - goto err_disable_connection; - - if (control->protocol_major > 0 || control->protocol_minor > 1) - control->has_bundle_version = true; - - /* FIXME: use protocol version instead */ - if (!(control->intf->quirks & GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE)) - control->has_bundle_activate = true; - - return 0; - -err_disable_connection: - gb_connection_disable(control->connection); - - return ret; -} - -void gb_control_disable(struct gb_control *control) -{ - dev_dbg(&control->connection->intf->dev, "%s\n", __func__); - - if (control->intf->disconnected) - gb_connection_disable_forced(control->connection); - else - gb_connection_disable(control->connection); -} - -int gb_control_suspend(struct gb_control *control) -{ - gb_connection_disable(control->connection); - - return 0; -} - -int gb_control_resume(struct gb_control *control) -{ - int ret; - - ret = gb_connection_enable_tx(control->connection); - if (ret) { - dev_err(&control->connection->intf->dev, - "failed to enable control connection: %d\n", ret); - return ret; - } - - return 0; -} - -int gb_control_add(struct gb_control *control) -{ - int ret; - - ret = device_add(&control->dev); - if (ret) { - dev_err(&control->dev, - "failed to register control device: %d\n", - ret); - return ret; - } - - return 0; -} - -void gb_control_del(struct gb_control *control) -{ - if (device_is_registered(&control->dev)) - device_del(&control->dev); -} - -struct gb_control *gb_control_get(struct gb_control *control) -{ - get_device(&control->dev); - - return control; -} - -void gb_control_put(struct gb_control *control) -{ - put_device(&control->dev); -} - -void gb_control_mode_switch_prepare(struct gb_control *control) -{ - gb_connection_mode_switch_prepare(control->connection); -} - -void gb_control_mode_switch_complete(struct gb_control *control) -{ - gb_connection_mode_switch_complete(control->connection); -} diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h deleted file mode 100644 index 3a29ec05f631..000000000000 --- a/drivers/staging/greybus/control.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Greybus CPort control protocol - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - */ - -#ifndef __CONTROL_H -#define __CONTROL_H - -struct gb_control { - struct device dev; - struct gb_interface *intf; - - struct gb_connection *connection; - - u8 protocol_major; - u8 protocol_minor; - - bool has_bundle_activate; - bool has_bundle_version; - - char *vendor_string; - char *product_string; -}; -#define to_gb_control(d) container_of(d, struct gb_control, dev) - -struct gb_control *gb_control_create(struct gb_interface *intf); -int gb_control_enable(struct gb_control *control); -void gb_control_disable(struct gb_control *control); -int gb_control_suspend(struct gb_control *control); -int gb_control_resume(struct gb_control *control); -int gb_control_add(struct gb_control *control); -void gb_control_del(struct gb_control *control); -struct gb_control *gb_control_get(struct gb_control *control); -void gb_control_put(struct gb_control *control); - -int gb_control_get_bundle_versions(struct gb_control *control); -int gb_control_connected_operation(struct gb_control *control, u16 cport_id); -int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id); -int gb_control_disconnecting_operation(struct gb_control *control, - u16 cport_id); -int gb_control_mode_switch_operation(struct gb_control *control); -void gb_control_mode_switch_prepare(struct gb_control *control); -void gb_control_mode_switch_complete(struct gb_control *control); -int gb_control_get_manifest_size_operation(struct gb_interface *intf); -int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest, - size_t size); -int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id); -int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id); -int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id); -int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id); -int gb_control_interface_suspend_prepare(struct gb_control *control); -int gb_control_interface_deactivate_prepare(struct gb_control *control); -int gb_control_interface_hibernate_abort(struct gb_control *control); -#endif /* __CONTROL_H */ diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c deleted file mode 100644 index d6b0d49130c0..000000000000 --- a/drivers/staging/greybus/core.c +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus "Core" - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define CREATE_TRACE_POINTS -#include "greybus.h" -#include "greybus_trace.h" - -#define GB_BUNDLE_AUTOSUSPEND_MS 3000 - -/* Allow greybus to be disabled at boot if needed */ -static bool nogreybus; -#ifdef MODULE -module_param(nogreybus, bool, 0444); -#else -core_param(nogreybus, nogreybus, bool, 0444); -#endif -int greybus_disabled(void) -{ - return nogreybus; -} -EXPORT_SYMBOL_GPL(greybus_disabled); - -static bool greybus_match_one_id(struct gb_bundle *bundle, - const struct greybus_bundle_id *id) -{ - if ((id->match_flags & GREYBUS_ID_MATCH_VENDOR) && - (id->vendor != bundle->intf->vendor_id)) - return false; - - if ((id->match_flags & GREYBUS_ID_MATCH_PRODUCT) && - (id->product != bundle->intf->product_id)) - return false; - - if ((id->match_flags & GREYBUS_ID_MATCH_CLASS) && - (id->class != bundle->class)) - return false; - - return true; -} - -static const struct greybus_bundle_id * -greybus_match_id(struct gb_bundle *bundle, const struct greybus_bundle_id *id) -{ - if (!id) - return NULL; - - for (; id->vendor || id->product || id->class || id->driver_info; - id++) { - if (greybus_match_one_id(bundle, id)) - return id; - } - - return NULL; -} - -static int greybus_match_device(struct device *dev, struct device_driver *drv) -{ - struct greybus_driver *driver = to_greybus_driver(drv); - struct gb_bundle *bundle; - const struct greybus_bundle_id *id; - - if (!is_gb_bundle(dev)) - return 0; - - bundle = to_gb_bundle(dev); - - id = greybus_match_id(bundle, driver->id_table); - if (id) - return 1; - /* FIXME - Dynamic ids? */ - return 0; -} - -static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct gb_host_device *hd; - struct gb_module *module = NULL; - struct gb_interface *intf = NULL; - struct gb_control *control = NULL; - struct gb_bundle *bundle = NULL; - struct gb_svc *svc = NULL; - - if (is_gb_host_device(dev)) { - hd = to_gb_host_device(dev); - } else if (is_gb_module(dev)) { - module = to_gb_module(dev); - hd = module->hd; - } else if (is_gb_interface(dev)) { - intf = to_gb_interface(dev); - module = intf->module; - hd = intf->hd; - } else if (is_gb_control(dev)) { - control = to_gb_control(dev); - intf = control->intf; - module = intf->module; - hd = intf->hd; - } else if (is_gb_bundle(dev)) { - bundle = to_gb_bundle(dev); - intf = bundle->intf; - module = intf->module; - hd = intf->hd; - } else if (is_gb_svc(dev)) { - svc = to_gb_svc(dev); - hd = svc->hd; - } else { - dev_WARN(dev, "uevent for unknown greybus device \"type\"!\n"); - return -EINVAL; - } - - if (add_uevent_var(env, "BUS=%u", hd->bus_id)) - return -ENOMEM; - - if (module) { - if (add_uevent_var(env, "MODULE=%u", module->module_id)) - return -ENOMEM; - } - - if (intf) { - if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id)) - return -ENOMEM; - if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x", - intf->vendor_id, intf->product_id)) - return -ENOMEM; - } - - if (bundle) { - // FIXME - // add a uevent that can "load" a bundle type - // This is what we need to bind a driver to so use the info - // in gmod here as well - - if (add_uevent_var(env, "BUNDLE=%u", bundle->id)) - return -ENOMEM; - if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class)) - return -ENOMEM; - } - - return 0; -} - -static void greybus_shutdown(struct device *dev) -{ - if (is_gb_host_device(dev)) { - struct gb_host_device *hd; - - hd = to_gb_host_device(dev); - gb_hd_shutdown(hd); - } -} - -struct bus_type greybus_bus_type = { - .name = "greybus", - .match = greybus_match_device, - .uevent = greybus_uevent, - .shutdown = greybus_shutdown, -}; - -static int greybus_probe(struct device *dev) -{ - struct greybus_driver *driver = to_greybus_driver(dev->driver); - struct gb_bundle *bundle = to_gb_bundle(dev); - const struct greybus_bundle_id *id; - int retval; - - /* match id */ - id = greybus_match_id(bundle, driver->id_table); - if (!id) - return -ENODEV; - - retval = pm_runtime_get_sync(&bundle->intf->dev); - if (retval < 0) { - pm_runtime_put_noidle(&bundle->intf->dev); - return retval; - } - - retval = gb_control_bundle_activate(bundle->intf->control, bundle->id); - if (retval) { - pm_runtime_put(&bundle->intf->dev); - return retval; - } - - /* - * Unbound bundle devices are always deactivated. During probe, the - * Runtime PM is set to enabled and active and the usage count is - * incremented. If the driver supports runtime PM, it should call - * pm_runtime_put() in its probe routine and pm_runtime_get_sync() - * in remove routine. - */ - pm_runtime_set_autosuspend_delay(dev, GB_BUNDLE_AUTOSUSPEND_MS); - pm_runtime_use_autosuspend(dev); - pm_runtime_get_noresume(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - retval = driver->probe(bundle, id); - if (retval) { - /* - * Catch buggy drivers that fail to destroy their connections. - */ - WARN_ON(!list_empty(&bundle->connections)); - - gb_control_bundle_deactivate(bundle->intf->control, bundle->id); - - pm_runtime_disable(dev); - pm_runtime_set_suspended(dev); - pm_runtime_put_noidle(dev); - pm_runtime_dont_use_autosuspend(dev); - pm_runtime_put(&bundle->intf->dev); - - return retval; - } - - pm_runtime_put(&bundle->intf->dev); - - return 0; -} - -static int greybus_remove(struct device *dev) -{ - struct greybus_driver *driver = to_greybus_driver(dev->driver); - struct gb_bundle *bundle = to_gb_bundle(dev); - struct gb_connection *connection; - int retval; - - retval = pm_runtime_get_sync(dev); - if (retval < 0) - dev_err(dev, "failed to resume bundle: %d\n", retval); - - /* - * Disable (non-offloaded) connections early in case the interface is - * already gone to avoid unceccessary operation timeouts during - * driver disconnect. Otherwise, only disable incoming requests. - */ - list_for_each_entry(connection, &bundle->connections, bundle_links) { - if (gb_connection_is_offloaded(connection)) - continue; - - if (bundle->intf->disconnected) - gb_connection_disable_forced(connection); - else - gb_connection_disable_rx(connection); - } - - driver->disconnect(bundle); - - /* Catch buggy drivers that fail to destroy their connections. */ - WARN_ON(!list_empty(&bundle->connections)); - - if (!bundle->intf->disconnected) - gb_control_bundle_deactivate(bundle->intf->control, bundle->id); - - pm_runtime_put_noidle(dev); - pm_runtime_disable(dev); - pm_runtime_set_suspended(dev); - pm_runtime_dont_use_autosuspend(dev); - pm_runtime_put_noidle(dev); - - return 0; -} - -int greybus_register_driver(struct greybus_driver *driver, struct module *owner, - const char *mod_name) -{ - int retval; - - if (greybus_disabled()) - return -ENODEV; - - driver->driver.bus = &greybus_bus_type; - driver->driver.name = driver->name; - driver->driver.probe = greybus_probe; - driver->driver.remove = greybus_remove; - driver->driver.owner = owner; - driver->driver.mod_name = mod_name; - - retval = driver_register(&driver->driver); - if (retval) - return retval; - - pr_info("registered new driver %s\n", driver->name); - return 0; -} -EXPORT_SYMBOL_GPL(greybus_register_driver); - -void greybus_deregister_driver(struct greybus_driver *driver) -{ - driver_unregister(&driver->driver); -} -EXPORT_SYMBOL_GPL(greybus_deregister_driver); - -static int __init gb_init(void) -{ - int retval; - - if (greybus_disabled()) - return -ENODEV; - - BUILD_BUG_ON(CPORT_ID_MAX >= (long)CPORT_ID_BAD); - - gb_debugfs_init(); - - retval = bus_register(&greybus_bus_type); - if (retval) { - pr_err("bus_register failed (%d)\n", retval); - goto error_bus; - } - - retval = gb_hd_init(); - if (retval) { - pr_err("gb_hd_init failed (%d)\n", retval); - goto error_hd; - } - - retval = gb_operation_init(); - if (retval) { - pr_err("gb_operation_init failed (%d)\n", retval); - goto error_operation; - } - return 0; /* Success */ - -error_operation: - gb_hd_exit(); -error_hd: - bus_unregister(&greybus_bus_type); -error_bus: - gb_debugfs_cleanup(); - - return retval; -} -module_init(gb_init); - -static void __exit gb_exit(void) -{ - gb_operation_exit(); - gb_hd_exit(); - bus_unregister(&greybus_bus_type); - gb_debugfs_cleanup(); - tracepoint_synchronize_unregister(); -} -module_exit(gb_exit); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>"); diff --git a/drivers/staging/greybus/debugfs.c b/drivers/staging/greybus/debugfs.c deleted file mode 100644 index 56e20c30feb5..000000000000 --- a/drivers/staging/greybus/debugfs.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus debugfs code - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#include <linux/debugfs.h> - -#include "greybus.h" - -static struct dentry *gb_debug_root; - -void __init gb_debugfs_init(void) -{ - gb_debug_root = debugfs_create_dir("greybus", NULL); -} - -void gb_debugfs_cleanup(void) -{ - debugfs_remove_recursive(gb_debug_root); - gb_debug_root = NULL; -} - -struct dentry *gb_debugfs_get(void) -{ - return gb_debug_root; -} -EXPORT_SYMBOL_GPL(gb_debugfs_get); diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c deleted file mode 100644 index be6af18cec31..000000000000 --- a/drivers/staging/greybus/es2.c +++ /dev/null @@ -1,1466 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus "AP" USB driver for "ES2" controller chips - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ -#include <linux/kthread.h> -#include <linux/sizes.h> -#include <linux/usb.h> -#include <linux/kfifo.h> -#include <linux/debugfs.h> -#include <linux/list.h> -#include <asm/unaligned.h> - -#include "arpc.h" -#include "greybus.h" -#include "greybus_trace.h" -#include "connection.h" - - -/* Default timeout for USB vendor requests. */ -#define ES2_USB_CTRL_TIMEOUT 500 - -/* Default timeout for ARPC CPort requests */ -#define ES2_ARPC_CPORT_TIMEOUT 500 - -/* Fixed CPort numbers */ -#define ES2_CPORT_CDSI0 16 -#define ES2_CPORT_CDSI1 17 - -/* Memory sizes for the buffers sent to/from the ES2 controller */ -#define ES2_GBUF_MSG_SIZE_MAX 2048 - -/* Memory sizes for the ARPC buffers */ -#define ARPC_OUT_SIZE_MAX U16_MAX -#define ARPC_IN_SIZE_MAX 128 - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x18d1, 0x1eaf) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -#define APB1_LOG_SIZE SZ_16K - -/* - * Number of CPort IN urbs in flight at any point in time. - * Adjust if we are having stalls in the USB buffer due to not enough urbs in - * flight. - */ -#define NUM_CPORT_IN_URB 4 - -/* Number of CPort OUT urbs in flight at any point in time. - * Adjust if we get messages saying we are out of urbs in the system log. - */ -#define NUM_CPORT_OUT_URB 8 - -/* - * Number of ARPC in urbs in flight at any point in time. - */ -#define NUM_ARPC_IN_URB 2 - -/* - * @endpoint: bulk in endpoint for CPort data - * @urb: array of urbs for the CPort in messages - * @buffer: array of buffers for the @cport_in_urb urbs - */ -struct es2_cport_in { - __u8 endpoint; - struct urb *urb[NUM_CPORT_IN_URB]; - u8 *buffer[NUM_CPORT_IN_URB]; -}; - -/** - * es2_ap_dev - ES2 USB Bridge to AP structure - * @usb_dev: pointer to the USB device we are. - * @usb_intf: pointer to the USB interface we are bound to. - * @hd: pointer to our gb_host_device structure - - * @cport_in: endpoint, urbs and buffer for cport in messages - * @cport_out_endpoint: endpoint for for cport out messages - * @cport_out_urb: array of urbs for the CPort out messages - * @cport_out_urb_busy: array of flags to see if the @cport_out_urb is busy or - * not. - * @cport_out_urb_cancelled: array of flags indicating whether the - * corresponding @cport_out_urb is being cancelled - * @cport_out_urb_lock: locks the @cport_out_urb_busy "list" - * - * @apb_log_task: task pointer for logging thread - * @apb_log_dentry: file system entry for the log file interface - * @apb_log_enable_dentry: file system entry for enabling logging - * @apb_log_fifo: kernel FIFO to carry logged data - * @arpc_urb: array of urbs for the ARPC in messages - * @arpc_buffer: array of buffers for the @arpc_urb urbs - * @arpc_endpoint_in: bulk in endpoint for APBridgeA RPC - * @arpc_id_cycle: gives an unique id to ARPC - * @arpc_lock: locks ARPC list - * @arpcs: list of in progress ARPCs - */ -struct es2_ap_dev { - struct usb_device *usb_dev; - struct usb_interface *usb_intf; - struct gb_host_device *hd; - - struct es2_cport_in cport_in; - __u8 cport_out_endpoint; - struct urb *cport_out_urb[NUM_CPORT_OUT_URB]; - bool cport_out_urb_busy[NUM_CPORT_OUT_URB]; - bool cport_out_urb_cancelled[NUM_CPORT_OUT_URB]; - spinlock_t cport_out_urb_lock; - - bool cdsi1_in_use; - - struct task_struct *apb_log_task; - struct dentry *apb_log_dentry; - struct dentry *apb_log_enable_dentry; - DECLARE_KFIFO(apb_log_fifo, char, APB1_LOG_SIZE); - - __u8 arpc_endpoint_in; - struct urb *arpc_urb[NUM_ARPC_IN_URB]; - u8 *arpc_buffer[NUM_ARPC_IN_URB]; - - int arpc_id_cycle; - spinlock_t arpc_lock; - struct list_head arpcs; -}; - -struct arpc { - struct list_head list; - struct arpc_request_message *req; - struct arpc_response_message *resp; - struct completion response_received; - bool active; -}; - -static inline struct es2_ap_dev *hd_to_es2(struct gb_host_device *hd) -{ - return (struct es2_ap_dev *)&hd->hd_priv; -} - -static void cport_out_callback(struct urb *urb); -static void usb_log_enable(struct es2_ap_dev *es2); -static void usb_log_disable(struct es2_ap_dev *es2); -static int arpc_sync(struct es2_ap_dev *es2, u8 type, void *payload, - size_t size, int *result, unsigned int timeout); - -static int output_sync(struct es2_ap_dev *es2, void *req, u16 size, u8 cmd) -{ - struct usb_device *udev = es2->usb_dev; - u8 *data; - int retval; - - data = kmemdup(req, size, GFP_KERNEL); - if (!data) - return -ENOMEM; - - retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - cmd, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, - 0, 0, data, size, ES2_USB_CTRL_TIMEOUT); - if (retval < 0) - dev_err(&udev->dev, "%s: return error %d\n", __func__, retval); - else - retval = 0; - - kfree(data); - return retval; -} - -static void ap_urb_complete(struct urb *urb) -{ - struct usb_ctrlrequest *dr = urb->context; - - kfree(dr); - usb_free_urb(urb); -} - -static int output_async(struct es2_ap_dev *es2, void *req, u16 size, u8 cmd) -{ - struct usb_device *udev = es2->usb_dev; - struct urb *urb; - struct usb_ctrlrequest *dr; - u8 *buf; - int retval; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - dr = kmalloc(sizeof(*dr) + size, GFP_ATOMIC); - if (!dr) { - usb_free_urb(urb); - return -ENOMEM; - } - - buf = (u8 *)dr + sizeof(*dr); - memcpy(buf, req, size); - - dr->bRequest = cmd; - dr->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE; - dr->wValue = 0; - dr->wIndex = 0; - dr->wLength = cpu_to_le16(size); - - usb_fill_control_urb(urb, udev, usb_sndctrlpipe(udev, 0), - (unsigned char *)dr, buf, size, - ap_urb_complete, dr); - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) { - usb_free_urb(urb); - kfree(dr); - } - return retval; -} - -static int output(struct gb_host_device *hd, void *req, u16 size, u8 cmd, - bool async) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - - if (async) - return output_async(es2, req, size, cmd); - - return output_sync(es2, req, size, cmd); -} - -static int es2_cport_in_enable(struct es2_ap_dev *es2, - struct es2_cport_in *cport_in) -{ - struct urb *urb; - int ret; - int i; - - for (i = 0; i < NUM_CPORT_IN_URB; ++i) { - urb = cport_in->urb[i]; - - ret = usb_submit_urb(urb, GFP_KERNEL); - if (ret) { - dev_err(&es2->usb_dev->dev, - "failed to submit in-urb: %d\n", ret); - goto err_kill_urbs; - } - } - - return 0; - -err_kill_urbs: - for (--i; i >= 0; --i) { - urb = cport_in->urb[i]; - usb_kill_urb(urb); - } - - return ret; -} - -static void es2_cport_in_disable(struct es2_ap_dev *es2, - struct es2_cport_in *cport_in) -{ - struct urb *urb; - int i; - - for (i = 0; i < NUM_CPORT_IN_URB; ++i) { - urb = cport_in->urb[i]; - usb_kill_urb(urb); - } -} - -static int es2_arpc_in_enable(struct es2_ap_dev *es2) -{ - struct urb *urb; - int ret; - int i; - - for (i = 0; i < NUM_ARPC_IN_URB; ++i) { - urb = es2->arpc_urb[i]; - - ret = usb_submit_urb(urb, GFP_KERNEL); - if (ret) { - dev_err(&es2->usb_dev->dev, - "failed to submit arpc in-urb: %d\n", ret); - goto err_kill_urbs; - } - } - - return 0; - -err_kill_urbs: - for (--i; i >= 0; --i) { - urb = es2->arpc_urb[i]; - usb_kill_urb(urb); - } - - return ret; -} - -static void es2_arpc_in_disable(struct es2_ap_dev *es2) -{ - struct urb *urb; - int i; - - for (i = 0; i < NUM_ARPC_IN_URB; ++i) { - urb = es2->arpc_urb[i]; - usb_kill_urb(urb); - } -} - -static struct urb *next_free_urb(struct es2_ap_dev *es2, gfp_t gfp_mask) -{ - struct urb *urb = NULL; - unsigned long flags; - int i; - - spin_lock_irqsave(&es2->cport_out_urb_lock, flags); - - /* Look in our pool of allocated urbs first, as that's the "fastest" */ - for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { - if (!es2->cport_out_urb_busy[i] && - !es2->cport_out_urb_cancelled[i]) { - es2->cport_out_urb_busy[i] = true; - urb = es2->cport_out_urb[i]; - break; - } - } - spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags); - if (urb) - return urb; - - /* - * Crap, pool is empty, complain to the syslog and go allocate one - * dynamically as we have to succeed. - */ - dev_dbg(&es2->usb_dev->dev, - "No free CPort OUT urbs, having to dynamically allocate one!\n"); - return usb_alloc_urb(0, gfp_mask); -} - -static void free_urb(struct es2_ap_dev *es2, struct urb *urb) -{ - unsigned long flags; - int i; - /* - * See if this was an urb in our pool, if so mark it "free", otherwise - * we need to free it ourselves. - */ - spin_lock_irqsave(&es2->cport_out_urb_lock, flags); - for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { - if (urb == es2->cport_out_urb[i]) { - es2->cport_out_urb_busy[i] = false; - urb = NULL; - break; - } - } - spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags); - - /* If urb is not NULL, then we need to free this urb */ - usb_free_urb(urb); -} - -/* - * We (ab)use the operation-message header pad bytes to transfer the - * cport id in order to minimise overhead. - */ -static void -gb_message_cport_pack(struct gb_operation_msg_hdr *header, u16 cport_id) -{ - header->pad[0] = cport_id; -} - -/* Clear the pad bytes used for the CPort id */ -static void gb_message_cport_clear(struct gb_operation_msg_hdr *header) -{ - header->pad[0] = 0; -} - -/* Extract the CPort id packed into the header, and clear it */ -static u16 gb_message_cport_unpack(struct gb_operation_msg_hdr *header) -{ - u16 cport_id = header->pad[0]; - - gb_message_cport_clear(header); - - return cport_id; -} - -/* - * Returns zero if the message was successfully queued, or a negative errno - * otherwise. - */ -static int message_send(struct gb_host_device *hd, u16 cport_id, - struct gb_message *message, gfp_t gfp_mask) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - size_t buffer_size; - int retval; - struct urb *urb; - unsigned long flags; - - /* - * The data actually transferred will include an indication - * of where the data should be sent. Do one last check of - * the target CPort id before filling it in. - */ - if (!cport_id_valid(hd, cport_id)) { - dev_err(&udev->dev, "invalid cport %u\n", cport_id); - return -EINVAL; - } - - /* Find a free urb */ - urb = next_free_urb(es2, gfp_mask); - if (!urb) - return -ENOMEM; - - spin_lock_irqsave(&es2->cport_out_urb_lock, flags); - message->hcpriv = urb; - spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags); - - /* Pack the cport id into the message header */ - gb_message_cport_pack(message->header, cport_id); - - buffer_size = sizeof(*message->header) + message->payload_size; - - usb_fill_bulk_urb(urb, udev, - usb_sndbulkpipe(udev, - es2->cport_out_endpoint), - message->buffer, buffer_size, - cport_out_callback, message); - urb->transfer_flags |= URB_ZERO_PACKET; - - trace_gb_message_submit(message); - - retval = usb_submit_urb(urb, gfp_mask); - if (retval) { - dev_err(&udev->dev, "failed to submit out-urb: %d\n", retval); - - spin_lock_irqsave(&es2->cport_out_urb_lock, flags); - message->hcpriv = NULL; - spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags); - - free_urb(es2, urb); - gb_message_cport_clear(message->header); - - return retval; - } - - return 0; -} - -/* - * Can not be called in atomic context. - */ -static void message_cancel(struct gb_message *message) -{ - struct gb_host_device *hd = message->operation->connection->hd; - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct urb *urb; - int i; - - might_sleep(); - - spin_lock_irq(&es2->cport_out_urb_lock); - urb = message->hcpriv; - - /* Prevent dynamically allocated urb from being deallocated. */ - usb_get_urb(urb); - - /* Prevent pre-allocated urb from being reused. */ - for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { - if (urb == es2->cport_out_urb[i]) { - es2->cport_out_urb_cancelled[i] = true; - break; - } - } - spin_unlock_irq(&es2->cport_out_urb_lock); - - usb_kill_urb(urb); - - if (i < NUM_CPORT_OUT_URB) { - spin_lock_irq(&es2->cport_out_urb_lock); - es2->cport_out_urb_cancelled[i] = false; - spin_unlock_irq(&es2->cport_out_urb_lock); - } - - usb_free_urb(urb); -} - -static int es2_cport_allocate(struct gb_host_device *hd, int cport_id, - unsigned long flags) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct ida *id_map = &hd->cport_id_map; - int ida_start, ida_end; - - switch (cport_id) { - case ES2_CPORT_CDSI0: - case ES2_CPORT_CDSI1: - dev_err(&hd->dev, "cport %d not available\n", cport_id); - return -EBUSY; - } - - if (flags & GB_CONNECTION_FLAG_OFFLOADED && - flags & GB_CONNECTION_FLAG_CDSI1) { - if (es2->cdsi1_in_use) { - dev_err(&hd->dev, "CDSI1 already in use\n"); - return -EBUSY; - } - - es2->cdsi1_in_use = true; - - return ES2_CPORT_CDSI1; - } - - if (cport_id < 0) { - ida_start = 0; - ida_end = hd->num_cports; - } else if (cport_id < hd->num_cports) { - ida_start = cport_id; - ida_end = cport_id + 1; - } else { - dev_err(&hd->dev, "cport %d not available\n", cport_id); - return -EINVAL; - } - - return ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL); -} - -static void es2_cport_release(struct gb_host_device *hd, u16 cport_id) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - - switch (cport_id) { - case ES2_CPORT_CDSI1: - es2->cdsi1_in_use = false; - return; - } - - ida_simple_remove(&hd->cport_id_map, cport_id); -} - -static int cport_enable(struct gb_host_device *hd, u16 cport_id, - unsigned long flags) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - struct gb_apb_request_cport_flags *req; - u32 connection_flags; - int ret; - - req = kzalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return -ENOMEM; - - connection_flags = 0; - if (flags & GB_CONNECTION_FLAG_CONTROL) - connection_flags |= GB_APB_CPORT_FLAG_CONTROL; - if (flags & GB_CONNECTION_FLAG_HIGH_PRIO) - connection_flags |= GB_APB_CPORT_FLAG_HIGH_PRIO; - - req->flags = cpu_to_le32(connection_flags); - - dev_dbg(&hd->dev, "%s - cport = %u, flags = %02x\n", __func__, - cport_id, connection_flags); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - GB_APB_REQUEST_CPORT_FLAGS, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, cport_id, 0, - req, sizeof(*req), ES2_USB_CTRL_TIMEOUT); - if (ret != sizeof(*req)) { - dev_err(&udev->dev, "failed to set cport flags for port %d\n", - cport_id); - if (ret >= 0) - ret = -EIO; - - goto out; - } - - ret = 0; -out: - kfree(req); - - return ret; -} - -static int es2_cport_connected(struct gb_host_device *hd, u16 cport_id) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct device *dev = &es2->usb_dev->dev; - struct arpc_cport_connected_req req; - int ret; - - req.cport_id = cpu_to_le16(cport_id); - ret = arpc_sync(es2, ARPC_TYPE_CPORT_CONNECTED, &req, sizeof(req), - NULL, ES2_ARPC_CPORT_TIMEOUT); - if (ret) { - dev_err(dev, "failed to set connected state for cport %u: %d\n", - cport_id, ret); - return ret; - } - - return 0; -} - -static int es2_cport_flush(struct gb_host_device *hd, u16 cport_id) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct device *dev = &es2->usb_dev->dev; - struct arpc_cport_flush_req req; - int ret; - - req.cport_id = cpu_to_le16(cport_id); - ret = arpc_sync(es2, ARPC_TYPE_CPORT_FLUSH, &req, sizeof(req), - NULL, ES2_ARPC_CPORT_TIMEOUT); - if (ret) { - dev_err(dev, "failed to flush cport %u: %d\n", cport_id, ret); - return ret; - } - - return 0; -} - -static int es2_cport_shutdown(struct gb_host_device *hd, u16 cport_id, - u8 phase, unsigned int timeout) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct device *dev = &es2->usb_dev->dev; - struct arpc_cport_shutdown_req req; - int result; - int ret; - - if (timeout > U16_MAX) - return -EINVAL; - - req.cport_id = cpu_to_le16(cport_id); - req.timeout = cpu_to_le16(timeout); - req.phase = phase; - ret = arpc_sync(es2, ARPC_TYPE_CPORT_SHUTDOWN, &req, sizeof(req), - &result, ES2_ARPC_CPORT_TIMEOUT + timeout); - if (ret) { - dev_err(dev, "failed to send shutdown over cport %u: %d (%d)\n", - cport_id, ret, result); - return ret; - } - - return 0; -} - -static int es2_cport_quiesce(struct gb_host_device *hd, u16 cport_id, - size_t peer_space, unsigned int timeout) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct device *dev = &es2->usb_dev->dev; - struct arpc_cport_quiesce_req req; - int result; - int ret; - - if (peer_space > U16_MAX) - return -EINVAL; - - if (timeout > U16_MAX) - return -EINVAL; - - req.cport_id = cpu_to_le16(cport_id); - req.peer_space = cpu_to_le16(peer_space); - req.timeout = cpu_to_le16(timeout); - ret = arpc_sync(es2, ARPC_TYPE_CPORT_QUIESCE, &req, sizeof(req), - &result, ES2_ARPC_CPORT_TIMEOUT + timeout); - if (ret) { - dev_err(dev, "failed to quiesce cport %u: %d (%d)\n", - cport_id, ret, result); - return ret; - } - - return 0; -} - -static int es2_cport_clear(struct gb_host_device *hd, u16 cport_id) -{ - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct device *dev = &es2->usb_dev->dev; - struct arpc_cport_clear_req req; - int ret; - - req.cport_id = cpu_to_le16(cport_id); - ret = arpc_sync(es2, ARPC_TYPE_CPORT_CLEAR, &req, sizeof(req), - NULL, ES2_ARPC_CPORT_TIMEOUT); - if (ret) { - dev_err(dev, "failed to clear cport %u: %d\n", cport_id, ret); - return ret; - } - - return 0; -} - -static int latency_tag_enable(struct gb_host_device *hd, u16 cport_id) -{ - int retval; - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - - retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - GB_APB_REQUEST_LATENCY_TAG_EN, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, cport_id, 0, NULL, - 0, ES2_USB_CTRL_TIMEOUT); - - if (retval < 0) - dev_err(&udev->dev, "Cannot enable latency tag for cport %d\n", - cport_id); - return retval; -} - -static int latency_tag_disable(struct gb_host_device *hd, u16 cport_id) -{ - int retval; - struct es2_ap_dev *es2 = hd_to_es2(hd); - struct usb_device *udev = es2->usb_dev; - - retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - GB_APB_REQUEST_LATENCY_TAG_DIS, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, cport_id, 0, NULL, - 0, ES2_USB_CTRL_TIMEOUT); - - if (retval < 0) - dev_err(&udev->dev, "Cannot disable latency tag for cport %d\n", - cport_id); - return retval; -} - -static struct gb_hd_driver es2_driver = { - .hd_priv_size = sizeof(struct es2_ap_dev), - .message_send = message_send, - .message_cancel = message_cancel, - .cport_allocate = es2_cport_allocate, - .cport_release = es2_cport_release, - .cport_enable = cport_enable, - .cport_connected = es2_cport_connected, - .cport_flush = es2_cport_flush, - .cport_shutdown = es2_cport_shutdown, - .cport_quiesce = es2_cport_quiesce, - .cport_clear = es2_cport_clear, - .latency_tag_enable = latency_tag_enable, - .latency_tag_disable = latency_tag_disable, - .output = output, -}; - -/* Common function to report consistent warnings based on URB status */ -static int check_urb_status(struct urb *urb) -{ - struct device *dev = &urb->dev->dev; - int status = urb->status; - - switch (status) { - case 0: - return 0; - - case -EOVERFLOW: - dev_err(dev, "%s: overflow actual length is %d\n", - __func__, urb->actual_length); - /* fall through */ - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -EILSEQ: - case -EPROTO: - /* device is gone, stop sending */ - return status; - } - dev_err(dev, "%s: unknown status %d\n", __func__, status); - - return -EAGAIN; -} - -static void es2_destroy(struct es2_ap_dev *es2) -{ - struct usb_device *udev; - struct urb *urb; - int i; - - debugfs_remove(es2->apb_log_enable_dentry); - usb_log_disable(es2); - - /* Tear down everything! */ - for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { - urb = es2->cport_out_urb[i]; - usb_kill_urb(urb); - usb_free_urb(urb); - es2->cport_out_urb[i] = NULL; - es2->cport_out_urb_busy[i] = false; /* just to be anal */ - } - - for (i = 0; i < NUM_ARPC_IN_URB; ++i) { - usb_free_urb(es2->arpc_urb[i]); - kfree(es2->arpc_buffer[i]); - es2->arpc_buffer[i] = NULL; - } - - for (i = 0; i < NUM_CPORT_IN_URB; ++i) { - usb_free_urb(es2->cport_in.urb[i]); - kfree(es2->cport_in.buffer[i]); - es2->cport_in.buffer[i] = NULL; - } - - /* release reserved CDSI0 and CDSI1 cports */ - gb_hd_cport_release_reserved(es2->hd, ES2_CPORT_CDSI1); - gb_hd_cport_release_reserved(es2->hd, ES2_CPORT_CDSI0); - - udev = es2->usb_dev; - gb_hd_put(es2->hd); - - usb_put_dev(udev); -} - -static void cport_in_callback(struct urb *urb) -{ - struct gb_host_device *hd = urb->context; - struct device *dev = &urb->dev->dev; - struct gb_operation_msg_hdr *header; - int status = check_urb_status(urb); - int retval; - u16 cport_id; - - if (status) { - if ((status == -EAGAIN) || (status == -EPROTO)) - goto exit; - - /* The urb is being unlinked */ - if (status == -ENOENT || status == -ESHUTDOWN) - return; - - dev_err(dev, "urb cport in error %d (dropped)\n", status); - return; - } - - if (urb->actual_length < sizeof(*header)) { - dev_err(dev, "short message received\n"); - goto exit; - } - - /* Extract the CPort id, which is packed in the message header */ - header = urb->transfer_buffer; - cport_id = gb_message_cport_unpack(header); - - if (cport_id_valid(hd, cport_id)) { - greybus_data_rcvd(hd, cport_id, urb->transfer_buffer, - urb->actual_length); - } else { - dev_err(dev, "invalid cport id %u received\n", cport_id); - } -exit: - /* put our urb back in the request pool */ - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(dev, "failed to resubmit in-urb: %d\n", retval); -} - -static void cport_out_callback(struct urb *urb) -{ - struct gb_message *message = urb->context; - struct gb_host_device *hd = message->operation->connection->hd; - struct es2_ap_dev *es2 = hd_to_es2(hd); - int status = check_urb_status(urb); - unsigned long flags; - - gb_message_cport_clear(message->header); - - spin_lock_irqsave(&es2->cport_out_urb_lock, flags); - message->hcpriv = NULL; - spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags); - - /* - * Tell the submitter that the message send (attempt) is - * complete, and report the status. - */ - greybus_message_sent(hd, message, status); - - free_urb(es2, urb); -} - -static struct arpc *arpc_alloc(void *payload, u16 size, u8 type) -{ - struct arpc *rpc; - - if (size + sizeof(*rpc->req) > ARPC_OUT_SIZE_MAX) - return NULL; - - rpc = kzalloc(sizeof(*rpc), GFP_KERNEL); - if (!rpc) - return NULL; - - INIT_LIST_HEAD(&rpc->list); - rpc->req = kzalloc(sizeof(*rpc->req) + size, GFP_KERNEL); - if (!rpc->req) - goto err_free_rpc; - - rpc->resp = kzalloc(sizeof(*rpc->resp), GFP_KERNEL); - if (!rpc->resp) - goto err_free_req; - - rpc->req->type = type; - rpc->req->size = cpu_to_le16(sizeof(*rpc->req) + size); - memcpy(rpc->req->data, payload, size); - - init_completion(&rpc->response_received); - - return rpc; - -err_free_req: - kfree(rpc->req); -err_free_rpc: - kfree(rpc); - - return NULL; -} - -static void arpc_free(struct arpc *rpc) -{ - kfree(rpc->req); - kfree(rpc->resp); - kfree(rpc); -} - -static struct arpc *arpc_find(struct es2_ap_dev *es2, __le16 id) -{ - struct arpc *rpc; - - list_for_each_entry(rpc, &es2->arpcs, list) { - if (rpc->req->id == id) - return rpc; - } - - return NULL; -} - -static void arpc_add(struct es2_ap_dev *es2, struct arpc *rpc) -{ - rpc->active = true; - rpc->req->id = cpu_to_le16(es2->arpc_id_cycle++); - list_add_tail(&rpc->list, &es2->arpcs); -} - -static void arpc_del(struct es2_ap_dev *es2, struct arpc *rpc) -{ - if (rpc->active) { - rpc->active = false; - list_del(&rpc->list); - } -} - -static int arpc_send(struct es2_ap_dev *es2, struct arpc *rpc, int timeout) -{ - struct usb_device *udev = es2->usb_dev; - int retval; - - retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - GB_APB_REQUEST_ARPC_RUN, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, - 0, 0, - rpc->req, le16_to_cpu(rpc->req->size), - ES2_USB_CTRL_TIMEOUT); - if (retval != le16_to_cpu(rpc->req->size)) { - dev_err(&udev->dev, - "failed to send ARPC request %d: %d\n", - rpc->req->type, retval); - if (retval > 0) - retval = -EIO; - return retval; - } - - return 0; -} - -static int arpc_sync(struct es2_ap_dev *es2, u8 type, void *payload, - size_t size, int *result, unsigned int timeout) -{ - struct arpc *rpc; - unsigned long flags; - int retval; - - if (result) - *result = 0; - - rpc = arpc_alloc(payload, size, type); - if (!rpc) - return -ENOMEM; - - spin_lock_irqsave(&es2->arpc_lock, flags); - arpc_add(es2, rpc); - spin_unlock_irqrestore(&es2->arpc_lock, flags); - - retval = arpc_send(es2, rpc, timeout); - if (retval) - goto out_arpc_del; - - retval = wait_for_completion_interruptible_timeout( - &rpc->response_received, - msecs_to_jiffies(timeout)); - if (retval <= 0) { - if (!retval) - retval = -ETIMEDOUT; - goto out_arpc_del; - } - - if (rpc->resp->result) { - retval = -EREMOTEIO; - if (result) - *result = rpc->resp->result; - } else { - retval = 0; - } - -out_arpc_del: - spin_lock_irqsave(&es2->arpc_lock, flags); - arpc_del(es2, rpc); - spin_unlock_irqrestore(&es2->arpc_lock, flags); - arpc_free(rpc); - - if (retval < 0 && retval != -EREMOTEIO) { - dev_err(&es2->usb_dev->dev, - "failed to execute ARPC: %d\n", retval); - } - - return retval; -} - -static void arpc_in_callback(struct urb *urb) -{ - struct es2_ap_dev *es2 = urb->context; - struct device *dev = &urb->dev->dev; - int status = check_urb_status(urb); - struct arpc *rpc; - struct arpc_response_message *resp; - unsigned long flags; - int retval; - - if (status) { - if ((status == -EAGAIN) || (status == -EPROTO)) - goto exit; - - /* The urb is being unlinked */ - if (status == -ENOENT || status == -ESHUTDOWN) - return; - - dev_err(dev, "arpc in-urb error %d (dropped)\n", status); - return; - } - - if (urb->actual_length < sizeof(*resp)) { - dev_err(dev, "short aprc response received\n"); - goto exit; - } - - resp = urb->transfer_buffer; - spin_lock_irqsave(&es2->arpc_lock, flags); - rpc = arpc_find(es2, resp->id); - if (!rpc) { - dev_err(dev, "invalid arpc response id received: %u\n", - le16_to_cpu(resp->id)); - spin_unlock_irqrestore(&es2->arpc_lock, flags); - goto exit; - } - - arpc_del(es2, rpc); - memcpy(rpc->resp, resp, sizeof(*resp)); - complete(&rpc->response_received); - spin_unlock_irqrestore(&es2->arpc_lock, flags); - -exit: - /* put our urb back in the request pool */ - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(dev, "failed to resubmit arpc in-urb: %d\n", retval); -} - -#define APB1_LOG_MSG_SIZE 64 -static void apb_log_get(struct es2_ap_dev *es2, char *buf) -{ - int retval; - - do { - retval = usb_control_msg(es2->usb_dev, - usb_rcvctrlpipe(es2->usb_dev, 0), - GB_APB_REQUEST_LOG, - USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, - 0x00, 0x00, - buf, - APB1_LOG_MSG_SIZE, - ES2_USB_CTRL_TIMEOUT); - if (retval > 0) - kfifo_in(&es2->apb_log_fifo, buf, retval); - } while (retval > 0); -} - -static int apb_log_poll(void *data) -{ - struct es2_ap_dev *es2 = data; - char *buf; - - buf = kmalloc(APB1_LOG_MSG_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - while (!kthread_should_stop()) { - msleep(1000); - apb_log_get(es2, buf); - } - - kfree(buf); - - return 0; -} - -static ssize_t apb_log_read(struct file *f, char __user *buf, - size_t count, loff_t *ppos) -{ - struct es2_ap_dev *es2 = file_inode(f)->i_private; - ssize_t ret; - size_t copied; - char *tmp_buf; - - if (count > APB1_LOG_SIZE) - count = APB1_LOG_SIZE; - - tmp_buf = kmalloc(count, GFP_KERNEL); - if (!tmp_buf) - return -ENOMEM; - - copied = kfifo_out(&es2->apb_log_fifo, tmp_buf, count); - ret = simple_read_from_buffer(buf, count, ppos, tmp_buf, copied); - - kfree(tmp_buf); - - return ret; -} - -static const struct file_operations apb_log_fops = { - .read = apb_log_read, -}; - -static void usb_log_enable(struct es2_ap_dev *es2) -{ - if (!IS_ERR_OR_NULL(es2->apb_log_task)) - return; - - /* get log from APB1 */ - es2->apb_log_task = kthread_run(apb_log_poll, es2, "apb_log"); - if (IS_ERR(es2->apb_log_task)) - return; - /* XXX We will need to rename this per APB */ - es2->apb_log_dentry = debugfs_create_file("apb_log", 0444, - gb_debugfs_get(), es2, - &apb_log_fops); -} - -static void usb_log_disable(struct es2_ap_dev *es2) -{ - if (IS_ERR_OR_NULL(es2->apb_log_task)) - return; - - debugfs_remove(es2->apb_log_dentry); - es2->apb_log_dentry = NULL; - - kthread_stop(es2->apb_log_task); - es2->apb_log_task = NULL; -} - -static ssize_t apb_log_enable_read(struct file *f, char __user *buf, - size_t count, loff_t *ppos) -{ - struct es2_ap_dev *es2 = file_inode(f)->i_private; - int enable = !IS_ERR_OR_NULL(es2->apb_log_task); - char tmp_buf[3]; - - sprintf(tmp_buf, "%d\n", enable); - return simple_read_from_buffer(buf, count, ppos, tmp_buf, 3); -} - -static ssize_t apb_log_enable_write(struct file *f, const char __user *buf, - size_t count, loff_t *ppos) -{ - int enable; - ssize_t retval; - struct es2_ap_dev *es2 = file_inode(f)->i_private; - - retval = kstrtoint_from_user(buf, count, 10, &enable); - if (retval) - return retval; - - if (enable) - usb_log_enable(es2); - else - usb_log_disable(es2); - - return count; -} - -static const struct file_operations apb_log_enable_fops = { - .read = apb_log_enable_read, - .write = apb_log_enable_write, -}; - -static int apb_get_cport_count(struct usb_device *udev) -{ - int retval; - __le16 *cport_count; - - cport_count = kzalloc(sizeof(*cport_count), GFP_KERNEL); - if (!cport_count) - return -ENOMEM; - - retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - GB_APB_REQUEST_CPORT_COUNT, - USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_INTERFACE, 0, 0, cport_count, - sizeof(*cport_count), ES2_USB_CTRL_TIMEOUT); - if (retval != sizeof(*cport_count)) { - dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n", - retval); - - if (retval >= 0) - retval = -EIO; - - goto out; - } - - retval = le16_to_cpu(*cport_count); - - /* We need to fit a CPort ID in one byte of a message header */ - if (retval > U8_MAX) { - retval = U8_MAX; - dev_warn(&udev->dev, "Limiting number of CPorts to U8_MAX\n"); - } - -out: - kfree(cport_count); - return retval; -} - -/* - * The ES2 USB Bridge device has 15 endpoints - * 1 Control - usual USB stuff + AP -> APBridgeA messages - * 7 Bulk IN - CPort data in - * 7 Bulk OUT - CPort data out - */ -static int ap_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct es2_ap_dev *es2; - struct gb_host_device *hd; - struct usb_device *udev; - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - __u8 ep_addr; - int retval; - int i; - int num_cports; - bool bulk_out_found = false; - bool bulk_in_found = false; - bool arpc_in_found = false; - - udev = usb_get_dev(interface_to_usbdev(interface)); - - num_cports = apb_get_cport_count(udev); - if (num_cports < 0) { - usb_put_dev(udev); - dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n", - num_cports); - return num_cports; - } - - hd = gb_hd_create(&es2_driver, &udev->dev, ES2_GBUF_MSG_SIZE_MAX, - num_cports); - if (IS_ERR(hd)) { - usb_put_dev(udev); - return PTR_ERR(hd); - } - - es2 = hd_to_es2(hd); - es2->hd = hd; - es2->usb_intf = interface; - es2->usb_dev = udev; - spin_lock_init(&es2->cport_out_urb_lock); - INIT_KFIFO(es2->apb_log_fifo); - usb_set_intfdata(interface, es2); - - /* - * Reserve the CDSI0 and CDSI1 CPorts so they won't be allocated - * dynamically. - */ - retval = gb_hd_cport_reserve(hd, ES2_CPORT_CDSI0); - if (retval) - goto error; - retval = gb_hd_cport_reserve(hd, ES2_CPORT_CDSI1); - if (retval) - goto error; - - /* find all bulk endpoints */ - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i].desc; - ep_addr = endpoint->bEndpointAddress; - - if (usb_endpoint_is_bulk_in(endpoint)) { - if (!bulk_in_found) { - es2->cport_in.endpoint = ep_addr; - bulk_in_found = true; - } else if (!arpc_in_found) { - es2->arpc_endpoint_in = ep_addr; - arpc_in_found = true; - } else { - dev_warn(&udev->dev, - "Unused bulk IN endpoint found: 0x%02x\n", - ep_addr); - } - continue; - } - if (usb_endpoint_is_bulk_out(endpoint)) { - if (!bulk_out_found) { - es2->cport_out_endpoint = ep_addr; - bulk_out_found = true; - } else { - dev_warn(&udev->dev, - "Unused bulk OUT endpoint found: 0x%02x\n", - ep_addr); - } - continue; - } - dev_warn(&udev->dev, - "Unknown endpoint type found, address 0x%02x\n", - ep_addr); - } - if (!bulk_in_found || !arpc_in_found || !bulk_out_found) { - dev_err(&udev->dev, "Not enough endpoints found in device, aborting!\n"); - retval = -ENODEV; - goto error; - } - - /* Allocate buffers for our cport in messages */ - for (i = 0; i < NUM_CPORT_IN_URB; ++i) { - struct urb *urb; - u8 *buffer; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - retval = -ENOMEM; - goto error; - } - es2->cport_in.urb[i] = urb; - - buffer = kmalloc(ES2_GBUF_MSG_SIZE_MAX, GFP_KERNEL); - if (!buffer) { - retval = -ENOMEM; - goto error; - } - - usb_fill_bulk_urb(urb, udev, - usb_rcvbulkpipe(udev, es2->cport_in.endpoint), - buffer, ES2_GBUF_MSG_SIZE_MAX, - cport_in_callback, hd); - - es2->cport_in.buffer[i] = buffer; - } - - /* Allocate buffers for ARPC in messages */ - for (i = 0; i < NUM_ARPC_IN_URB; ++i) { - struct urb *urb; - u8 *buffer; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - retval = -ENOMEM; - goto error; - } - es2->arpc_urb[i] = urb; - - buffer = kmalloc(ARPC_IN_SIZE_MAX, GFP_KERNEL); - if (!buffer) { - retval = -ENOMEM; - goto error; - } - - usb_fill_bulk_urb(urb, udev, - usb_rcvbulkpipe(udev, - es2->arpc_endpoint_in), - buffer, ARPC_IN_SIZE_MAX, - arpc_in_callback, es2); - - es2->arpc_buffer[i] = buffer; - } - - /* Allocate urbs for our CPort OUT messages */ - for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { - struct urb *urb; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - retval = -ENOMEM; - goto error; - } - - es2->cport_out_urb[i] = urb; - es2->cport_out_urb_busy[i] = false; /* just to be anal */ - } - - /* XXX We will need to rename this per APB */ - es2->apb_log_enable_dentry = debugfs_create_file("apb_log_enable", - 0644, - gb_debugfs_get(), es2, - &apb_log_enable_fops); - - INIT_LIST_HEAD(&es2->arpcs); - spin_lock_init(&es2->arpc_lock); - - retval = es2_arpc_in_enable(es2); - if (retval) - goto error; - - retval = gb_hd_add(hd); - if (retval) - goto err_disable_arpc_in; - - retval = es2_cport_in_enable(es2, &es2->cport_in); - if (retval) - goto err_hd_del; - - return 0; - -err_hd_del: - gb_hd_del(hd); -err_disable_arpc_in: - es2_arpc_in_disable(es2); -error: - es2_destroy(es2); - - return retval; -} - -static void ap_disconnect(struct usb_interface *interface) -{ - struct es2_ap_dev *es2 = usb_get_intfdata(interface); - - gb_hd_del(es2->hd); - - es2_cport_in_disable(es2, &es2->cport_in); - es2_arpc_in_disable(es2); - - es2_destroy(es2); -} - -static struct usb_driver es2_ap_driver = { - .name = "es2_ap_driver", - .probe = ap_probe, - .disconnect = ap_disconnect, - .id_table = id_table, - .soft_unbind = 1, -}; - -module_usb_driver(es2_ap_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>"); diff --git a/drivers/staging/greybus/firmware.h b/drivers/staging/greybus/firmware.h index 946221307ef6..5d2564462ffc 100644 --- a/drivers/staging/greybus/firmware.h +++ b/drivers/staging/greybus/firmware.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Greybus Firmware Management Header * @@ -9,7 +9,7 @@ #ifndef __FIRMWARE_H #define __FIRMWARE_H -#include "greybus.h" +#include <linux/greybus.h> #define FW_NAME_PREFIX "gmp_" diff --git a/drivers/staging/greybus/fw-core.c b/drivers/staging/greybus/fw-core.c index 388866d92f5b..57bebf24636b 100644 --- a/drivers/staging/greybus/fw-core.c +++ b/drivers/staging/greybus/fw-core.c @@ -8,8 +8,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/firmware.h> +#include <linux/greybus.h> #include "firmware.h" -#include "greybus.h" #include "spilib.h" struct gb_fw_core { diff --git a/drivers/staging/greybus/fw-download.c b/drivers/staging/greybus/fw-download.c index d3b7cccbc10d..543692c567f9 100644 --- a/drivers/staging/greybus/fw-download.c +++ b/drivers/staging/greybus/fw-download.c @@ -10,8 +10,8 @@ #include <linux/jiffies.h> #include <linux/mutex.h> #include <linux/workqueue.h> +#include <linux/greybus.h> #include "firmware.h" -#include "greybus.h" /* Estimated minimum buffer size, actual size can be smaller than this */ #define MIN_FETCH_SIZE 512 diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c index 71aec14f8181..687c6405c65b 100644 --- a/drivers/staging/greybus/fw-management.c +++ b/drivers/staging/greybus/fw-management.c @@ -13,10 +13,10 @@ #include <linux/idr.h> #include <linux/ioctl.h> #include <linux/uaccess.h> +#include <linux/greybus.h> #include "firmware.h" #include "greybus_firmware.h" -#include "greybus.h" #define FW_MGMT_TIMEOUT_MS 1000 diff --git a/drivers/staging/greybus/gb-camera.h b/drivers/staging/greybus/gb-camera.h index ee293e461fc3..5fc469101fc1 100644 --- a/drivers/staging/greybus/gb-camera.h +++ b/drivers/staging/greybus/gb-camera.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Greybus Camera protocol driver. * diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index 6cb85c3d3572..9fc5c47be9bd 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -13,8 +13,8 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/device.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" #define GB_GBPHY_AUTOSUSPEND_MS 3000 diff --git a/drivers/staging/greybus/gbphy.h b/drivers/staging/greybus/gbphy.h index 99463489d7d6..087928a586fb 100644 --- a/drivers/staging/greybus/gbphy.h +++ b/drivers/staging/greybus/gbphy.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Greybus Bridged-Phy Bus driver * diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index 3151004d26fb..1ff34abd5692 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -13,8 +13,8 @@ #include <linux/irqdomain.h> #include <linux/gpio/driver.h> #include <linux/mutex.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" struct gb_gpio_line { diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h deleted file mode 100644 index d03ddb7c9df0..000000000000 --- a/drivers/staging/greybus/greybus.h +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus driver and device API - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#ifndef __LINUX_GREYBUS_H -#define __LINUX_GREYBUS_H - -#ifdef __KERNEL__ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/list.h> -#include <linux/slab.h> -#include <linux/device.h> -#include <linux/module.h> -#include <linux/pm_runtime.h> -#include <linux/idr.h> - -#include "greybus_id.h" -#include "greybus_manifest.h" -#include "greybus_protocols.h" -#include "manifest.h" -#include "hd.h" -#include "svc.h" -#include "control.h" -#include "module.h" -#include "interface.h" -#include "bundle.h" -#include "connection.h" -#include "operation.h" - -/* Matches up with the Greybus Protocol specification document */ -#define GREYBUS_VERSION_MAJOR 0x00 -#define GREYBUS_VERSION_MINOR 0x01 - -#define GREYBUS_ID_MATCH_DEVICE \ - (GREYBUS_ID_MATCH_VENDOR | GREYBUS_ID_MATCH_PRODUCT) - -#define GREYBUS_DEVICE(v, p) \ - .match_flags = GREYBUS_ID_MATCH_DEVICE, \ - .vendor = (v), \ - .product = (p), - -#define GREYBUS_DEVICE_CLASS(c) \ - .match_flags = GREYBUS_ID_MATCH_CLASS, \ - .class = (c), - -/* Maximum number of CPorts */ -#define CPORT_ID_MAX 4095 /* UniPro max id is 4095 */ -#define CPORT_ID_BAD U16_MAX - -struct greybus_driver { - const char *name; - - int (*probe)(struct gb_bundle *bundle, - const struct greybus_bundle_id *id); - void (*disconnect)(struct gb_bundle *bundle); - - const struct greybus_bundle_id *id_table; - - struct device_driver driver; -}; -#define to_greybus_driver(d) container_of(d, struct greybus_driver, driver) - -static inline void greybus_set_drvdata(struct gb_bundle *bundle, void *data) -{ - dev_set_drvdata(&bundle->dev, data); -} - -static inline void *greybus_get_drvdata(struct gb_bundle *bundle) -{ - return dev_get_drvdata(&bundle->dev); -} - -/* Don't call these directly, use the module_greybus_driver() macro instead */ -int greybus_register_driver(struct greybus_driver *driver, - struct module *module, const char *mod_name); -void greybus_deregister_driver(struct greybus_driver *driver); - -/* define to get proper THIS_MODULE and KBUILD_MODNAME values */ -#define greybus_register(driver) \ - greybus_register_driver(driver, THIS_MODULE, KBUILD_MODNAME) -#define greybus_deregister(driver) \ - greybus_deregister_driver(driver) - -/** - * module_greybus_driver() - Helper macro for registering a Greybus driver - * @__greybus_driver: greybus_driver structure - * - * Helper macro for Greybus drivers to set up proper module init / exit - * functions. Replaces module_init() and module_exit() and keeps people from - * printing pointless things to the kernel log when their driver is loaded. - */ -#define module_greybus_driver(__greybus_driver) \ - module_driver(__greybus_driver, greybus_register, greybus_deregister) - -int greybus_disabled(void); - -void gb_debugfs_init(void); -void gb_debugfs_cleanup(void); -struct dentry *gb_debugfs_get(void); - -extern struct bus_type greybus_bus_type; - -extern struct device_type greybus_hd_type; -extern struct device_type greybus_module_type; -extern struct device_type greybus_interface_type; -extern struct device_type greybus_control_type; -extern struct device_type greybus_bundle_type; -extern struct device_type greybus_svc_type; - -static inline int is_gb_host_device(const struct device *dev) -{ - return dev->type == &greybus_hd_type; -} - -static inline int is_gb_module(const struct device *dev) -{ - return dev->type == &greybus_module_type; -} - -static inline int is_gb_interface(const struct device *dev) -{ - return dev->type == &greybus_interface_type; -} - -static inline int is_gb_control(const struct device *dev) -{ - return dev->type == &greybus_control_type; -} - -static inline int is_gb_bundle(const struct device *dev) -{ - return dev->type == &greybus_bundle_type; -} - -static inline int is_gb_svc(const struct device *dev) -{ - return dev->type == &greybus_svc_type; -} - -static inline bool cport_id_valid(struct gb_host_device *hd, u16 cport_id) -{ - return cport_id != CPORT_ID_BAD && cport_id < hd->num_cports; -} - -#endif /* __KERNEL__ */ -#endif /* __LINUX_GREYBUS_H */ diff --git a/drivers/staging/greybus/greybus_authentication.h b/drivers/staging/greybus/greybus_authentication.h index 03ea9615b217..7edc7295b7ab 100644 --- a/drivers/staging/greybus/greybus_authentication.h +++ b/drivers/staging/greybus/greybus_authentication.h @@ -1,55 +1,9 @@ -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ /* * Greybus Component Authentication User Header * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * * Copyright(c) 2016 Google Inc. All rights reserved. * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details. - * - * BSD LICENSE - * - * Copyright(c) 2016 Google Inc. All rights reserved. - * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. or Linaro Ltd. nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR - * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __GREYBUS_AUTHENTICATION_USER_H diff --git a/drivers/staging/greybus/greybus_firmware.h b/drivers/staging/greybus/greybus_firmware.h index b58281a63ba4..f68fd5e25321 100644 --- a/drivers/staging/greybus/greybus_firmware.h +++ b/drivers/staging/greybus/greybus_firmware.h @@ -1,55 +1,9 @@ -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ /* * Greybus Firmware Management User Header * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * * Copyright(c) 2016 Google Inc. All rights reserved. * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details. - * - * BSD LICENSE - * - * Copyright(c) 2016 Google Inc. All rights reserved. - * Copyright(c) 2016 Linaro Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. or Linaro Ltd. nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR - * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __GREYBUS_FIRMWARE_USER_H diff --git a/drivers/staging/greybus/greybus_id.h b/drivers/staging/greybus/greybus_id.h deleted file mode 100644 index f4c8440093e4..000000000000 --- a/drivers/staging/greybus/greybus_id.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* FIXME - * move this to include/linux/mod_devicetable.h when merging - */ - -#ifndef __LINUX_GREYBUS_ID_H -#define __LINUX_GREYBUS_ID_H - -#include <linux/types.h> -#include <linux/mod_devicetable.h> - - -struct greybus_bundle_id { - __u16 match_flags; - __u32 vendor; - __u32 product; - __u8 class; - - kernel_ulong_t driver_info __aligned(sizeof(kernel_ulong_t)); -}; - -/* Used to match the greybus_bundle_id */ -#define GREYBUS_ID_MATCH_VENDOR BIT(0) -#define GREYBUS_ID_MATCH_PRODUCT BIT(1) -#define GREYBUS_ID_MATCH_CLASS BIT(2) - -#endif /* __LINUX_GREYBUS_ID_H */ diff --git a/drivers/staging/greybus/greybus_manifest.h b/drivers/staging/greybus/greybus_manifest.h deleted file mode 100644 index 2cec5cf7a846..000000000000 --- a/drivers/staging/greybus/greybus_manifest.h +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus manifest definition - * - * See "Greybus Application Protocol" document (version 0.1) for - * details on these values and structures. - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - * - * Released under the GPLv2 and BSD licenses. - */ - -#ifndef __GREYBUS_MANIFEST_H -#define __GREYBUS_MANIFEST_H - -enum greybus_descriptor_type { - GREYBUS_TYPE_INVALID = 0x00, - GREYBUS_TYPE_INTERFACE = 0x01, - GREYBUS_TYPE_STRING = 0x02, - GREYBUS_TYPE_BUNDLE = 0x03, - GREYBUS_TYPE_CPORT = 0x04, -}; - -enum greybus_protocol { - GREYBUS_PROTOCOL_CONTROL = 0x00, - /* 0x01 is unused */ - GREYBUS_PROTOCOL_GPIO = 0x02, - GREYBUS_PROTOCOL_I2C = 0x03, - GREYBUS_PROTOCOL_UART = 0x04, - GREYBUS_PROTOCOL_HID = 0x05, - GREYBUS_PROTOCOL_USB = 0x06, - GREYBUS_PROTOCOL_SDIO = 0x07, - GREYBUS_PROTOCOL_POWER_SUPPLY = 0x08, - GREYBUS_PROTOCOL_PWM = 0x09, - /* 0x0a is unused */ - GREYBUS_PROTOCOL_SPI = 0x0b, - GREYBUS_PROTOCOL_DISPLAY = 0x0c, - GREYBUS_PROTOCOL_CAMERA_MGMT = 0x0d, - GREYBUS_PROTOCOL_SENSOR = 0x0e, - GREYBUS_PROTOCOL_LIGHTS = 0x0f, - GREYBUS_PROTOCOL_VIBRATOR = 0x10, - GREYBUS_PROTOCOL_LOOPBACK = 0x11, - GREYBUS_PROTOCOL_AUDIO_MGMT = 0x12, - GREYBUS_PROTOCOL_AUDIO_DATA = 0x13, - GREYBUS_PROTOCOL_SVC = 0x14, - GREYBUS_PROTOCOL_BOOTROM = 0x15, - GREYBUS_PROTOCOL_CAMERA_DATA = 0x16, - GREYBUS_PROTOCOL_FW_DOWNLOAD = 0x17, - GREYBUS_PROTOCOL_FW_MANAGEMENT = 0x18, - GREYBUS_PROTOCOL_AUTHENTICATION = 0x19, - GREYBUS_PROTOCOL_LOG = 0x1a, - /* ... */ - GREYBUS_PROTOCOL_RAW = 0xfe, - GREYBUS_PROTOCOL_VENDOR = 0xff, -}; - -enum greybus_class_type { - GREYBUS_CLASS_CONTROL = 0x00, - /* 0x01 is unused */ - /* 0x02 is unused */ - /* 0x03 is unused */ - /* 0x04 is unused */ - GREYBUS_CLASS_HID = 0x05, - /* 0x06 is unused */ - /* 0x07 is unused */ - GREYBUS_CLASS_POWER_SUPPLY = 0x08, - /* 0x09 is unused */ - GREYBUS_CLASS_BRIDGED_PHY = 0x0a, - /* 0x0b is unused */ - GREYBUS_CLASS_DISPLAY = 0x0c, - GREYBUS_CLASS_CAMERA = 0x0d, - GREYBUS_CLASS_SENSOR = 0x0e, - GREYBUS_CLASS_LIGHTS = 0x0f, - GREYBUS_CLASS_VIBRATOR = 0x10, - GREYBUS_CLASS_LOOPBACK = 0x11, - GREYBUS_CLASS_AUDIO = 0x12, - /* 0x13 is unused */ - /* 0x14 is unused */ - GREYBUS_CLASS_BOOTROM = 0x15, - GREYBUS_CLASS_FW_MANAGEMENT = 0x16, - GREYBUS_CLASS_LOG = 0x17, - /* ... */ - GREYBUS_CLASS_RAW = 0xfe, - GREYBUS_CLASS_VENDOR = 0xff, -}; - -enum { - GREYBUS_INTERFACE_FEATURE_TIMESYNC = BIT(0), -}; - -/* - * The string in a string descriptor is not NUL-terminated. The - * size of the descriptor will be rounded up to a multiple of 4 - * bytes, by padding the string with 0x00 bytes if necessary. - */ -struct greybus_descriptor_string { - __u8 length; - __u8 id; - __u8 string[0]; -} __packed; - -/* - * An interface descriptor describes information about an interface as a whole, - * *not* the functions within it. - */ -struct greybus_descriptor_interface { - __u8 vendor_stringid; - __u8 product_stringid; - __u8 features; - __u8 pad; -} __packed; - -/* - * An bundle descriptor defines an identification number and a class for - * each bundle. - * - * @id: Uniquely identifies a bundle within a interface, its sole purpose is to - * allow CPort descriptors to specify which bundle they are associated with. - * The first bundle will have id 0, second will have 1 and so on. - * - * The largest CPort id associated with an bundle (defined by a - * CPort descriptor in the manifest) is used to determine how to - * encode the device id and module number in UniPro packets - * that use the bundle. - * - * @class: It is used by kernel to know the functionality provided by the - * bundle and will be matched against drivers functinality while probing greybus - * driver. It should contain one of the values defined in - * 'enum greybus_class_type'. - * - */ -struct greybus_descriptor_bundle { - __u8 id; /* interface-relative id (0..) */ - __u8 class; - __u8 pad[2]; -} __packed; - -/* - * A CPort descriptor indicates the id of the bundle within the - * module it's associated with, along with the CPort id used to - * address the CPort. The protocol id defines the format of messages - * exchanged using the CPort. - */ -struct greybus_descriptor_cport { - __le16 id; - __u8 bundle; - __u8 protocol_id; /* enum greybus_protocol */ -} __packed; - -struct greybus_descriptor_header { - __le16 size; - __u8 type; /* enum greybus_descriptor_type */ - __u8 pad; -} __packed; - -struct greybus_descriptor { - struct greybus_descriptor_header header; - union { - struct greybus_descriptor_string string; - struct greybus_descriptor_interface interface; - struct greybus_descriptor_bundle bundle; - struct greybus_descriptor_cport cport; - }; -} __packed; - -struct greybus_manifest_header { - __le16 size; - __u8 version_major; - __u8 version_minor; -} __packed; - -struct greybus_manifest { - struct greybus_manifest_header header; - struct greybus_descriptor descriptors[0]; -} __packed; - -#endif /* __GREYBUS_MANIFEST_H */ diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h deleted file mode 100644 index ddc73f10eb22..000000000000 --- a/drivers/staging/greybus/greybus_protocols.h +++ /dev/null @@ -1,2222 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) -/* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2014 - 2015 Google Inc. All rights reserved. - * Copyright(c) 2014 - 2015 Linaro Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details. - * - * BSD LICENSE - * - * Copyright(c) 2014 - 2015 Google Inc. All rights reserved. - * Copyright(c) 2014 - 2015 Linaro Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. or Linaro Ltd. nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR - * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __GREYBUS_PROTOCOLS_H -#define __GREYBUS_PROTOCOLS_H - -/* Fixed IDs for control/svc protocols */ - -/* SVC switch-port device ids */ -#define GB_SVC_DEVICE_ID_SVC 0 -#define GB_SVC_DEVICE_ID_AP 1 -#define GB_SVC_DEVICE_ID_MIN 2 -#define GB_SVC_DEVICE_ID_MAX 31 - -#define GB_SVC_CPORT_ID 0 -#define GB_CONTROL_BUNDLE_ID 0 -#define GB_CONTROL_CPORT_ID 0 - - -/* - * All operation messages (both requests and responses) begin with - * a header that encodes the size of the message (header included). - * This header also contains a unique identifier, that associates a - * response message with its operation. The header contains an - * operation type field, whose interpretation is dependent on what - * type of protocol is used over the connection. The high bit - * (0x80) of the operation type field is used to indicate whether - * the message is a request (clear) or a response (set). - * - * Response messages include an additional result byte, which - * communicates the result of the corresponding request. A zero - * result value means the operation completed successfully. Any - * other value indicates an error; in this case, the payload of the - * response message (if any) is ignored. The result byte must be - * zero in the header for a request message. - * - * The wire format for all numeric fields in the header is little - * endian. Any operation-specific data begins immediately after the - * header. - */ -struct gb_operation_msg_hdr { - __le16 size; /* Size in bytes of header + payload */ - __le16 operation_id; /* Operation unique id */ - __u8 type; /* E.g GB_I2C_TYPE_* or GB_GPIO_TYPE_* */ - __u8 result; /* Result of request (in responses only) */ - __u8 pad[2]; /* must be zero (ignore when read) */ -} __packed; - - -/* Generic request types */ -#define GB_REQUEST_TYPE_CPORT_SHUTDOWN 0x00 -#define GB_REQUEST_TYPE_INVALID 0x7f - -struct gb_cport_shutdown_request { - __u8 phase; -} __packed; - - -/* Control Protocol */ - -/* Greybus control request types */ -#define GB_CONTROL_TYPE_VERSION 0x01 -#define GB_CONTROL_TYPE_PROBE_AP 0x02 -#define GB_CONTROL_TYPE_GET_MANIFEST_SIZE 0x03 -#define GB_CONTROL_TYPE_GET_MANIFEST 0x04 -#define GB_CONTROL_TYPE_CONNECTED 0x05 -#define GB_CONTROL_TYPE_DISCONNECTED 0x06 -#define GB_CONTROL_TYPE_TIMESYNC_ENABLE 0x07 -#define GB_CONTROL_TYPE_TIMESYNC_DISABLE 0x08 -#define GB_CONTROL_TYPE_TIMESYNC_AUTHORITATIVE 0x09 -/* Unused 0x0a */ -#define GB_CONTROL_TYPE_BUNDLE_VERSION 0x0b -#define GB_CONTROL_TYPE_DISCONNECTING 0x0c -#define GB_CONTROL_TYPE_TIMESYNC_GET_LAST_EVENT 0x0d -#define GB_CONTROL_TYPE_MODE_SWITCH 0x0e -#define GB_CONTROL_TYPE_BUNDLE_SUSPEND 0x0f -#define GB_CONTROL_TYPE_BUNDLE_RESUME 0x10 -#define GB_CONTROL_TYPE_BUNDLE_DEACTIVATE 0x11 -#define GB_CONTROL_TYPE_BUNDLE_ACTIVATE 0x12 -#define GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE 0x13 -#define GB_CONTROL_TYPE_INTF_DEACTIVATE_PREPARE 0x14 -#define GB_CONTROL_TYPE_INTF_HIBERNATE_ABORT 0x15 - -struct gb_control_version_request { - __u8 major; - __u8 minor; -} __packed; - -struct gb_control_version_response { - __u8 major; - __u8 minor; -} __packed; - -struct gb_control_bundle_version_request { - __u8 bundle_id; -} __packed; - -struct gb_control_bundle_version_response { - __u8 major; - __u8 minor; -} __packed; - -/* Control protocol manifest get size request has no payload*/ -struct gb_control_get_manifest_size_response { - __le16 size; -} __packed; - -/* Control protocol manifest get request has no payload */ -struct gb_control_get_manifest_response { - __u8 data[0]; -} __packed; - -/* Control protocol [dis]connected request */ -struct gb_control_connected_request { - __le16 cport_id; -} __packed; - -struct gb_control_disconnecting_request { - __le16 cport_id; -} __packed; -/* disconnecting response has no payload */ - -struct gb_control_disconnected_request { - __le16 cport_id; -} __packed; -/* Control protocol [dis]connected response has no payload */ - -/* - * All Bundle power management operations use the same request and response - * layout and status codes. - */ - -#define GB_CONTROL_BUNDLE_PM_OK 0x00 -#define GB_CONTROL_BUNDLE_PM_INVAL 0x01 -#define GB_CONTROL_BUNDLE_PM_BUSY 0x02 -#define GB_CONTROL_BUNDLE_PM_FAIL 0x03 -#define GB_CONTROL_BUNDLE_PM_NA 0x04 - -struct gb_control_bundle_pm_request { - __u8 bundle_id; -} __packed; - -struct gb_control_bundle_pm_response { - __u8 status; -} __packed; - -/* - * Interface Suspend Prepare and Deactivate Prepare operations use the same - * response layout and error codes. Define a single response structure and reuse - * it. Both operations have no payload. - */ - -#define GB_CONTROL_INTF_PM_OK 0x00 -#define GB_CONTROL_INTF_PM_BUSY 0x01 -#define GB_CONTROL_INTF_PM_NA 0x02 - -struct gb_control_intf_pm_response { - __u8 status; -} __packed; - -/* APBridge protocol */ - -/* request APB1 log */ -#define GB_APB_REQUEST_LOG 0x02 - -/* request to map a cport to bulk in and bulk out endpoints */ -#define GB_APB_REQUEST_EP_MAPPING 0x03 - -/* request to get the number of cports available */ -#define GB_APB_REQUEST_CPORT_COUNT 0x04 - -/* request to reset a cport state */ -#define GB_APB_REQUEST_RESET_CPORT 0x05 - -/* request to time the latency of messages on a given cport */ -#define GB_APB_REQUEST_LATENCY_TAG_EN 0x06 -#define GB_APB_REQUEST_LATENCY_TAG_DIS 0x07 - -/* request to control the CSI transmitter */ -#define GB_APB_REQUEST_CSI_TX_CONTROL 0x08 - -/* request to control audio streaming */ -#define GB_APB_REQUEST_AUDIO_CONTROL 0x09 - -/* TimeSync requests */ -#define GB_APB_REQUEST_TIMESYNC_ENABLE 0x0d -#define GB_APB_REQUEST_TIMESYNC_DISABLE 0x0e -#define GB_APB_REQUEST_TIMESYNC_AUTHORITATIVE 0x0f -#define GB_APB_REQUEST_TIMESYNC_GET_LAST_EVENT 0x10 - -/* requests to set Greybus CPort flags */ -#define GB_APB_REQUEST_CPORT_FLAGS 0x11 - -/* ARPC request */ -#define GB_APB_REQUEST_ARPC_RUN 0x12 - -struct gb_apb_request_cport_flags { - __le32 flags; -#define GB_APB_CPORT_FLAG_CONTROL 0x01 -#define GB_APB_CPORT_FLAG_HIGH_PRIO 0x02 -} __packed; - - -/* Firmware Download Protocol */ - -/* Request Types */ -#define GB_FW_DOWNLOAD_TYPE_FIND_FIRMWARE 0x01 -#define GB_FW_DOWNLOAD_TYPE_FETCH_FIRMWARE 0x02 -#define GB_FW_DOWNLOAD_TYPE_RELEASE_FIRMWARE 0x03 - -#define GB_FIRMWARE_TAG_MAX_SIZE 10 - -/* firmware download find firmware request/response */ -struct gb_fw_download_find_firmware_request { - __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE]; -} __packed; - -struct gb_fw_download_find_firmware_response { - __u8 firmware_id; - __le32 size; -} __packed; - -/* firmware download fetch firmware request/response */ -struct gb_fw_download_fetch_firmware_request { - __u8 firmware_id; - __le32 offset; - __le32 size; -} __packed; - -struct gb_fw_download_fetch_firmware_response { - __u8 data[0]; -} __packed; - -/* firmware download release firmware request */ -struct gb_fw_download_release_firmware_request { - __u8 firmware_id; -} __packed; -/* firmware download release firmware response has no payload */ - - -/* Firmware Management Protocol */ - -/* Request Types */ -#define GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION 0x01 -#define GB_FW_MGMT_TYPE_LOAD_AND_VALIDATE_FW 0x02 -#define GB_FW_MGMT_TYPE_LOADED_FW 0x03 -#define GB_FW_MGMT_TYPE_BACKEND_FW_VERSION 0x04 -#define GB_FW_MGMT_TYPE_BACKEND_FW_UPDATE 0x05 -#define GB_FW_MGMT_TYPE_BACKEND_FW_UPDATED 0x06 - -#define GB_FW_LOAD_METHOD_UNIPRO 0x01 -#define GB_FW_LOAD_METHOD_INTERNAL 0x02 - -#define GB_FW_LOAD_STATUS_FAILED 0x00 -#define GB_FW_LOAD_STATUS_UNVALIDATED 0x01 -#define GB_FW_LOAD_STATUS_VALIDATED 0x02 -#define GB_FW_LOAD_STATUS_VALIDATION_FAILED 0x03 - -#define GB_FW_BACKEND_FW_STATUS_SUCCESS 0x01 -#define GB_FW_BACKEND_FW_STATUS_FAIL_FIND 0x02 -#define GB_FW_BACKEND_FW_STATUS_FAIL_FETCH 0x03 -#define GB_FW_BACKEND_FW_STATUS_FAIL_WRITE 0x04 -#define GB_FW_BACKEND_FW_STATUS_INT 0x05 -#define GB_FW_BACKEND_FW_STATUS_RETRY 0x06 -#define GB_FW_BACKEND_FW_STATUS_NOT_SUPPORTED 0x07 - -#define GB_FW_BACKEND_VERSION_STATUS_SUCCESS 0x01 -#define GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE 0x02 -#define GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED 0x03 -#define GB_FW_BACKEND_VERSION_STATUS_RETRY 0x04 -#define GB_FW_BACKEND_VERSION_STATUS_FAIL_INT 0x05 - -/* firmware management interface firmware version request has no payload */ -struct gb_fw_mgmt_interface_fw_version_response { - __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE]; - __le16 major; - __le16 minor; -} __packed; - -/* firmware management load and validate firmware request/response */ -struct gb_fw_mgmt_load_and_validate_fw_request { - __u8 request_id; - __u8 load_method; - __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE]; -} __packed; -/* firmware management load and validate firmware response has no payload*/ - -/* firmware management loaded firmware request */ -struct gb_fw_mgmt_loaded_fw_request { - __u8 request_id; - __u8 status; - __le16 major; - __le16 minor; -} __packed; -/* firmware management loaded firmware response has no payload */ - -/* firmware management backend firmware version request/response */ -struct gb_fw_mgmt_backend_fw_version_request { - __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE]; -} __packed; - -struct gb_fw_mgmt_backend_fw_version_response { - __le16 major; - __le16 minor; - __u8 status; -} __packed; - -/* firmware management backend firmware update request */ -struct gb_fw_mgmt_backend_fw_update_request { - __u8 request_id; - __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE]; -} __packed; -/* firmware management backend firmware update response has no payload */ - -/* firmware management backend firmware updated request */ -struct gb_fw_mgmt_backend_fw_updated_request { - __u8 request_id; - __u8 status; -} __packed; -/* firmware management backend firmware updated response has no payload */ - - -/* Component Authentication Protocol (CAP) */ - -/* Request Types */ -#define GB_CAP_TYPE_GET_ENDPOINT_UID 0x01 -#define GB_CAP_TYPE_GET_IMS_CERTIFICATE 0x02 -#define GB_CAP_TYPE_AUTHENTICATE 0x03 - -/* CAP get endpoint uid request has no payload */ -struct gb_cap_get_endpoint_uid_response { - __u8 uid[8]; -} __packed; - -/* CAP get endpoint ims certificate request/response */ -struct gb_cap_get_ims_certificate_request { - __le32 certificate_class; - __le32 certificate_id; -} __packed; - -struct gb_cap_get_ims_certificate_response { - __u8 result_code; - __u8 certificate[0]; -} __packed; - -/* CAP authenticate request/response */ -struct gb_cap_authenticate_request { - __le32 auth_type; - __u8 uid[8]; - __u8 challenge[32]; -} __packed; - -struct gb_cap_authenticate_response { - __u8 result_code; - __u8 response[64]; - __u8 signature[0]; -} __packed; - - -/* Bootrom Protocol */ - -/* Version of the Greybus bootrom protocol we support */ -#define GB_BOOTROM_VERSION_MAJOR 0x00 -#define GB_BOOTROM_VERSION_MINOR 0x01 - -/* Greybus bootrom request types */ -#define GB_BOOTROM_TYPE_VERSION 0x01 -#define GB_BOOTROM_TYPE_FIRMWARE_SIZE 0x02 -#define GB_BOOTROM_TYPE_GET_FIRMWARE 0x03 -#define GB_BOOTROM_TYPE_READY_TO_BOOT 0x04 -#define GB_BOOTROM_TYPE_AP_READY 0x05 /* Request with no-payload */ -#define GB_BOOTROM_TYPE_GET_VID_PID 0x06 /* Request with no-payload */ - -/* Greybus bootrom boot stages */ -#define GB_BOOTROM_BOOT_STAGE_ONE 0x01 /* Reserved for the boot ROM */ -#define GB_BOOTROM_BOOT_STAGE_TWO 0x02 /* Bootrom package to be loaded by the boot ROM */ -#define GB_BOOTROM_BOOT_STAGE_THREE 0x03 /* Module personality package loaded by Stage 2 firmware */ - -/* Greybus bootrom ready to boot status */ -#define GB_BOOTROM_BOOT_STATUS_INVALID 0x00 /* Firmware blob could not be validated */ -#define GB_BOOTROM_BOOT_STATUS_INSECURE 0x01 /* Firmware blob is valid but insecure */ -#define GB_BOOTROM_BOOT_STATUS_SECURE 0x02 /* Firmware blob is valid and secure */ - -/* Max bootrom data fetch size in bytes */ -#define GB_BOOTROM_FETCH_MAX 2000 - -struct gb_bootrom_version_request { - __u8 major; - __u8 minor; -} __packed; - -struct gb_bootrom_version_response { - __u8 major; - __u8 minor; -} __packed; - -/* Bootrom protocol firmware size request/response */ -struct gb_bootrom_firmware_size_request { - __u8 stage; -} __packed; - -struct gb_bootrom_firmware_size_response { - __le32 size; -} __packed; - -/* Bootrom protocol get firmware request/response */ -struct gb_bootrom_get_firmware_request { - __le32 offset; - __le32 size; -} __packed; - -struct gb_bootrom_get_firmware_response { - __u8 data[0]; -} __packed; - -/* Bootrom protocol Ready to boot request */ -struct gb_bootrom_ready_to_boot_request { - __u8 status; -} __packed; -/* Bootrom protocol Ready to boot response has no payload */ - -/* Bootrom protocol get VID/PID request has no payload */ -struct gb_bootrom_get_vid_pid_response { - __le32 vendor_id; - __le32 product_id; -} __packed; - - -/* Power Supply */ - -/* Greybus power supply request types */ -#define GB_POWER_SUPPLY_TYPE_GET_SUPPLIES 0x02 -#define GB_POWER_SUPPLY_TYPE_GET_DESCRIPTION 0x03 -#define GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS 0x04 -#define GB_POWER_SUPPLY_TYPE_GET_PROPERTY 0x05 -#define GB_POWER_SUPPLY_TYPE_SET_PROPERTY 0x06 -#define GB_POWER_SUPPLY_TYPE_EVENT 0x07 - -/* Greybus power supply battery technologies types */ -#define GB_POWER_SUPPLY_TECH_UNKNOWN 0x0000 -#define GB_POWER_SUPPLY_TECH_NiMH 0x0001 -#define GB_POWER_SUPPLY_TECH_LION 0x0002 -#define GB_POWER_SUPPLY_TECH_LIPO 0x0003 -#define GB_POWER_SUPPLY_TECH_LiFe 0x0004 -#define GB_POWER_SUPPLY_TECH_NiCd 0x0005 -#define GB_POWER_SUPPLY_TECH_LiMn 0x0006 - -/* Greybus power supply types */ -#define GB_POWER_SUPPLY_UNKNOWN_TYPE 0x0000 -#define GB_POWER_SUPPLY_BATTERY_TYPE 0x0001 -#define GB_POWER_SUPPLY_UPS_TYPE 0x0002 -#define GB_POWER_SUPPLY_MAINS_TYPE 0x0003 -#define GB_POWER_SUPPLY_USB_TYPE 0x0004 -#define GB_POWER_SUPPLY_USB_DCP_TYPE 0x0005 -#define GB_POWER_SUPPLY_USB_CDP_TYPE 0x0006 -#define GB_POWER_SUPPLY_USB_ACA_TYPE 0x0007 - -/* Greybus power supply health values */ -#define GB_POWER_SUPPLY_HEALTH_UNKNOWN 0x0000 -#define GB_POWER_SUPPLY_HEALTH_GOOD 0x0001 -#define GB_POWER_SUPPLY_HEALTH_OVERHEAT 0x0002 -#define GB_POWER_SUPPLY_HEALTH_DEAD 0x0003 -#define GB_POWER_SUPPLY_HEALTH_OVERVOLTAGE 0x0004 -#define GB_POWER_SUPPLY_HEALTH_UNSPEC_FAILURE 0x0005 -#define GB_POWER_SUPPLY_HEALTH_COLD 0x0006 -#define GB_POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE 0x0007 -#define GB_POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE 0x0008 - -/* Greybus power supply status values */ -#define GB_POWER_SUPPLY_STATUS_UNKNOWN 0x0000 -#define GB_POWER_SUPPLY_STATUS_CHARGING 0x0001 -#define GB_POWER_SUPPLY_STATUS_DISCHARGING 0x0002 -#define GB_POWER_SUPPLY_STATUS_NOT_CHARGING 0x0003 -#define GB_POWER_SUPPLY_STATUS_FULL 0x0004 - -/* Greybus power supply capacity level values */ -#define GB_POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN 0x0000 -#define GB_POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL 0x0001 -#define GB_POWER_SUPPLY_CAPACITY_LEVEL_LOW 0x0002 -#define GB_POWER_SUPPLY_CAPACITY_LEVEL_NORMAL 0x0003 -#define GB_POWER_SUPPLY_CAPACITY_LEVEL_HIGH 0x0004 -#define GB_POWER_SUPPLY_CAPACITY_LEVEL_FULL 0x0005 - -/* Greybus power supply scope values */ -#define GB_POWER_SUPPLY_SCOPE_UNKNOWN 0x0000 -#define GB_POWER_SUPPLY_SCOPE_SYSTEM 0x0001 -#define GB_POWER_SUPPLY_SCOPE_DEVICE 0x0002 - -struct gb_power_supply_get_supplies_response { - __u8 supplies_count; -} __packed; - -struct gb_power_supply_get_description_request { - __u8 psy_id; -} __packed; - -struct gb_power_supply_get_description_response { - __u8 manufacturer[32]; - __u8 model[32]; - __u8 serial_number[32]; - __le16 type; - __u8 properties_count; -} __packed; - -struct gb_power_supply_props_desc { - __u8 property; -#define GB_POWER_SUPPLY_PROP_STATUS 0x00 -#define GB_POWER_SUPPLY_PROP_CHARGE_TYPE 0x01 -#define GB_POWER_SUPPLY_PROP_HEALTH 0x02 -#define GB_POWER_SUPPLY_PROP_PRESENT 0x03 -#define GB_POWER_SUPPLY_PROP_ONLINE 0x04 -#define GB_POWER_SUPPLY_PROP_AUTHENTIC 0x05 -#define GB_POWER_SUPPLY_PROP_TECHNOLOGY 0x06 -#define GB_POWER_SUPPLY_PROP_CYCLE_COUNT 0x07 -#define GB_POWER_SUPPLY_PROP_VOLTAGE_MAX 0x08 -#define GB_POWER_SUPPLY_PROP_VOLTAGE_MIN 0x09 -#define GB_POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN 0x0A -#define GB_POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN 0x0B -#define GB_POWER_SUPPLY_PROP_VOLTAGE_NOW 0x0C -#define GB_POWER_SUPPLY_PROP_VOLTAGE_AVG 0x0D -#define GB_POWER_SUPPLY_PROP_VOLTAGE_OCV 0x0E -#define GB_POWER_SUPPLY_PROP_VOLTAGE_BOOT 0x0F -#define GB_POWER_SUPPLY_PROP_CURRENT_MAX 0x10 -#define GB_POWER_SUPPLY_PROP_CURRENT_NOW 0x11 -#define GB_POWER_SUPPLY_PROP_CURRENT_AVG 0x12 -#define GB_POWER_SUPPLY_PROP_CURRENT_BOOT 0x13 -#define GB_POWER_SUPPLY_PROP_POWER_NOW 0x14 -#define GB_POWER_SUPPLY_PROP_POWER_AVG 0x15 -#define GB_POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN 0x16 -#define GB_POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN 0x17 -#define GB_POWER_SUPPLY_PROP_CHARGE_FULL 0x18 -#define GB_POWER_SUPPLY_PROP_CHARGE_EMPTY 0x19 -#define GB_POWER_SUPPLY_PROP_CHARGE_NOW 0x1A -#define GB_POWER_SUPPLY_PROP_CHARGE_AVG 0x1B -#define GB_POWER_SUPPLY_PROP_CHARGE_COUNTER 0x1C -#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT 0x1D -#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX 0x1E -#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE 0x1F -#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX 0x20 -#define GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT 0x21 -#define GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX 0x22 -#define GB_POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT 0x23 -#define GB_POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN 0x24 -#define GB_POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN 0x25 -#define GB_POWER_SUPPLY_PROP_ENERGY_FULL 0x26 -#define GB_POWER_SUPPLY_PROP_ENERGY_EMPTY 0x27 -#define GB_POWER_SUPPLY_PROP_ENERGY_NOW 0x28 -#define GB_POWER_SUPPLY_PROP_ENERGY_AVG 0x29 -#define GB_POWER_SUPPLY_PROP_CAPACITY 0x2A -#define GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN 0x2B -#define GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX 0x2C -#define GB_POWER_SUPPLY_PROP_CAPACITY_LEVEL 0x2D -#define GB_POWER_SUPPLY_PROP_TEMP 0x2E -#define GB_POWER_SUPPLY_PROP_TEMP_MAX 0x2F -#define GB_POWER_SUPPLY_PROP_TEMP_MIN 0x30 -#define GB_POWER_SUPPLY_PROP_TEMP_ALERT_MIN 0x31 -#define GB_POWER_SUPPLY_PROP_TEMP_ALERT_MAX 0x32 -#define GB_POWER_SUPPLY_PROP_TEMP_AMBIENT 0x33 -#define GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN 0x34 -#define GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX 0x35 -#define GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW 0x36 -#define GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG 0x37 -#define GB_POWER_SUPPLY_PROP_TIME_TO_FULL_NOW 0x38 -#define GB_POWER_SUPPLY_PROP_TIME_TO_FULL_AVG 0x39 -#define GB_POWER_SUPPLY_PROP_TYPE 0x3A -#define GB_POWER_SUPPLY_PROP_SCOPE 0x3B -#define GB_POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT 0x3C -#define GB_POWER_SUPPLY_PROP_CALIBRATE 0x3D - __u8 is_writeable; -} __packed; - -struct gb_power_supply_get_property_descriptors_request { - __u8 psy_id; -} __packed; - -struct gb_power_supply_get_property_descriptors_response { - __u8 properties_count; - struct gb_power_supply_props_desc props[]; -} __packed; - -struct gb_power_supply_get_property_request { - __u8 psy_id; - __u8 property; -} __packed; - -struct gb_power_supply_get_property_response { - __le32 prop_val; -}; - -struct gb_power_supply_set_property_request { - __u8 psy_id; - __u8 property; - __le32 prop_val; -} __packed; - -struct gb_power_supply_event_request { - __u8 psy_id; - __u8 event; -#define GB_POWER_SUPPLY_UPDATE 0x01 -} __packed; - - -/* HID */ - -/* Greybus HID operation types */ -#define GB_HID_TYPE_GET_DESC 0x02 -#define GB_HID_TYPE_GET_REPORT_DESC 0x03 -#define GB_HID_TYPE_PWR_ON 0x04 -#define GB_HID_TYPE_PWR_OFF 0x05 -#define GB_HID_TYPE_GET_REPORT 0x06 -#define GB_HID_TYPE_SET_REPORT 0x07 -#define GB_HID_TYPE_IRQ_EVENT 0x08 - -/* Report type */ -#define GB_HID_INPUT_REPORT 0 -#define GB_HID_OUTPUT_REPORT 1 -#define GB_HID_FEATURE_REPORT 2 - -/* Different request/response structures */ -/* HID get descriptor response */ -struct gb_hid_desc_response { - __u8 bLength; - __le16 wReportDescLength; - __le16 bcdHID; - __le16 wProductID; - __le16 wVendorID; - __u8 bCountryCode; -} __packed; - -/* HID get report request/response */ -struct gb_hid_get_report_request { - __u8 report_type; - __u8 report_id; -} __packed; - -/* HID set report request */ -struct gb_hid_set_report_request { - __u8 report_type; - __u8 report_id; - __u8 report[0]; -} __packed; - -/* HID input report request, via interrupt pipe */ -struct gb_hid_input_report_request { - __u8 report[0]; -} __packed; - - -/* I2C */ - -/* Greybus i2c request types */ -#define GB_I2C_TYPE_FUNCTIONALITY 0x02 -#define GB_I2C_TYPE_TRANSFER 0x05 - -/* functionality request has no payload */ -struct gb_i2c_functionality_response { - __le32 functionality; -} __packed; - -/* - * Outgoing data immediately follows the op count and ops array. - * The data for each write (master -> slave) op in the array is sent - * in order, with no (e.g. pad) bytes separating them. - * - * Short reads cause the entire transfer request to fail So response - * payload consists only of bytes read, and the number of bytes is - * exactly what was specified in the corresponding op. Like - * outgoing data, the incoming data is in order and contiguous. - */ -struct gb_i2c_transfer_op { - __le16 addr; - __le16 flags; - __le16 size; -} __packed; - -struct gb_i2c_transfer_request { - __le16 op_count; - struct gb_i2c_transfer_op ops[0]; /* op_count of these */ -} __packed; -struct gb_i2c_transfer_response { - __u8 data[0]; /* inbound data */ -} __packed; - - -/* GPIO */ - -/* Greybus GPIO request types */ -#define GB_GPIO_TYPE_LINE_COUNT 0x02 -#define GB_GPIO_TYPE_ACTIVATE 0x03 -#define GB_GPIO_TYPE_DEACTIVATE 0x04 -#define GB_GPIO_TYPE_GET_DIRECTION 0x05 -#define GB_GPIO_TYPE_DIRECTION_IN 0x06 -#define GB_GPIO_TYPE_DIRECTION_OUT 0x07 -#define GB_GPIO_TYPE_GET_VALUE 0x08 -#define GB_GPIO_TYPE_SET_VALUE 0x09 -#define GB_GPIO_TYPE_SET_DEBOUNCE 0x0a -#define GB_GPIO_TYPE_IRQ_TYPE 0x0b -#define GB_GPIO_TYPE_IRQ_MASK 0x0c -#define GB_GPIO_TYPE_IRQ_UNMASK 0x0d -#define GB_GPIO_TYPE_IRQ_EVENT 0x0e - -#define GB_GPIO_IRQ_TYPE_NONE 0x00 -#define GB_GPIO_IRQ_TYPE_EDGE_RISING 0x01 -#define GB_GPIO_IRQ_TYPE_EDGE_FALLING 0x02 -#define GB_GPIO_IRQ_TYPE_EDGE_BOTH 0x03 -#define GB_GPIO_IRQ_TYPE_LEVEL_HIGH 0x04 -#define GB_GPIO_IRQ_TYPE_LEVEL_LOW 0x08 - -/* line count request has no payload */ -struct gb_gpio_line_count_response { - __u8 count; -} __packed; - -struct gb_gpio_activate_request { - __u8 which; -} __packed; -/* activate response has no payload */ - -struct gb_gpio_deactivate_request { - __u8 which; -} __packed; -/* deactivate response has no payload */ - -struct gb_gpio_get_direction_request { - __u8 which; -} __packed; -struct gb_gpio_get_direction_response { - __u8 direction; -} __packed; - -struct gb_gpio_direction_in_request { - __u8 which; -} __packed; -/* direction in response has no payload */ - -struct gb_gpio_direction_out_request { - __u8 which; - __u8 value; -} __packed; -/* direction out response has no payload */ - -struct gb_gpio_get_value_request { - __u8 which; -} __packed; -struct gb_gpio_get_value_response { - __u8 value; -} __packed; - -struct gb_gpio_set_value_request { - __u8 which; - __u8 value; -} __packed; -/* set value response has no payload */ - -struct gb_gpio_set_debounce_request { - __u8 which; - __le16 usec; -} __packed; -/* debounce response has no payload */ - -struct gb_gpio_irq_type_request { - __u8 which; - __u8 type; -} __packed; -/* irq type response has no payload */ - -struct gb_gpio_irq_mask_request { - __u8 which; -} __packed; -/* irq mask response has no payload */ - -struct gb_gpio_irq_unmask_request { - __u8 which; -} __packed; -/* irq unmask response has no payload */ - -/* irq event requests originate on another module and are handled on the AP */ -struct gb_gpio_irq_event_request { - __u8 which; -} __packed; -/* irq event has no response */ - - -/* PWM */ - -/* Greybus PWM operation types */ -#define GB_PWM_TYPE_PWM_COUNT 0x02 -#define GB_PWM_TYPE_ACTIVATE 0x03 -#define GB_PWM_TYPE_DEACTIVATE 0x04 -#define GB_PWM_TYPE_CONFIG 0x05 -#define GB_PWM_TYPE_POLARITY 0x06 -#define GB_PWM_TYPE_ENABLE 0x07 -#define GB_PWM_TYPE_DISABLE 0x08 - -/* pwm count request has no payload */ -struct gb_pwm_count_response { - __u8 count; -} __packed; - -struct gb_pwm_activate_request { - __u8 which; -} __packed; - -struct gb_pwm_deactivate_request { - __u8 which; -} __packed; - -struct gb_pwm_config_request { - __u8 which; - __le32 duty; - __le32 period; -} __packed; - -struct gb_pwm_polarity_request { - __u8 which; - __u8 polarity; -} __packed; - -struct gb_pwm_enable_request { - __u8 which; -} __packed; - -struct gb_pwm_disable_request { - __u8 which; -} __packed; - -/* SPI */ - -/* Should match up with modes in linux/spi/spi.h */ -#define GB_SPI_MODE_CPHA 0x01 /* clock phase */ -#define GB_SPI_MODE_CPOL 0x02 /* clock polarity */ -#define GB_SPI_MODE_MODE_0 (0 | 0) /* (original MicroWire) */ -#define GB_SPI_MODE_MODE_1 (0 | GB_SPI_MODE_CPHA) -#define GB_SPI_MODE_MODE_2 (GB_SPI_MODE_CPOL | 0) -#define GB_SPI_MODE_MODE_3 (GB_SPI_MODE_CPOL | GB_SPI_MODE_CPHA) -#define GB_SPI_MODE_CS_HIGH 0x04 /* chipselect active high? */ -#define GB_SPI_MODE_LSB_FIRST 0x08 /* per-word bits-on-wire */ -#define GB_SPI_MODE_3WIRE 0x10 /* SI/SO signals shared */ -#define GB_SPI_MODE_LOOP 0x20 /* loopback mode */ -#define GB_SPI_MODE_NO_CS 0x40 /* 1 dev/bus, no chipselect */ -#define GB_SPI_MODE_READY 0x80 /* slave pulls low to pause */ - -/* Should match up with flags in linux/spi/spi.h */ -#define GB_SPI_FLAG_HALF_DUPLEX BIT(0) /* can't do full duplex */ -#define GB_SPI_FLAG_NO_RX BIT(1) /* can't do buffer read */ -#define GB_SPI_FLAG_NO_TX BIT(2) /* can't do buffer write */ - -/* Greybus spi operation types */ -#define GB_SPI_TYPE_MASTER_CONFIG 0x02 -#define GB_SPI_TYPE_DEVICE_CONFIG 0x03 -#define GB_SPI_TYPE_TRANSFER 0x04 - -/* mode request has no payload */ -struct gb_spi_master_config_response { - __le32 bits_per_word_mask; - __le32 min_speed_hz; - __le32 max_speed_hz; - __le16 mode; - __le16 flags; - __u8 num_chipselect; -} __packed; - -struct gb_spi_device_config_request { - __u8 chip_select; -} __packed; - -struct gb_spi_device_config_response { - __le16 mode; - __u8 bits_per_word; - __le32 max_speed_hz; - __u8 device_type; -#define GB_SPI_SPI_DEV 0x00 -#define GB_SPI_SPI_NOR 0x01 -#define GB_SPI_SPI_MODALIAS 0x02 - __u8 name[32]; -} __packed; - -/** - * struct gb_spi_transfer - a read/write buffer pair - * @speed_hz: Select a speed other than the device default for this transfer. If - * 0 the default (from @spi_device) is used. - * @len: size of rx and tx buffers (in bytes) - * @delay_usecs: microseconds to delay after this transfer before (optionally) - * changing the chipselect status, then starting the next transfer or - * completing this spi_message. - * @cs_change: affects chipselect after this transfer completes - * @bits_per_word: select a bits_per_word other than the device default for this - * transfer. If 0 the default (from @spi_device) is used. - */ -struct gb_spi_transfer { - __le32 speed_hz; - __le32 len; - __le16 delay_usecs; - __u8 cs_change; - __u8 bits_per_word; - __u8 xfer_flags; -#define GB_SPI_XFER_READ 0x01 -#define GB_SPI_XFER_WRITE 0x02 -#define GB_SPI_XFER_INPROGRESS 0x04 -} __packed; - -struct gb_spi_transfer_request { - __u8 chip_select; /* of the spi device */ - __u8 mode; /* of the spi device */ - __le16 count; - struct gb_spi_transfer transfers[0]; /* count of these */ -} __packed; - -struct gb_spi_transfer_response { - __u8 data[0]; /* inbound data */ -} __packed; - -/* Version of the Greybus SVC protocol we support */ -#define GB_SVC_VERSION_MAJOR 0x00 -#define GB_SVC_VERSION_MINOR 0x01 - -/* Greybus SVC request types */ -#define GB_SVC_TYPE_PROTOCOL_VERSION 0x01 -#define GB_SVC_TYPE_SVC_HELLO 0x02 -#define GB_SVC_TYPE_INTF_DEVICE_ID 0x03 -#define GB_SVC_TYPE_INTF_RESET 0x06 -#define GB_SVC_TYPE_CONN_CREATE 0x07 -#define GB_SVC_TYPE_CONN_DESTROY 0x08 -#define GB_SVC_TYPE_DME_PEER_GET 0x09 -#define GB_SVC_TYPE_DME_PEER_SET 0x0a -#define GB_SVC_TYPE_ROUTE_CREATE 0x0b -#define GB_SVC_TYPE_ROUTE_DESTROY 0x0c -#define GB_SVC_TYPE_TIMESYNC_ENABLE 0x0d -#define GB_SVC_TYPE_TIMESYNC_DISABLE 0x0e -#define GB_SVC_TYPE_TIMESYNC_AUTHORITATIVE 0x0f -#define GB_SVC_TYPE_INTF_SET_PWRM 0x10 -#define GB_SVC_TYPE_INTF_EJECT 0x11 -#define GB_SVC_TYPE_PING 0x13 -#define GB_SVC_TYPE_PWRMON_RAIL_COUNT_GET 0x14 -#define GB_SVC_TYPE_PWRMON_RAIL_NAMES_GET 0x15 -#define GB_SVC_TYPE_PWRMON_SAMPLE_GET 0x16 -#define GB_SVC_TYPE_PWRMON_INTF_SAMPLE_GET 0x17 -#define GB_SVC_TYPE_TIMESYNC_WAKE_PINS_ACQUIRE 0x18 -#define GB_SVC_TYPE_TIMESYNC_WAKE_PINS_RELEASE 0x19 -#define GB_SVC_TYPE_TIMESYNC_PING 0x1a -#define GB_SVC_TYPE_MODULE_INSERTED 0x1f -#define GB_SVC_TYPE_MODULE_REMOVED 0x20 -#define GB_SVC_TYPE_INTF_VSYS_ENABLE 0x21 -#define GB_SVC_TYPE_INTF_VSYS_DISABLE 0x22 -#define GB_SVC_TYPE_INTF_REFCLK_ENABLE 0x23 -#define GB_SVC_TYPE_INTF_REFCLK_DISABLE 0x24 -#define GB_SVC_TYPE_INTF_UNIPRO_ENABLE 0x25 -#define GB_SVC_TYPE_INTF_UNIPRO_DISABLE 0x26 -#define GB_SVC_TYPE_INTF_ACTIVATE 0x27 -#define GB_SVC_TYPE_INTF_RESUME 0x28 -#define GB_SVC_TYPE_INTF_MAILBOX_EVENT 0x29 -#define GB_SVC_TYPE_INTF_OOPS 0x2a - -/* Greybus SVC protocol status values */ -#define GB_SVC_OP_SUCCESS 0x00 -#define GB_SVC_OP_UNKNOWN_ERROR 0x01 -#define GB_SVC_INTF_NOT_DETECTED 0x02 -#define GB_SVC_INTF_NO_UPRO_LINK 0x03 -#define GB_SVC_INTF_UPRO_NOT_DOWN 0x04 -#define GB_SVC_INTF_UPRO_NOT_HIBERNATED 0x05 -#define GB_SVC_INTF_NO_V_SYS 0x06 -#define GB_SVC_INTF_V_CHG 0x07 -#define GB_SVC_INTF_WAKE_BUSY 0x08 -#define GB_SVC_INTF_NO_REFCLK 0x09 -#define GB_SVC_INTF_RELEASING 0x0a -#define GB_SVC_INTF_NO_ORDER 0x0b -#define GB_SVC_INTF_MBOX_SET 0x0c -#define GB_SVC_INTF_BAD_MBOX 0x0d -#define GB_SVC_INTF_OP_TIMEOUT 0x0e -#define GB_SVC_PWRMON_OP_NOT_PRESENT 0x0f - -struct gb_svc_version_request { - __u8 major; - __u8 minor; -} __packed; - -struct gb_svc_version_response { - __u8 major; - __u8 minor; -} __packed; - -/* SVC protocol hello request */ -struct gb_svc_hello_request { - __le16 endo_id; - __u8 interface_id; -} __packed; -/* hello response has no payload */ - -struct gb_svc_intf_device_id_request { - __u8 intf_id; - __u8 device_id; -} __packed; -/* device id response has no payload */ - -struct gb_svc_intf_reset_request { - __u8 intf_id; -} __packed; -/* interface reset response has no payload */ - -struct gb_svc_intf_eject_request { - __u8 intf_id; -} __packed; -/* interface eject response has no payload */ - -struct gb_svc_conn_create_request { - __u8 intf1_id; - __le16 cport1_id; - __u8 intf2_id; - __le16 cport2_id; - __u8 tc; - __u8 flags; -} __packed; -/* connection create response has no payload */ - -struct gb_svc_conn_destroy_request { - __u8 intf1_id; - __le16 cport1_id; - __u8 intf2_id; - __le16 cport2_id; -} __packed; -/* connection destroy response has no payload */ - -struct gb_svc_dme_peer_get_request { - __u8 intf_id; - __le16 attr; - __le16 selector; -} __packed; - -struct gb_svc_dme_peer_get_response { - __le16 result_code; - __le32 attr_value; -} __packed; - -struct gb_svc_dme_peer_set_request { - __u8 intf_id; - __le16 attr; - __le16 selector; - __le32 value; -} __packed; - -struct gb_svc_dme_peer_set_response { - __le16 result_code; -} __packed; - -/* Greybus init-status values, currently retrieved using DME peer gets. */ -#define GB_INIT_SPI_BOOT_STARTED 0x02 -#define GB_INIT_TRUSTED_SPI_BOOT_FINISHED 0x03 -#define GB_INIT_UNTRUSTED_SPI_BOOT_FINISHED 0x04 -#define GB_INIT_BOOTROM_UNIPRO_BOOT_STARTED 0x06 -#define GB_INIT_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED 0x09 -#define GB_INIT_S2_LOADER_BOOT_STARTED 0x0D - -struct gb_svc_route_create_request { - __u8 intf1_id; - __u8 dev1_id; - __u8 intf2_id; - __u8 dev2_id; -} __packed; -/* route create response has no payload */ - -struct gb_svc_route_destroy_request { - __u8 intf1_id; - __u8 intf2_id; -} __packed; -/* route destroy response has no payload */ - -/* used for svc_intf_vsys_{enable,disable} */ -struct gb_svc_intf_vsys_request { - __u8 intf_id; -} __packed; - -struct gb_svc_intf_vsys_response { - __u8 result_code; -#define GB_SVC_INTF_VSYS_OK 0x00 - /* 0x01 is reserved */ -#define GB_SVC_INTF_VSYS_FAIL 0x02 -} __packed; - -/* used for svc_intf_refclk_{enable,disable} */ -struct gb_svc_intf_refclk_request { - __u8 intf_id; -} __packed; - -struct gb_svc_intf_refclk_response { - __u8 result_code; -#define GB_SVC_INTF_REFCLK_OK 0x00 - /* 0x01 is reserved */ -#define GB_SVC_INTF_REFCLK_FAIL 0x02 -} __packed; - -/* used for svc_intf_unipro_{enable,disable} */ -struct gb_svc_intf_unipro_request { - __u8 intf_id; -} __packed; - -struct gb_svc_intf_unipro_response { - __u8 result_code; -#define GB_SVC_INTF_UNIPRO_OK 0x00 - /* 0x01 is reserved */ -#define GB_SVC_INTF_UNIPRO_FAIL 0x02 -#define GB_SVC_INTF_UNIPRO_NOT_OFF 0x03 -} __packed; - -#define GB_SVC_UNIPRO_FAST_MODE 0x01 -#define GB_SVC_UNIPRO_SLOW_MODE 0x02 -#define GB_SVC_UNIPRO_FAST_AUTO_MODE 0x04 -#define GB_SVC_UNIPRO_SLOW_AUTO_MODE 0x05 -#define GB_SVC_UNIPRO_MODE_UNCHANGED 0x07 -#define GB_SVC_UNIPRO_HIBERNATE_MODE 0x11 -#define GB_SVC_UNIPRO_OFF_MODE 0x12 - -#define GB_SVC_SMALL_AMPLITUDE 0x01 -#define GB_SVC_LARGE_AMPLITUDE 0x02 - -#define GB_SVC_NO_DE_EMPHASIS 0x00 -#define GB_SVC_SMALL_DE_EMPHASIS 0x01 -#define GB_SVC_LARGE_DE_EMPHASIS 0x02 - -#define GB_SVC_PWRM_RXTERMINATION 0x01 -#define GB_SVC_PWRM_TXTERMINATION 0x02 -#define GB_SVC_PWRM_LINE_RESET 0x04 -#define GB_SVC_PWRM_SCRAMBLING 0x20 - -#define GB_SVC_PWRM_QUIRK_HSSER 0x00000001 - -#define GB_SVC_UNIPRO_HS_SERIES_A 0x01 -#define GB_SVC_UNIPRO_HS_SERIES_B 0x02 - -#define GB_SVC_SETPWRM_PWR_OK 0x00 -#define GB_SVC_SETPWRM_PWR_LOCAL 0x01 -#define GB_SVC_SETPWRM_PWR_REMOTE 0x02 -#define GB_SVC_SETPWRM_PWR_BUSY 0x03 -#define GB_SVC_SETPWRM_PWR_ERROR_CAP 0x04 -#define GB_SVC_SETPWRM_PWR_FATAL_ERROR 0x05 - -struct gb_svc_l2_timer_cfg { - __le16 tsb_fc0_protection_timeout; - __le16 tsb_tc0_replay_timeout; - __le16 tsb_afc0_req_timeout; - __le16 tsb_fc1_protection_timeout; - __le16 tsb_tc1_replay_timeout; - __le16 tsb_afc1_req_timeout; - __le16 reserved_for_tc2[3]; - __le16 reserved_for_tc3[3]; -} __packed; - -struct gb_svc_intf_set_pwrm_request { - __u8 intf_id; - __u8 hs_series; - __u8 tx_mode; - __u8 tx_gear; - __u8 tx_nlanes; - __u8 tx_amplitude; - __u8 tx_hs_equalizer; - __u8 rx_mode; - __u8 rx_gear; - __u8 rx_nlanes; - __u8 flags; - __le32 quirks; - struct gb_svc_l2_timer_cfg local_l2timerdata, remote_l2timerdata; -} __packed; - -struct gb_svc_intf_set_pwrm_response { - __u8 result_code; -} __packed; - -struct gb_svc_key_event_request { - __le16 key_code; -#define GB_KEYCODE_ARA 0x00 - - __u8 key_event; -#define GB_SVC_KEY_RELEASED 0x00 -#define GB_SVC_KEY_PRESSED 0x01 -} __packed; - -#define GB_SVC_PWRMON_MAX_RAIL_COUNT 254 - -struct gb_svc_pwrmon_rail_count_get_response { - __u8 rail_count; -} __packed; - -#define GB_SVC_PWRMON_RAIL_NAME_BUFSIZE 32 - -struct gb_svc_pwrmon_rail_names_get_response { - __u8 status; - __u8 name[0][GB_SVC_PWRMON_RAIL_NAME_BUFSIZE]; -} __packed; - -#define GB_SVC_PWRMON_TYPE_CURR 0x01 -#define GB_SVC_PWRMON_TYPE_VOL 0x02 -#define GB_SVC_PWRMON_TYPE_PWR 0x03 - -#define GB_SVC_PWRMON_GET_SAMPLE_OK 0x00 -#define GB_SVC_PWRMON_GET_SAMPLE_INVAL 0x01 -#define GB_SVC_PWRMON_GET_SAMPLE_NOSUPP 0x02 -#define GB_SVC_PWRMON_GET_SAMPLE_HWERR 0x03 - -struct gb_svc_pwrmon_sample_get_request { - __u8 rail_id; - __u8 measurement_type; -} __packed; - -struct gb_svc_pwrmon_sample_get_response { - __u8 result; - __le32 measurement; -} __packed; - -struct gb_svc_pwrmon_intf_sample_get_request { - __u8 intf_id; - __u8 measurement_type; -} __packed; - -struct gb_svc_pwrmon_intf_sample_get_response { - __u8 result; - __le32 measurement; -} __packed; - -#define GB_SVC_MODULE_INSERTED_FLAG_NO_PRIMARY 0x0001 - -struct gb_svc_module_inserted_request { - __u8 primary_intf_id; - __u8 intf_count; - __le16 flags; -} __packed; -/* module_inserted response has no payload */ - -struct gb_svc_module_removed_request { - __u8 primary_intf_id; -} __packed; -/* module_removed response has no payload */ - -struct gb_svc_intf_activate_request { - __u8 intf_id; -} __packed; - -#define GB_SVC_INTF_TYPE_UNKNOWN 0x00 -#define GB_SVC_INTF_TYPE_DUMMY 0x01 -#define GB_SVC_INTF_TYPE_UNIPRO 0x02 -#define GB_SVC_INTF_TYPE_GREYBUS 0x03 - -struct gb_svc_intf_activate_response { - __u8 status; - __u8 intf_type; -} __packed; - -struct gb_svc_intf_resume_request { - __u8 intf_id; -} __packed; - -struct gb_svc_intf_resume_response { - __u8 status; -} __packed; - -#define GB_SVC_INTF_MAILBOX_NONE 0x00 -#define GB_SVC_INTF_MAILBOX_AP 0x01 -#define GB_SVC_INTF_MAILBOX_GREYBUS 0x02 - -struct gb_svc_intf_mailbox_event_request { - __u8 intf_id; - __le16 result_code; - __le32 mailbox; -} __packed; -/* intf_mailbox_event response has no payload */ - -struct gb_svc_intf_oops_request { - __u8 intf_id; - __u8 reason; -} __packed; -/* intf_oops response has no payload */ - - -/* RAW */ - -/* Greybus raw request types */ -#define GB_RAW_TYPE_SEND 0x02 - -struct gb_raw_send_request { - __le32 len; - __u8 data[0]; -} __packed; - - -/* UART */ - -/* Greybus UART operation types */ -#define GB_UART_TYPE_SEND_DATA 0x02 -#define GB_UART_TYPE_RECEIVE_DATA 0x03 /* Unsolicited data */ -#define GB_UART_TYPE_SET_LINE_CODING 0x04 -#define GB_UART_TYPE_SET_CONTROL_LINE_STATE 0x05 -#define GB_UART_TYPE_SEND_BREAK 0x06 -#define GB_UART_TYPE_SERIAL_STATE 0x07 /* Unsolicited data */ -#define GB_UART_TYPE_RECEIVE_CREDITS 0x08 -#define GB_UART_TYPE_FLUSH_FIFOS 0x09 - -/* Represents data from AP -> Module */ -struct gb_uart_send_data_request { - __le16 size; - __u8 data[0]; -} __packed; - -/* recv-data-request flags */ -#define GB_UART_RECV_FLAG_FRAMING 0x01 /* Framing error */ -#define GB_UART_RECV_FLAG_PARITY 0x02 /* Parity error */ -#define GB_UART_RECV_FLAG_OVERRUN 0x04 /* Overrun error */ -#define GB_UART_RECV_FLAG_BREAK 0x08 /* Break */ - -/* Represents data from Module -> AP */ -struct gb_uart_recv_data_request { - __le16 size; - __u8 flags; - __u8 data[0]; -} __packed; - -struct gb_uart_receive_credits_request { - __le16 count; -} __packed; - -struct gb_uart_set_line_coding_request { - __le32 rate; - __u8 format; -#define GB_SERIAL_1_STOP_BITS 0 -#define GB_SERIAL_1_5_STOP_BITS 1 -#define GB_SERIAL_2_STOP_BITS 2 - - __u8 parity; -#define GB_SERIAL_NO_PARITY 0 -#define GB_SERIAL_ODD_PARITY 1 -#define GB_SERIAL_EVEN_PARITY 2 -#define GB_SERIAL_MARK_PARITY 3 -#define GB_SERIAL_SPACE_PARITY 4 - - __u8 data_bits; - - __u8 flow_control; -#define GB_SERIAL_AUTO_RTSCTS_EN 0x1 -} __packed; - -/* output control lines */ -#define GB_UART_CTRL_DTR 0x01 -#define GB_UART_CTRL_RTS 0x02 - -struct gb_uart_set_control_line_state_request { - __u8 control; -} __packed; - -struct gb_uart_set_break_request { - __u8 state; -} __packed; - -/* input control lines and line errors */ -#define GB_UART_CTRL_DCD 0x01 -#define GB_UART_CTRL_DSR 0x02 -#define GB_UART_CTRL_RI 0x04 - -struct gb_uart_serial_state_request { - __u8 control; -} __packed; - -struct gb_uart_serial_flush_request { - __u8 flags; -#define GB_SERIAL_FLAG_FLUSH_TRANSMITTER 0x01 -#define GB_SERIAL_FLAG_FLUSH_RECEIVER 0x02 -} __packed; - -/* Loopback */ - -/* Greybus loopback request types */ -#define GB_LOOPBACK_TYPE_PING 0x02 -#define GB_LOOPBACK_TYPE_TRANSFER 0x03 -#define GB_LOOPBACK_TYPE_SINK 0x04 - -/* - * Loopback request/response header format should be identical - * to simplify bandwidth and data movement analysis. - */ -struct gb_loopback_transfer_request { - __le32 len; - __le32 reserved0; - __le32 reserved1; - __u8 data[0]; -} __packed; - -struct gb_loopback_transfer_response { - __le32 len; - __le32 reserved0; - __le32 reserved1; - __u8 data[0]; -} __packed; - -/* SDIO */ -/* Greybus SDIO operation types */ -#define GB_SDIO_TYPE_GET_CAPABILITIES 0x02 -#define GB_SDIO_TYPE_SET_IOS 0x03 -#define GB_SDIO_TYPE_COMMAND 0x04 -#define GB_SDIO_TYPE_TRANSFER 0x05 -#define GB_SDIO_TYPE_EVENT 0x06 - -/* get caps response: request has no payload */ -struct gb_sdio_get_caps_response { - __le32 caps; -#define GB_SDIO_CAP_NONREMOVABLE 0x00000001 -#define GB_SDIO_CAP_4_BIT_DATA 0x00000002 -#define GB_SDIO_CAP_8_BIT_DATA 0x00000004 -#define GB_SDIO_CAP_MMC_HS 0x00000008 -#define GB_SDIO_CAP_SD_HS 0x00000010 -#define GB_SDIO_CAP_ERASE 0x00000020 -#define GB_SDIO_CAP_1_2V_DDR 0x00000040 -#define GB_SDIO_CAP_1_8V_DDR 0x00000080 -#define GB_SDIO_CAP_POWER_OFF_CARD 0x00000100 -#define GB_SDIO_CAP_UHS_SDR12 0x00000200 -#define GB_SDIO_CAP_UHS_SDR25 0x00000400 -#define GB_SDIO_CAP_UHS_SDR50 0x00000800 -#define GB_SDIO_CAP_UHS_SDR104 0x00001000 -#define GB_SDIO_CAP_UHS_DDR50 0x00002000 -#define GB_SDIO_CAP_DRIVER_TYPE_A 0x00004000 -#define GB_SDIO_CAP_DRIVER_TYPE_C 0x00008000 -#define GB_SDIO_CAP_DRIVER_TYPE_D 0x00010000 -#define GB_SDIO_CAP_HS200_1_2V 0x00020000 -#define GB_SDIO_CAP_HS200_1_8V 0x00040000 -#define GB_SDIO_CAP_HS400_1_2V 0x00080000 -#define GB_SDIO_CAP_HS400_1_8V 0x00100000 - - /* see possible values below at vdd */ - __le32 ocr; - __le32 f_min; - __le32 f_max; - __le16 max_blk_count; - __le16 max_blk_size; -} __packed; - -/* set ios request: response has no payload */ -struct gb_sdio_set_ios_request { - __le32 clock; - __le32 vdd; -#define GB_SDIO_VDD_165_195 0x00000001 -#define GB_SDIO_VDD_20_21 0x00000002 -#define GB_SDIO_VDD_21_22 0x00000004 -#define GB_SDIO_VDD_22_23 0x00000008 -#define GB_SDIO_VDD_23_24 0x00000010 -#define GB_SDIO_VDD_24_25 0x00000020 -#define GB_SDIO_VDD_25_26 0x00000040 -#define GB_SDIO_VDD_26_27 0x00000080 -#define GB_SDIO_VDD_27_28 0x00000100 -#define GB_SDIO_VDD_28_29 0x00000200 -#define GB_SDIO_VDD_29_30 0x00000400 -#define GB_SDIO_VDD_30_31 0x00000800 -#define GB_SDIO_VDD_31_32 0x00001000 -#define GB_SDIO_VDD_32_33 0x00002000 -#define GB_SDIO_VDD_33_34 0x00004000 -#define GB_SDIO_VDD_34_35 0x00008000 -#define GB_SDIO_VDD_35_36 0x00010000 - - __u8 bus_mode; -#define GB_SDIO_BUSMODE_OPENDRAIN 0x00 -#define GB_SDIO_BUSMODE_PUSHPULL 0x01 - - __u8 power_mode; -#define GB_SDIO_POWER_OFF 0x00 -#define GB_SDIO_POWER_UP 0x01 -#define GB_SDIO_POWER_ON 0x02 -#define GB_SDIO_POWER_UNDEFINED 0x03 - - __u8 bus_width; -#define GB_SDIO_BUS_WIDTH_1 0x00 -#define GB_SDIO_BUS_WIDTH_4 0x02 -#define GB_SDIO_BUS_WIDTH_8 0x03 - - __u8 timing; -#define GB_SDIO_TIMING_LEGACY 0x00 -#define GB_SDIO_TIMING_MMC_HS 0x01 -#define GB_SDIO_TIMING_SD_HS 0x02 -#define GB_SDIO_TIMING_UHS_SDR12 0x03 -#define GB_SDIO_TIMING_UHS_SDR25 0x04 -#define GB_SDIO_TIMING_UHS_SDR50 0x05 -#define GB_SDIO_TIMING_UHS_SDR104 0x06 -#define GB_SDIO_TIMING_UHS_DDR50 0x07 -#define GB_SDIO_TIMING_MMC_DDR52 0x08 -#define GB_SDIO_TIMING_MMC_HS200 0x09 -#define GB_SDIO_TIMING_MMC_HS400 0x0A - - __u8 signal_voltage; -#define GB_SDIO_SIGNAL_VOLTAGE_330 0x00 -#define GB_SDIO_SIGNAL_VOLTAGE_180 0x01 -#define GB_SDIO_SIGNAL_VOLTAGE_120 0x02 - - __u8 drv_type; -#define GB_SDIO_SET_DRIVER_TYPE_B 0x00 -#define GB_SDIO_SET_DRIVER_TYPE_A 0x01 -#define GB_SDIO_SET_DRIVER_TYPE_C 0x02 -#define GB_SDIO_SET_DRIVER_TYPE_D 0x03 -} __packed; - -/* command request */ -struct gb_sdio_command_request { - __u8 cmd; - __u8 cmd_flags; -#define GB_SDIO_RSP_NONE 0x00 -#define GB_SDIO_RSP_PRESENT 0x01 -#define GB_SDIO_RSP_136 0x02 -#define GB_SDIO_RSP_CRC 0x04 -#define GB_SDIO_RSP_BUSY 0x08 -#define GB_SDIO_RSP_OPCODE 0x10 - - __u8 cmd_type; -#define GB_SDIO_CMD_AC 0x00 -#define GB_SDIO_CMD_ADTC 0x01 -#define GB_SDIO_CMD_BC 0x02 -#define GB_SDIO_CMD_BCR 0x03 - - __le32 cmd_arg; - __le16 data_blocks; - __le16 data_blksz; -} __packed; - -struct gb_sdio_command_response { - __le32 resp[4]; -} __packed; - -/* transfer request */ -struct gb_sdio_transfer_request { - __u8 data_flags; -#define GB_SDIO_DATA_WRITE 0x01 -#define GB_SDIO_DATA_READ 0x02 -#define GB_SDIO_DATA_STREAM 0x04 - - __le16 data_blocks; - __le16 data_blksz; - __u8 data[0]; -} __packed; - -struct gb_sdio_transfer_response { - __le16 data_blocks; - __le16 data_blksz; - __u8 data[0]; -} __packed; - -/* event request: generated by module and is defined as unidirectional */ -struct gb_sdio_event_request { - __u8 event; -#define GB_SDIO_CARD_INSERTED 0x01 -#define GB_SDIO_CARD_REMOVED 0x02 -#define GB_SDIO_WP 0x04 -} __packed; - -/* Camera */ - -/* Greybus Camera request types */ -#define GB_CAMERA_TYPE_CAPABILITIES 0x02 -#define GB_CAMERA_TYPE_CONFIGURE_STREAMS 0x03 -#define GB_CAMERA_TYPE_CAPTURE 0x04 -#define GB_CAMERA_TYPE_FLUSH 0x05 -#define GB_CAMERA_TYPE_METADATA 0x06 - -#define GB_CAMERA_MAX_STREAMS 4 -#define GB_CAMERA_MAX_SETTINGS_SIZE 8192 - -/* Greybus Camera Configure Streams request payload */ -struct gb_camera_stream_config_request { - __le16 width; - __le16 height; - __le16 format; - __le16 padding; -} __packed; - -struct gb_camera_configure_streams_request { - __u8 num_streams; - __u8 flags; -#define GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY 0x01 - __le16 padding; - struct gb_camera_stream_config_request config[0]; -} __packed; - -/* Greybus Camera Configure Streams response payload */ -struct gb_camera_stream_config_response { - __le16 width; - __le16 height; - __le16 format; - __u8 virtual_channel; - __u8 data_type[2]; - __le16 max_pkt_size; - __u8 padding; - __le32 max_size; -} __packed; - -struct gb_camera_configure_streams_response { - __u8 num_streams; -#define GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED 0x01 - __u8 flags; - __u8 padding[2]; - __le32 data_rate; - struct gb_camera_stream_config_response config[0]; -}; - -/* Greybus Camera Capture request payload - response has no payload */ -struct gb_camera_capture_request { - __le32 request_id; - __u8 streams; - __u8 padding; - __le16 num_frames; - __u8 settings[0]; -} __packed; - -/* Greybus Camera Flush response payload - request has no payload */ -struct gb_camera_flush_response { - __le32 request_id; -} __packed; - -/* Greybus Camera Metadata request payload - operation has no response */ -struct gb_camera_metadata_request { - __le32 request_id; - __le16 frame_number; - __u8 stream; - __u8 padding; - __u8 metadata[0]; -} __packed; - -/* Lights */ - -/* Greybus Lights request types */ -#define GB_LIGHTS_TYPE_GET_LIGHTS 0x02 -#define GB_LIGHTS_TYPE_GET_LIGHT_CONFIG 0x03 -#define GB_LIGHTS_TYPE_GET_CHANNEL_CONFIG 0x04 -#define GB_LIGHTS_TYPE_GET_CHANNEL_FLASH_CONFIG 0x05 -#define GB_LIGHTS_TYPE_SET_BRIGHTNESS 0x06 -#define GB_LIGHTS_TYPE_SET_BLINK 0x07 -#define GB_LIGHTS_TYPE_SET_COLOR 0x08 -#define GB_LIGHTS_TYPE_SET_FADE 0x09 -#define GB_LIGHTS_TYPE_EVENT 0x0A -#define GB_LIGHTS_TYPE_SET_FLASH_INTENSITY 0x0B -#define GB_LIGHTS_TYPE_SET_FLASH_STROBE 0x0C -#define GB_LIGHTS_TYPE_SET_FLASH_TIMEOUT 0x0D -#define GB_LIGHTS_TYPE_GET_FLASH_FAULT 0x0E - -/* Greybus Light modes */ - -/* - * if you add any specific mode below, update also the - * GB_CHANNEL_MODE_DEFINED_RANGE value accordingly - */ -#define GB_CHANNEL_MODE_NONE 0x00000000 -#define GB_CHANNEL_MODE_BATTERY 0x00000001 -#define GB_CHANNEL_MODE_POWER 0x00000002 -#define GB_CHANNEL_MODE_WIRELESS 0x00000004 -#define GB_CHANNEL_MODE_BLUETOOTH 0x00000008 -#define GB_CHANNEL_MODE_KEYBOARD 0x00000010 -#define GB_CHANNEL_MODE_BUTTONS 0x00000020 -#define GB_CHANNEL_MODE_NOTIFICATION 0x00000040 -#define GB_CHANNEL_MODE_ATTENTION 0x00000080 -#define GB_CHANNEL_MODE_FLASH 0x00000100 -#define GB_CHANNEL_MODE_TORCH 0x00000200 -#define GB_CHANNEL_MODE_INDICATOR 0x00000400 - -/* Lights Mode valid bit values */ -#define GB_CHANNEL_MODE_DEFINED_RANGE 0x000004FF -#define GB_CHANNEL_MODE_VENDOR_RANGE 0x00F00000 - -/* Greybus Light Channels Flags */ -#define GB_LIGHT_CHANNEL_MULTICOLOR 0x00000001 -#define GB_LIGHT_CHANNEL_FADER 0x00000002 -#define GB_LIGHT_CHANNEL_BLINK 0x00000004 - -/* get count of lights in module */ -struct gb_lights_get_lights_response { - __u8 lights_count; -} __packed; - -/* light config request payload */ -struct gb_lights_get_light_config_request { - __u8 id; -} __packed; - -/* light config response payload */ -struct gb_lights_get_light_config_response { - __u8 channel_count; - __u8 name[32]; -} __packed; - -/* channel config request payload */ -struct gb_lights_get_channel_config_request { - __u8 light_id; - __u8 channel_id; -} __packed; - -/* channel flash config request payload */ -struct gb_lights_get_channel_flash_config_request { - __u8 light_id; - __u8 channel_id; -} __packed; - -/* channel config response payload */ -struct gb_lights_get_channel_config_response { - __u8 max_brightness; - __le32 flags; - __le32 color; - __u8 color_name[32]; - __le32 mode; - __u8 mode_name[32]; -} __packed; - -/* channel flash config response payload */ -struct gb_lights_get_channel_flash_config_response { - __le32 intensity_min_uA; - __le32 intensity_max_uA; - __le32 intensity_step_uA; - __le32 timeout_min_us; - __le32 timeout_max_us; - __le32 timeout_step_us; -} __packed; - -/* blink request payload: response have no payload */ -struct gb_lights_blink_request { - __u8 light_id; - __u8 channel_id; - __le16 time_on_ms; - __le16 time_off_ms; -} __packed; - -/* set brightness request payload: response have no payload */ -struct gb_lights_set_brightness_request { - __u8 light_id; - __u8 channel_id; - __u8 brightness; -} __packed; - -/* set color request payload: response have no payload */ -struct gb_lights_set_color_request { - __u8 light_id; - __u8 channel_id; - __le32 color; -} __packed; - -/* set fade request payload: response have no payload */ -struct gb_lights_set_fade_request { - __u8 light_id; - __u8 channel_id; - __u8 fade_in; - __u8 fade_out; -} __packed; - -/* event request: generated by module */ -struct gb_lights_event_request { - __u8 light_id; - __u8 event; -#define GB_LIGHTS_LIGHT_CONFIG 0x01 -} __packed; - -/* set flash intensity request payload: response have no payload */ -struct gb_lights_set_flash_intensity_request { - __u8 light_id; - __u8 channel_id; - __le32 intensity_uA; -} __packed; - -/* set flash strobe state request payload: response have no payload */ -struct gb_lights_set_flash_strobe_request { - __u8 light_id; - __u8 channel_id; - __u8 state; -} __packed; - -/* set flash timeout request payload: response have no payload */ -struct gb_lights_set_flash_timeout_request { - __u8 light_id; - __u8 channel_id; - __le32 timeout_us; -} __packed; - -/* get flash fault request payload */ -struct gb_lights_get_flash_fault_request { - __u8 light_id; - __u8 channel_id; -} __packed; - -/* get flash fault response payload */ -struct gb_lights_get_flash_fault_response { - __le32 fault; -#define GB_LIGHTS_FLASH_FAULT_OVER_VOLTAGE 0x00000000 -#define GB_LIGHTS_FLASH_FAULT_TIMEOUT 0x00000001 -#define GB_LIGHTS_FLASH_FAULT_OVER_TEMPERATURE 0x00000002 -#define GB_LIGHTS_FLASH_FAULT_SHORT_CIRCUIT 0x00000004 -#define GB_LIGHTS_FLASH_FAULT_OVER_CURRENT 0x00000008 -#define GB_LIGHTS_FLASH_FAULT_INDICATOR 0x00000010 -#define GB_LIGHTS_FLASH_FAULT_UNDER_VOLTAGE 0x00000020 -#define GB_LIGHTS_FLASH_FAULT_INPUT_VOLTAGE 0x00000040 -#define GB_LIGHTS_FLASH_FAULT_LED_OVER_TEMPERATURE 0x00000080 -} __packed; - -/* Audio */ - -#define GB_AUDIO_TYPE_GET_TOPOLOGY_SIZE 0x02 -#define GB_AUDIO_TYPE_GET_TOPOLOGY 0x03 -#define GB_AUDIO_TYPE_GET_CONTROL 0x04 -#define GB_AUDIO_TYPE_SET_CONTROL 0x05 -#define GB_AUDIO_TYPE_ENABLE_WIDGET 0x06 -#define GB_AUDIO_TYPE_DISABLE_WIDGET 0x07 -#define GB_AUDIO_TYPE_GET_PCM 0x08 -#define GB_AUDIO_TYPE_SET_PCM 0x09 -#define GB_AUDIO_TYPE_SET_TX_DATA_SIZE 0x0a - /* 0x0b unused */ -#define GB_AUDIO_TYPE_ACTIVATE_TX 0x0c -#define GB_AUDIO_TYPE_DEACTIVATE_TX 0x0d -#define GB_AUDIO_TYPE_SET_RX_DATA_SIZE 0x0e - /* 0x0f unused */ -#define GB_AUDIO_TYPE_ACTIVATE_RX 0x10 -#define GB_AUDIO_TYPE_DEACTIVATE_RX 0x11 -#define GB_AUDIO_TYPE_JACK_EVENT 0x12 -#define GB_AUDIO_TYPE_BUTTON_EVENT 0x13 -#define GB_AUDIO_TYPE_STREAMING_EVENT 0x14 -#define GB_AUDIO_TYPE_SEND_DATA 0x15 - -/* Module must be able to buffer 10ms of audio data, minimum */ -#define GB_AUDIO_SAMPLE_BUFFER_MIN_US 10000 - -#define GB_AUDIO_PCM_NAME_MAX 32 -#define AUDIO_DAI_NAME_MAX 32 -#define AUDIO_CONTROL_NAME_MAX 32 -#define AUDIO_CTL_ELEM_NAME_MAX 44 -#define AUDIO_ENUM_NAME_MAX 64 -#define AUDIO_WIDGET_NAME_MAX 32 - -/* See SNDRV_PCM_FMTBIT_* in Linux source */ -#define GB_AUDIO_PCM_FMT_S8 BIT(0) -#define GB_AUDIO_PCM_FMT_U8 BIT(1) -#define GB_AUDIO_PCM_FMT_S16_LE BIT(2) -#define GB_AUDIO_PCM_FMT_S16_BE BIT(3) -#define GB_AUDIO_PCM_FMT_U16_LE BIT(4) -#define GB_AUDIO_PCM_FMT_U16_BE BIT(5) -#define GB_AUDIO_PCM_FMT_S24_LE BIT(6) -#define GB_AUDIO_PCM_FMT_S24_BE BIT(7) -#define GB_AUDIO_PCM_FMT_U24_LE BIT(8) -#define GB_AUDIO_PCM_FMT_U24_BE BIT(9) -#define GB_AUDIO_PCM_FMT_S32_LE BIT(10) -#define GB_AUDIO_PCM_FMT_S32_BE BIT(11) -#define GB_AUDIO_PCM_FMT_U32_LE BIT(12) -#define GB_AUDIO_PCM_FMT_U32_BE BIT(13) - -/* See SNDRV_PCM_RATE_* in Linux source */ -#define GB_AUDIO_PCM_RATE_5512 BIT(0) -#define GB_AUDIO_PCM_RATE_8000 BIT(1) -#define GB_AUDIO_PCM_RATE_11025 BIT(2) -#define GB_AUDIO_PCM_RATE_16000 BIT(3) -#define GB_AUDIO_PCM_RATE_22050 BIT(4) -#define GB_AUDIO_PCM_RATE_32000 BIT(5) -#define GB_AUDIO_PCM_RATE_44100 BIT(6) -#define GB_AUDIO_PCM_RATE_48000 BIT(7) -#define GB_AUDIO_PCM_RATE_64000 BIT(8) -#define GB_AUDIO_PCM_RATE_88200 BIT(9) -#define GB_AUDIO_PCM_RATE_96000 BIT(10) -#define GB_AUDIO_PCM_RATE_176400 BIT(11) -#define GB_AUDIO_PCM_RATE_192000 BIT(12) - -#define GB_AUDIO_STREAM_TYPE_CAPTURE 0x1 -#define GB_AUDIO_STREAM_TYPE_PLAYBACK 0x2 - -#define GB_AUDIO_CTL_ELEM_ACCESS_READ BIT(0) -#define GB_AUDIO_CTL_ELEM_ACCESS_WRITE BIT(1) - -/* See SNDRV_CTL_ELEM_TYPE_* in Linux source */ -#define GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN 0x01 -#define GB_AUDIO_CTL_ELEM_TYPE_INTEGER 0x02 -#define GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED 0x03 -#define GB_AUDIO_CTL_ELEM_TYPE_INTEGER64 0x06 - -/* See SNDRV_CTL_ELEM_IFACE_* in Linux source */ -#define GB_AUDIO_CTL_ELEM_IFACE_CARD 0x00 -#define GB_AUDIO_CTL_ELEM_IFACE_HWDEP 0x01 -#define GB_AUDIO_CTL_ELEM_IFACE_MIXER 0x02 -#define GB_AUDIO_CTL_ELEM_IFACE_PCM 0x03 -#define GB_AUDIO_CTL_ELEM_IFACE_RAWMIDI 0x04 -#define GB_AUDIO_CTL_ELEM_IFACE_TIMER 0x05 -#define GB_AUDIO_CTL_ELEM_IFACE_SEQUENCER 0x06 - -/* SNDRV_CTL_ELEM_ACCESS_* in Linux source */ -#define GB_AUDIO_ACCESS_READ BIT(0) -#define GB_AUDIO_ACCESS_WRITE BIT(1) -#define GB_AUDIO_ACCESS_VOLATILE BIT(2) -#define GB_AUDIO_ACCESS_TIMESTAMP BIT(3) -#define GB_AUDIO_ACCESS_TLV_READ BIT(4) -#define GB_AUDIO_ACCESS_TLV_WRITE BIT(5) -#define GB_AUDIO_ACCESS_TLV_COMMAND BIT(6) -#define GB_AUDIO_ACCESS_INACTIVE BIT(7) -#define GB_AUDIO_ACCESS_LOCK BIT(8) -#define GB_AUDIO_ACCESS_OWNER BIT(9) - -/* enum snd_soc_dapm_type */ -#define GB_AUDIO_WIDGET_TYPE_INPUT 0x0 -#define GB_AUDIO_WIDGET_TYPE_OUTPUT 0x1 -#define GB_AUDIO_WIDGET_TYPE_MUX 0x2 -#define GB_AUDIO_WIDGET_TYPE_VIRT_MUX 0x3 -#define GB_AUDIO_WIDGET_TYPE_VALUE_MUX 0x4 -#define GB_AUDIO_WIDGET_TYPE_MIXER 0x5 -#define GB_AUDIO_WIDGET_TYPE_MIXER_NAMED_CTL 0x6 -#define GB_AUDIO_WIDGET_TYPE_PGA 0x7 -#define GB_AUDIO_WIDGET_TYPE_OUT_DRV 0x8 -#define GB_AUDIO_WIDGET_TYPE_ADC 0x9 -#define GB_AUDIO_WIDGET_TYPE_DAC 0xa -#define GB_AUDIO_WIDGET_TYPE_MICBIAS 0xb -#define GB_AUDIO_WIDGET_TYPE_MIC 0xc -#define GB_AUDIO_WIDGET_TYPE_HP 0xd -#define GB_AUDIO_WIDGET_TYPE_SPK 0xe -#define GB_AUDIO_WIDGET_TYPE_LINE 0xf -#define GB_AUDIO_WIDGET_TYPE_SWITCH 0x10 -#define GB_AUDIO_WIDGET_TYPE_VMID 0x11 -#define GB_AUDIO_WIDGET_TYPE_PRE 0x12 -#define GB_AUDIO_WIDGET_TYPE_POST 0x13 -#define GB_AUDIO_WIDGET_TYPE_SUPPLY 0x14 -#define GB_AUDIO_WIDGET_TYPE_REGULATOR_SUPPLY 0x15 -#define GB_AUDIO_WIDGET_TYPE_CLOCK_SUPPLY 0x16 -#define GB_AUDIO_WIDGET_TYPE_AIF_IN 0x17 -#define GB_AUDIO_WIDGET_TYPE_AIF_OUT 0x18 -#define GB_AUDIO_WIDGET_TYPE_SIGGEN 0x19 -#define GB_AUDIO_WIDGET_TYPE_DAI_IN 0x1a -#define GB_AUDIO_WIDGET_TYPE_DAI_OUT 0x1b -#define GB_AUDIO_WIDGET_TYPE_DAI_LINK 0x1c - -#define GB_AUDIO_WIDGET_STATE_DISABLED 0x01 -#define GB_AUDIO_WIDGET_STATE_ENAABLED 0x02 - -#define GB_AUDIO_JACK_EVENT_INSERTION 0x1 -#define GB_AUDIO_JACK_EVENT_REMOVAL 0x2 - -#define GB_AUDIO_BUTTON_EVENT_PRESS 0x1 -#define GB_AUDIO_BUTTON_EVENT_RELEASE 0x2 - -#define GB_AUDIO_STREAMING_EVENT_UNSPECIFIED 0x1 -#define GB_AUDIO_STREAMING_EVENT_HALT 0x2 -#define GB_AUDIO_STREAMING_EVENT_INTERNAL_ERROR 0x3 -#define GB_AUDIO_STREAMING_EVENT_PROTOCOL_ERROR 0x4 -#define GB_AUDIO_STREAMING_EVENT_FAILURE 0x5 -#define GB_AUDIO_STREAMING_EVENT_UNDERRUN 0x6 -#define GB_AUDIO_STREAMING_EVENT_OVERRUN 0x7 -#define GB_AUDIO_STREAMING_EVENT_CLOCKING 0x8 -#define GB_AUDIO_STREAMING_EVENT_DATA_LEN 0x9 - -#define GB_AUDIO_INVALID_INDEX 0xff - -/* enum snd_jack_types */ -#define GB_AUDIO_JACK_HEADPHONE 0x0000001 -#define GB_AUDIO_JACK_MICROPHONE 0x0000002 -#define GB_AUDIO_JACK_HEADSET (GB_AUDIO_JACK_HEADPHONE | \ - GB_AUDIO_JACK_MICROPHONE) -#define GB_AUDIO_JACK_LINEOUT 0x0000004 -#define GB_AUDIO_JACK_MECHANICAL 0x0000008 -#define GB_AUDIO_JACK_VIDEOOUT 0x0000010 -#define GB_AUDIO_JACK_AVOUT (GB_AUDIO_JACK_LINEOUT | \ - GB_AUDIO_JACK_VIDEOOUT) -#define GB_AUDIO_JACK_LINEIN 0x0000020 -#define GB_AUDIO_JACK_OC_HPHL 0x0000040 -#define GB_AUDIO_JACK_OC_HPHR 0x0000080 -#define GB_AUDIO_JACK_MICROPHONE2 0x0000200 -#define GB_AUDIO_JACK_ANC_HEADPHONE (GB_AUDIO_JACK_HEADPHONE | \ - GB_AUDIO_JACK_MICROPHONE | \ - GB_AUDIO_JACK_MICROPHONE2) -/* Kept separate from switches to facilitate implementation */ -#define GB_AUDIO_JACK_BTN_0 0x4000000 -#define GB_AUDIO_JACK_BTN_1 0x2000000 -#define GB_AUDIO_JACK_BTN_2 0x1000000 -#define GB_AUDIO_JACK_BTN_3 0x0800000 - -struct gb_audio_pcm { - __u8 stream_name[GB_AUDIO_PCM_NAME_MAX]; - __le32 formats; /* GB_AUDIO_PCM_FMT_* */ - __le32 rates; /* GB_AUDIO_PCM_RATE_* */ - __u8 chan_min; - __u8 chan_max; - __u8 sig_bits; /* number of bits of content */ -} __packed; - -struct gb_audio_dai { - __u8 name[AUDIO_DAI_NAME_MAX]; - __le16 data_cport; - struct gb_audio_pcm capture; - struct gb_audio_pcm playback; -} __packed; - -struct gb_audio_integer { - __le32 min; - __le32 max; - __le32 step; -} __packed; - -struct gb_audio_integer64 { - __le64 min; - __le64 max; - __le64 step; -} __packed; - -struct gb_audio_enumerated { - __le32 items; - __le16 names_length; - __u8 names[0]; -} __packed; - -struct gb_audio_ctl_elem_info { /* See snd_ctl_elem_info in Linux source */ - __u8 type; /* GB_AUDIO_CTL_ELEM_TYPE_* */ - __le16 dimen[4]; - union { - struct gb_audio_integer integer; - struct gb_audio_integer64 integer64; - struct gb_audio_enumerated enumerated; - } value; -} __packed; - -struct gb_audio_ctl_elem_value { /* See snd_ctl_elem_value in Linux source */ - __le64 timestamp; /* XXX needed? */ - union { - __le32 integer_value[2]; /* consider CTL_DOUBLE_xxx */ - __le64 integer64_value[2]; - __le32 enumerated_item[2]; - } value; -} __packed; - -struct gb_audio_control { - __u8 name[AUDIO_CONTROL_NAME_MAX]; - __u8 id; /* 0-63 */ - __u8 iface; /* GB_AUDIO_IFACE_* */ - __le16 data_cport; - __le32 access; /* GB_AUDIO_ACCESS_* */ - __u8 count; /* count of same elements */ - __u8 count_values; /* count of values, max=2 for CTL_DOUBLE_xxx */ - struct gb_audio_ctl_elem_info info; -} __packed; - -struct gb_audio_widget { - __u8 name[AUDIO_WIDGET_NAME_MAX]; - __u8 sname[AUDIO_WIDGET_NAME_MAX]; - __u8 id; - __u8 type; /* GB_AUDIO_WIDGET_TYPE_* */ - __u8 state; /* GB_AUDIO_WIDGET_STATE_* */ - __u8 ncontrols; - struct gb_audio_control ctl[0]; /* 'ncontrols' entries */ -} __packed; - -struct gb_audio_route { - __u8 source_id; /* widget id */ - __u8 destination_id; /* widget id */ - __u8 control_id; /* 0-63 */ - __u8 index; /* Selection within the control */ -} __packed; - -struct gb_audio_topology { - __u8 num_dais; - __u8 num_controls; - __u8 num_widgets; - __u8 num_routes; - __le32 size_dais; - __le32 size_controls; - __le32 size_widgets; - __le32 size_routes; - __le32 jack_type; - /* - * struct gb_audio_dai dai[num_dais]; - * struct gb_audio_control controls[num_controls]; - * struct gb_audio_widget widgets[num_widgets]; - * struct gb_audio_route routes[num_routes]; - */ - __u8 data[0]; -} __packed; - -struct gb_audio_get_topology_size_response { - __le16 size; -} __packed; - -struct gb_audio_get_topology_response { - struct gb_audio_topology topology; -} __packed; - -struct gb_audio_get_control_request { - __u8 control_id; - __u8 index; -} __packed; - -struct gb_audio_get_control_response { - struct gb_audio_ctl_elem_value value; -} __packed; - -struct gb_audio_set_control_request { - __u8 control_id; - __u8 index; - struct gb_audio_ctl_elem_value value; -} __packed; - -struct gb_audio_enable_widget_request { - __u8 widget_id; -} __packed; - -struct gb_audio_disable_widget_request { - __u8 widget_id; -} __packed; - -struct gb_audio_get_pcm_request { - __le16 data_cport; -} __packed; - -struct gb_audio_get_pcm_response { - __le32 format; - __le32 rate; - __u8 channels; - __u8 sig_bits; -} __packed; - -struct gb_audio_set_pcm_request { - __le16 data_cport; - __le32 format; - __le32 rate; - __u8 channels; - __u8 sig_bits; -} __packed; - -struct gb_audio_set_tx_data_size_request { - __le16 data_cport; - __le16 size; -} __packed; - -struct gb_audio_activate_tx_request { - __le16 data_cport; -} __packed; - -struct gb_audio_deactivate_tx_request { - __le16 data_cport; -} __packed; - -struct gb_audio_set_rx_data_size_request { - __le16 data_cport; - __le16 size; -} __packed; - -struct gb_audio_activate_rx_request { - __le16 data_cport; -} __packed; - -struct gb_audio_deactivate_rx_request { - __le16 data_cport; -} __packed; - -struct gb_audio_jack_event_request { - __u8 widget_id; - __u8 jack_attribute; - __u8 event; -} __packed; - -struct gb_audio_button_event_request { - __u8 widget_id; - __u8 button_id; - __u8 event; -} __packed; - -struct gb_audio_streaming_event_request { - __le16 data_cport; - __u8 event; -} __packed; - -struct gb_audio_send_data_request { - __le64 timestamp; - __u8 data[0]; -} __packed; - - -/* Log */ - -/* operations */ -#define GB_LOG_TYPE_SEND_LOG 0x02 - -/* length */ -#define GB_LOG_MAX_LEN 1024 - -struct gb_log_send_log_request { - __le16 len; - __u8 msg[0]; -} __packed; - -#endif /* __GREYBUS_PROTOCOLS_H */ - diff --git a/drivers/staging/greybus/greybus_trace.h b/drivers/staging/greybus/greybus_trace.h deleted file mode 100644 index 7b5e2c6b1f6b..000000000000 --- a/drivers/staging/greybus/greybus_trace.h +++ /dev/null @@ -1,502 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus driver and device API - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - */ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM greybus - -#if !defined(_TRACE_GREYBUS_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_GREYBUS_H - -#include <linux/tracepoint.h> - -struct gb_message; -struct gb_operation; -struct gb_connection; -struct gb_bundle; -struct gb_host_device; - -DECLARE_EVENT_CLASS(gb_message, - - TP_PROTO(struct gb_message *message), - - TP_ARGS(message), - - TP_STRUCT__entry( - __field(u16, size) - __field(u16, operation_id) - __field(u8, type) - __field(u8, result) - ), - - TP_fast_assign( - __entry->size = le16_to_cpu(message->header->size); - __entry->operation_id = - le16_to_cpu(message->header->operation_id); - __entry->type = message->header->type; - __entry->result = message->header->result; - ), - - TP_printk("size=%hu operation_id=0x%04x type=0x%02x result=0x%02x", - __entry->size, __entry->operation_id, - __entry->type, __entry->result) -); - -#define DEFINE_MESSAGE_EVENT(name) \ - DEFINE_EVENT(gb_message, name, \ - TP_PROTO(struct gb_message *message), \ - TP_ARGS(message)) - -/* - * Occurs immediately before calling a host device's message_send() - * method. - */ -DEFINE_MESSAGE_EVENT(gb_message_send); - -/* - * Occurs after an incoming request message has been received - */ -DEFINE_MESSAGE_EVENT(gb_message_recv_request); - -/* - * Occurs after an incoming response message has been received, - * after its matching request has been found. - */ -DEFINE_MESSAGE_EVENT(gb_message_recv_response); - -/* - * Occurs after an operation has been canceled, possibly before the - * cancellation is complete. - */ -DEFINE_MESSAGE_EVENT(gb_message_cancel_outgoing); - -/* - * Occurs when an incoming request is cancelled; if the response has - * been queued for sending, this occurs after it is sent. - */ -DEFINE_MESSAGE_EVENT(gb_message_cancel_incoming); - -/* - * Occurs in the host driver message_send() function just prior to - * handing off the data to be processed by hardware. - */ -DEFINE_MESSAGE_EVENT(gb_message_submit); - -#undef DEFINE_MESSAGE_EVENT - -DECLARE_EVENT_CLASS(gb_operation, - - TP_PROTO(struct gb_operation *operation), - - TP_ARGS(operation), - - TP_STRUCT__entry( - __field(u16, cport_id) /* CPort of HD side of connection */ - __field(u16, id) /* Operation ID */ - __field(u8, type) - __field(unsigned long, flags) - __field(int, active) - __field(int, waiters) - __field(int, errno) - ), - - TP_fast_assign( - __entry->cport_id = operation->connection->hd_cport_id; - __entry->id = operation->id; - __entry->type = operation->type; - __entry->flags = operation->flags; - __entry->active = operation->active; - __entry->waiters = atomic_read(&operation->waiters); - __entry->errno = operation->errno; - ), - - TP_printk("id=%04x type=0x%02x cport_id=%04x flags=0x%lx active=%d waiters=%d errno=%d", - __entry->id, __entry->cport_id, __entry->type, __entry->flags, - __entry->active, __entry->waiters, __entry->errno) -); - -#define DEFINE_OPERATION_EVENT(name) \ - DEFINE_EVENT(gb_operation, name, \ - TP_PROTO(struct gb_operation *operation), \ - TP_ARGS(operation)) - -/* - * Occurs after a new operation is created for an outgoing request - * has been successfully created. - */ -DEFINE_OPERATION_EVENT(gb_operation_create); - -/* - * Occurs after a new core operation has been created. - */ -DEFINE_OPERATION_EVENT(gb_operation_create_core); - -/* - * Occurs after a new operation has been created for an incoming - * request has been successfully created and initialized. - */ -DEFINE_OPERATION_EVENT(gb_operation_create_incoming); - -/* - * Occurs when the last reference to an operation has been dropped, - * prior to freeing resources. - */ -DEFINE_OPERATION_EVENT(gb_operation_destroy); - -/* - * Occurs when an operation has been marked active, after updating - * its active count. - */ -DEFINE_OPERATION_EVENT(gb_operation_get_active); - -/* - * Occurs when an operation has been marked active, before updating - * its active count. - */ -DEFINE_OPERATION_EVENT(gb_operation_put_active); - -#undef DEFINE_OPERATION_EVENT - -DECLARE_EVENT_CLASS(gb_connection, - - TP_PROTO(struct gb_connection *connection), - - TP_ARGS(connection), - - TP_STRUCT__entry( - __field(int, hd_bus_id) - __field(u8, bundle_id) - /* name contains "hd_cport_id/intf_id:cport_id" */ - __dynamic_array(char, name, sizeof(connection->name)) - __field(enum gb_connection_state, state) - __field(unsigned long, flags) - ), - - TP_fast_assign( - __entry->hd_bus_id = connection->hd->bus_id; - __entry->bundle_id = connection->bundle ? - connection->bundle->id : BUNDLE_ID_NONE; - memcpy(__get_str(name), connection->name, - sizeof(connection->name)); - __entry->state = connection->state; - __entry->flags = connection->flags; - ), - - TP_printk("hd_bus_id=%d bundle_id=0x%02x name=\"%s\" state=%u flags=0x%lx", - __entry->hd_bus_id, __entry->bundle_id, __get_str(name), - (unsigned int)__entry->state, __entry->flags) -); - -#define DEFINE_CONNECTION_EVENT(name) \ - DEFINE_EVENT(gb_connection, name, \ - TP_PROTO(struct gb_connection *connection), \ - TP_ARGS(connection)) - -/* - * Occurs after a new connection is successfully created. - */ -DEFINE_CONNECTION_EVENT(gb_connection_create); - -/* - * Occurs when the last reference to a connection has been dropped, - * before its resources are freed. - */ -DEFINE_CONNECTION_EVENT(gb_connection_release); - -/* - * Occurs when a new reference to connection is added, currently - * only when a message over the connection is received. - */ -DEFINE_CONNECTION_EVENT(gb_connection_get); - -/* - * Occurs when a new reference to connection is dropped, after a - * a received message is handled, or when the connection is - * destroyed. - */ -DEFINE_CONNECTION_EVENT(gb_connection_put); - -/* - * Occurs when a request to enable a connection is made, either for - * transmit only, or for both transmit and receive. - */ -DEFINE_CONNECTION_EVENT(gb_connection_enable); - -/* - * Occurs when a request to disable a connection is made, either for - * receive only, or for both transmit and receive. Also occurs when - * a request to forcefully disable a connection is made. - */ -DEFINE_CONNECTION_EVENT(gb_connection_disable); - -#undef DEFINE_CONNECTION_EVENT - -DECLARE_EVENT_CLASS(gb_bundle, - - TP_PROTO(struct gb_bundle *bundle), - - TP_ARGS(bundle), - - TP_STRUCT__entry( - __field(u8, intf_id) - __field(u8, id) - __field(u8, class) - __field(size_t, num_cports) - ), - - TP_fast_assign( - __entry->intf_id = bundle->intf->interface_id; - __entry->id = bundle->id; - __entry->class = bundle->class; - __entry->num_cports = bundle->num_cports; - ), - - TP_printk("intf_id=0x%02x id=%02x class=0x%02x num_cports=%zu", - __entry->intf_id, __entry->id, __entry->class, - __entry->num_cports) -); - -#define DEFINE_BUNDLE_EVENT(name) \ - DEFINE_EVENT(gb_bundle, name, \ - TP_PROTO(struct gb_bundle *bundle), \ - TP_ARGS(bundle)) - -/* - * Occurs after a new bundle is successfully created. - */ -DEFINE_BUNDLE_EVENT(gb_bundle_create); - -/* - * Occurs when the last reference to a bundle has been dropped, - * before its resources are freed. - */ -DEFINE_BUNDLE_EVENT(gb_bundle_release); - -/* - * Occurs when a bundle is added to an interface when the interface - * is enabled. - */ -DEFINE_BUNDLE_EVENT(gb_bundle_add); - -/* - * Occurs when a registered bundle gets destroyed, normally at the - * time an interface is disabled. - */ -DEFINE_BUNDLE_EVENT(gb_bundle_destroy); - -#undef DEFINE_BUNDLE_EVENT - -DECLARE_EVENT_CLASS(gb_interface, - - TP_PROTO(struct gb_interface *intf), - - TP_ARGS(intf), - - TP_STRUCT__entry( - __field(u8, module_id) - __field(u8, id) /* Interface id */ - __field(u8, device_id) - __field(int, disconnected) /* bool */ - __field(int, ejected) /* bool */ - __field(int, active) /* bool */ - __field(int, enabled) /* bool */ - __field(int, mode_switch) /* bool */ - ), - - TP_fast_assign( - __entry->module_id = intf->module->module_id; - __entry->id = intf->interface_id; - __entry->device_id = intf->device_id; - __entry->disconnected = intf->disconnected; - __entry->ejected = intf->ejected; - __entry->active = intf->active; - __entry->enabled = intf->enabled; - __entry->mode_switch = intf->mode_switch; - ), - - TP_printk("intf_id=%hhu device_id=%hhu module_id=%hhu D=%d J=%d A=%d E=%d M=%d", - __entry->id, __entry->device_id, __entry->module_id, - __entry->disconnected, __entry->ejected, __entry->active, - __entry->enabled, __entry->mode_switch) -); - -#define DEFINE_INTERFACE_EVENT(name) \ - DEFINE_EVENT(gb_interface, name, \ - TP_PROTO(struct gb_interface *intf), \ - TP_ARGS(intf)) - -/* - * Occurs after a new interface is successfully created. - */ -DEFINE_INTERFACE_EVENT(gb_interface_create); - -/* - * Occurs after the last reference to an interface has been dropped. - */ -DEFINE_INTERFACE_EVENT(gb_interface_release); - -/* - * Occurs after an interface been registerd. - */ -DEFINE_INTERFACE_EVENT(gb_interface_add); - -/* - * Occurs when a registered interface gets deregisterd. - */ -DEFINE_INTERFACE_EVENT(gb_interface_del); - -/* - * Occurs when a registered interface has been successfully - * activated. - */ -DEFINE_INTERFACE_EVENT(gb_interface_activate); - -/* - * Occurs when an activated interface is being deactivated. - */ -DEFINE_INTERFACE_EVENT(gb_interface_deactivate); - -/* - * Occurs when an interface has been successfully enabled. - */ -DEFINE_INTERFACE_EVENT(gb_interface_enable); - -/* - * Occurs when an enabled interface is being disabled. - */ -DEFINE_INTERFACE_EVENT(gb_interface_disable); - -#undef DEFINE_INTERFACE_EVENT - -DECLARE_EVENT_CLASS(gb_module, - - TP_PROTO(struct gb_module *module), - - TP_ARGS(module), - - TP_STRUCT__entry( - __field(int, hd_bus_id) - __field(u8, module_id) - __field(size_t, num_interfaces) - __field(int, disconnected) /* bool */ - ), - - TP_fast_assign( - __entry->hd_bus_id = module->hd->bus_id; - __entry->module_id = module->module_id; - __entry->num_interfaces = module->num_interfaces; - __entry->disconnected = module->disconnected; - ), - - TP_printk("hd_bus_id=%d module_id=%hhu num_interfaces=%zu disconnected=%d", - __entry->hd_bus_id, __entry->module_id, - __entry->num_interfaces, __entry->disconnected) -); - -#define DEFINE_MODULE_EVENT(name) \ - DEFINE_EVENT(gb_module, name, \ - TP_PROTO(struct gb_module *module), \ - TP_ARGS(module)) - -/* - * Occurs after a new module is successfully created, before - * creating any of its interfaces. - */ -DEFINE_MODULE_EVENT(gb_module_create); - -/* - * Occurs after the last reference to a module has been dropped. - */ -DEFINE_MODULE_EVENT(gb_module_release); - -/* - * Occurs after a module is successfully created, before registering - * any of its interfaces. - */ -DEFINE_MODULE_EVENT(gb_module_add); - -/* - * Occurs when a module is deleted, before deregistering its - * interfaces. - */ -DEFINE_MODULE_EVENT(gb_module_del); - -#undef DEFINE_MODULE_EVENT - -DECLARE_EVENT_CLASS(gb_host_device, - - TP_PROTO(struct gb_host_device *hd), - - TP_ARGS(hd), - - TP_STRUCT__entry( - __field(int, bus_id) - __field(size_t, num_cports) - __field(size_t, buffer_size_max) - ), - - TP_fast_assign( - __entry->bus_id = hd->bus_id; - __entry->num_cports = hd->num_cports; - __entry->buffer_size_max = hd->buffer_size_max; - ), - - TP_printk("bus_id=%d num_cports=%zu mtu=%zu", - __entry->bus_id, __entry->num_cports, - __entry->buffer_size_max) -); - -#define DEFINE_HD_EVENT(name) \ - DEFINE_EVENT(gb_host_device, name, \ - TP_PROTO(struct gb_host_device *hd), \ - TP_ARGS(hd)) - -/* - * Occurs after a new host device is successfully created, before - * its SVC has been set up. - */ -DEFINE_HD_EVENT(gb_hd_create); - -/* - * Occurs after the last reference to a host device has been - * dropped. - */ -DEFINE_HD_EVENT(gb_hd_release); - -/* - * Occurs after a new host device has been added, after the - * connection to its SVC has been enabled. - */ -DEFINE_HD_EVENT(gb_hd_add); - -/* - * Occurs when a host device is being disconnected from the AP USB - * host controller. - */ -DEFINE_HD_EVENT(gb_hd_del); - -/* - * Occurs when a host device has passed received data to the Greybus - * core, after it has been determined it is destined for a valid - * CPort. - */ -DEFINE_HD_EVENT(gb_hd_in); - -#undef DEFINE_HD_EVENT - -#endif /* _TRACE_GREYBUS_H */ - -/* This part must be outside protection */ -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . - -/* - * TRACE_INCLUDE_FILE is not needed if the filename and TRACE_SYSTEM are equal - */ -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE greybus_trace -#include <trace/define_trace.h> - diff --git a/drivers/staging/greybus/hd.c b/drivers/staging/greybus/hd.c deleted file mode 100644 index 969f86697673..000000000000 --- a/drivers/staging/greybus/hd.c +++ /dev/null @@ -1,256 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus Host Device - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> - -#include "greybus.h" -#include "greybus_trace.h" - -EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_create); -EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_release); -EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_add); -EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_del); -EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_in); -EXPORT_TRACEPOINT_SYMBOL_GPL(gb_message_submit); - -static struct ida gb_hd_bus_id_map; - -int gb_hd_output(struct gb_host_device *hd, void *req, u16 size, u8 cmd, - bool async) -{ - if (!hd || !hd->driver || !hd->driver->output) - return -EINVAL; - return hd->driver->output(hd, req, size, cmd, async); -} -EXPORT_SYMBOL_GPL(gb_hd_output); - -static ssize_t bus_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_host_device *hd = to_gb_host_device(dev); - - return sprintf(buf, "%d\n", hd->bus_id); -} -static DEVICE_ATTR_RO(bus_id); - -static struct attribute *bus_attrs[] = { - &dev_attr_bus_id.attr, - NULL -}; -ATTRIBUTE_GROUPS(bus); - -int gb_hd_cport_reserve(struct gb_host_device *hd, u16 cport_id) -{ - struct ida *id_map = &hd->cport_id_map; - int ret; - - ret = ida_simple_get(id_map, cport_id, cport_id + 1, GFP_KERNEL); - if (ret < 0) { - dev_err(&hd->dev, "failed to reserve cport %u\n", cport_id); - return ret; - } - - return 0; -} -EXPORT_SYMBOL_GPL(gb_hd_cport_reserve); - -void gb_hd_cport_release_reserved(struct gb_host_device *hd, u16 cport_id) -{ - struct ida *id_map = &hd->cport_id_map; - - ida_simple_remove(id_map, cport_id); -} -EXPORT_SYMBOL_GPL(gb_hd_cport_release_reserved); - -/* Locking: Caller guarantees serialisation */ -int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id, - unsigned long flags) -{ - struct ida *id_map = &hd->cport_id_map; - int ida_start, ida_end; - - if (hd->driver->cport_allocate) - return hd->driver->cport_allocate(hd, cport_id, flags); - - if (cport_id < 0) { - ida_start = 0; - ida_end = hd->num_cports; - } else if (cport_id < hd->num_cports) { - ida_start = cport_id; - ida_end = cport_id + 1; - } else { - dev_err(&hd->dev, "cport %d not available\n", cport_id); - return -EINVAL; - } - - return ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL); -} - -/* Locking: Caller guarantees serialisation */ -void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id) -{ - if (hd->driver->cport_release) { - hd->driver->cport_release(hd, cport_id); - return; - } - - ida_simple_remove(&hd->cport_id_map, cport_id); -} - -static void gb_hd_release(struct device *dev) -{ - struct gb_host_device *hd = to_gb_host_device(dev); - - trace_gb_hd_release(hd); - - if (hd->svc) - gb_svc_put(hd->svc); - ida_simple_remove(&gb_hd_bus_id_map, hd->bus_id); - ida_destroy(&hd->cport_id_map); - kfree(hd); -} - -struct device_type greybus_hd_type = { - .name = "greybus_host_device", - .release = gb_hd_release, -}; - -struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver, - struct device *parent, - size_t buffer_size_max, - size_t num_cports) -{ - struct gb_host_device *hd; - int ret; - - /* - * Validate that the driver implements all of the callbacks - * so that we don't have to every time we make them. - */ - if ((!driver->message_send) || (!driver->message_cancel)) { - dev_err(parent, "mandatory hd-callbacks missing\n"); - return ERR_PTR(-EINVAL); - } - - if (buffer_size_max < GB_OPERATION_MESSAGE_SIZE_MIN) { - dev_err(parent, "greybus host-device buffers too small\n"); - return ERR_PTR(-EINVAL); - } - - if (num_cports == 0 || num_cports > CPORT_ID_MAX + 1) { - dev_err(parent, "Invalid number of CPorts: %zu\n", num_cports); - return ERR_PTR(-EINVAL); - } - - /* - * Make sure to never allocate messages larger than what the Greybus - * protocol supports. - */ - if (buffer_size_max > GB_OPERATION_MESSAGE_SIZE_MAX) { - dev_warn(parent, "limiting buffer size to %u\n", - GB_OPERATION_MESSAGE_SIZE_MAX); - buffer_size_max = GB_OPERATION_MESSAGE_SIZE_MAX; - } - - hd = kzalloc(sizeof(*hd) + driver->hd_priv_size, GFP_KERNEL); - if (!hd) - return ERR_PTR(-ENOMEM); - - ret = ida_simple_get(&gb_hd_bus_id_map, 1, 0, GFP_KERNEL); - if (ret < 0) { - kfree(hd); - return ERR_PTR(ret); - } - hd->bus_id = ret; - - hd->driver = driver; - INIT_LIST_HEAD(&hd->modules); - INIT_LIST_HEAD(&hd->connections); - ida_init(&hd->cport_id_map); - hd->buffer_size_max = buffer_size_max; - hd->num_cports = num_cports; - - hd->dev.parent = parent; - hd->dev.bus = &greybus_bus_type; - hd->dev.type = &greybus_hd_type; - hd->dev.groups = bus_groups; - hd->dev.dma_mask = hd->dev.parent->dma_mask; - device_initialize(&hd->dev); - dev_set_name(&hd->dev, "greybus%d", hd->bus_id); - - trace_gb_hd_create(hd); - - hd->svc = gb_svc_create(hd); - if (!hd->svc) { - dev_err(&hd->dev, "failed to create svc\n"); - put_device(&hd->dev); - return ERR_PTR(-ENOMEM); - } - - return hd; -} -EXPORT_SYMBOL_GPL(gb_hd_create); - -int gb_hd_add(struct gb_host_device *hd) -{ - int ret; - - ret = device_add(&hd->dev); - if (ret) - return ret; - - ret = gb_svc_add(hd->svc); - if (ret) { - device_del(&hd->dev); - return ret; - } - - trace_gb_hd_add(hd); - - return 0; -} -EXPORT_SYMBOL_GPL(gb_hd_add); - -void gb_hd_del(struct gb_host_device *hd) -{ - trace_gb_hd_del(hd); - - /* - * Tear down the svc and flush any on-going hotplug processing before - * removing the remaining interfaces. - */ - gb_svc_del(hd->svc); - - device_del(&hd->dev); -} -EXPORT_SYMBOL_GPL(gb_hd_del); - -void gb_hd_shutdown(struct gb_host_device *hd) -{ - gb_svc_del(hd->svc); -} -EXPORT_SYMBOL_GPL(gb_hd_shutdown); - -void gb_hd_put(struct gb_host_device *hd) -{ - put_device(&hd->dev); -} -EXPORT_SYMBOL_GPL(gb_hd_put); - -int __init gb_hd_init(void) -{ - ida_init(&gb_hd_bus_id_map); - - return 0; -} - -void gb_hd_exit(void) -{ - ida_destroy(&gb_hd_bus_id_map); -} diff --git a/drivers/staging/greybus/hd.h b/drivers/staging/greybus/hd.h deleted file mode 100644 index 6cf024a20a58..000000000000 --- a/drivers/staging/greybus/hd.h +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus Host Device - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#ifndef __HD_H -#define __HD_H - -struct gb_host_device; -struct gb_message; - -struct gb_hd_driver { - size_t hd_priv_size; - - int (*cport_allocate)(struct gb_host_device *hd, int cport_id, - unsigned long flags); - void (*cport_release)(struct gb_host_device *hd, u16 cport_id); - int (*cport_enable)(struct gb_host_device *hd, u16 cport_id, - unsigned long flags); - int (*cport_disable)(struct gb_host_device *hd, u16 cport_id); - int (*cport_connected)(struct gb_host_device *hd, u16 cport_id); - int (*cport_flush)(struct gb_host_device *hd, u16 cport_id); - int (*cport_shutdown)(struct gb_host_device *hd, u16 cport_id, - u8 phase, unsigned int timeout); - int (*cport_quiesce)(struct gb_host_device *hd, u16 cport_id, - size_t peer_space, unsigned int timeout); - int (*cport_clear)(struct gb_host_device *hd, u16 cport_id); - - int (*message_send)(struct gb_host_device *hd, u16 dest_cport_id, - struct gb_message *message, gfp_t gfp_mask); - void (*message_cancel)(struct gb_message *message); - int (*latency_tag_enable)(struct gb_host_device *hd, u16 cport_id); - int (*latency_tag_disable)(struct gb_host_device *hd, u16 cport_id); - int (*output)(struct gb_host_device *hd, void *req, u16 size, u8 cmd, - bool async); -}; - -struct gb_host_device { - struct device dev; - int bus_id; - const struct gb_hd_driver *driver; - - struct list_head modules; - struct list_head connections; - struct ida cport_id_map; - - /* Number of CPorts supported by the UniPro IP */ - size_t num_cports; - - /* Host device buffer constraints */ - size_t buffer_size_max; - - struct gb_svc *svc; - /* Private data for the host driver */ - unsigned long hd_priv[0] __aligned(sizeof(s64)); -}; -#define to_gb_host_device(d) container_of(d, struct gb_host_device, dev) - -int gb_hd_cport_reserve(struct gb_host_device *hd, u16 cport_id); -void gb_hd_cport_release_reserved(struct gb_host_device *hd, u16 cport_id); -int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id, - unsigned long flags); -void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id); - -struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver, - struct device *parent, - size_t buffer_size_max, - size_t num_cports); -int gb_hd_add(struct gb_host_device *hd); -void gb_hd_del(struct gb_host_device *hd); -void gb_hd_shutdown(struct gb_host_device *hd); -void gb_hd_put(struct gb_host_device *hd); -int gb_hd_output(struct gb_host_device *hd, void *req, u16 size, u8 cmd, - bool in_irq); - -int gb_hd_init(void); -void gb_hd_exit(void); - -#endif /* __HD_H */ diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c index 8ab810bf5716..04bfd9110502 100644 --- a/drivers/staging/greybus/hid.c +++ b/drivers/staging/greybus/hid.c @@ -12,8 +12,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/slab.h> - -#include "greybus.h" +#include <linux/greybus.h> /* Greybus HID device's structure */ struct gb_hid { diff --git a/drivers/staging/greybus/i2c.c b/drivers/staging/greybus/i2c.c index 7bb85a75d3b1..ab06fc3b9e7e 100644 --- a/drivers/staging/greybus/i2c.c +++ b/drivers/staging/greybus/i2c.c @@ -10,8 +10,8 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/i2c.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" struct gb_i2c_device { @@ -31,7 +31,14 @@ static u32 gb_i2c_functionality_map(u32 gb_i2c_functionality) return gb_i2c_functionality; /* All bits the same for now */ } -static int gb_i2c_functionality_operation(struct gb_i2c_device *gb_i2c_dev) +/* + * Do initial setup of the i2c device. This includes verifying we + * can support it (based on the protocol version it advertises). + * If that's OK, we get and cached its functionality bits. + * + * Note: gb_i2c_dev->connection is assumed to have been valid. + */ +static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev) { struct gb_i2c_functionality_response response; u32 functionality; @@ -235,19 +242,6 @@ static const struct i2c_algorithm gb_i2c_algorithm = { .functionality = gb_i2c_functionality, }; -/* - * Do initial setup of the i2c device. This includes verifying we - * can support it (based on the protocol version it advertises). - * If that's OK, we get and cached its functionality bits. - * - * Note: gb_i2c_dev->connection is assumed to have been valid. - */ -static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev) -{ - /* Assume the functionality never changes, just get it once */ - return gb_i2c_functionality_operation(gb_i2c_dev); -} - static int gb_i2c_probe(struct gbphy_device *gbphy_dev, const struct gbphy_device_id *id) { diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c deleted file mode 100644 index d7b5b89a2f40..000000000000 --- a/drivers/staging/greybus/interface.c +++ /dev/null @@ -1,1263 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus interface code - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#include <linux/delay.h> - -#include "greybus.h" -#include "greybus_trace.h" - -#define GB_INTERFACE_MODE_SWITCH_TIMEOUT 2000 - -#define GB_INTERFACE_DEVICE_ID_BAD 0xff - -#define GB_INTERFACE_AUTOSUSPEND_MS 3000 - -/* Time required for interface to enter standby before disabling REFCLK */ -#define GB_INTERFACE_SUSPEND_HIBERNATE_DELAY_MS 20 - -/* Don't-care selector index */ -#define DME_SELECTOR_INDEX_NULL 0 - -/* DME attributes */ -/* FIXME: remove ES2 support and DME_T_TST_SRC_INCREMENT */ -#define DME_T_TST_SRC_INCREMENT 0x4083 - -#define DME_DDBL1_MANUFACTURERID 0x5003 -#define DME_DDBL1_PRODUCTID 0x5004 - -#define DME_TOSHIBA_GMP_VID 0x6000 -#define DME_TOSHIBA_GMP_PID 0x6001 -#define DME_TOSHIBA_GMP_SN0 0x6002 -#define DME_TOSHIBA_GMP_SN1 0x6003 -#define DME_TOSHIBA_GMP_INIT_STATUS 0x6101 - -/* DDBL1 Manufacturer and Product ids */ -#define TOSHIBA_DMID 0x0126 -#define TOSHIBA_ES2_BRIDGE_DPID 0x1000 -#define TOSHIBA_ES3_APBRIDGE_DPID 0x1001 -#define TOSHIBA_ES3_GBPHY_DPID 0x1002 - -static int gb_interface_hibernate_link(struct gb_interface *intf); -static int gb_interface_refclk_set(struct gb_interface *intf, bool enable); - -static int gb_interface_dme_attr_get(struct gb_interface *intf, - u16 attr, u32 *val) -{ - return gb_svc_dme_peer_get(intf->hd->svc, intf->interface_id, - attr, DME_SELECTOR_INDEX_NULL, val); -} - -static int gb_interface_read_ara_dme(struct gb_interface *intf) -{ - u32 sn0, sn1; - int ret; - - /* - * Unless this is a Toshiba bridge, bail out until we have defined - * standard GMP attributes. - */ - if (intf->ddbl1_manufacturer_id != TOSHIBA_DMID) { - dev_err(&intf->dev, "unknown manufacturer %08x\n", - intf->ddbl1_manufacturer_id); - return -ENODEV; - } - - ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_VID, - &intf->vendor_id); - if (ret) - return ret; - - ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_PID, - &intf->product_id); - if (ret) - return ret; - - ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_SN0, &sn0); - if (ret) - return ret; - - ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_SN1, &sn1); - if (ret) - return ret; - - intf->serial_number = (u64)sn1 << 32 | sn0; - - return 0; -} - -static int gb_interface_read_dme(struct gb_interface *intf) -{ - int ret; - - /* DME attributes have already been read */ - if (intf->dme_read) - return 0; - - ret = gb_interface_dme_attr_get(intf, DME_DDBL1_MANUFACTURERID, - &intf->ddbl1_manufacturer_id); - if (ret) - return ret; - - ret = gb_interface_dme_attr_get(intf, DME_DDBL1_PRODUCTID, - &intf->ddbl1_product_id); - if (ret) - return ret; - - if (intf->ddbl1_manufacturer_id == TOSHIBA_DMID && - intf->ddbl1_product_id == TOSHIBA_ES2_BRIDGE_DPID) { - intf->quirks |= GB_INTERFACE_QUIRK_NO_GMP_IDS; - intf->quirks |= GB_INTERFACE_QUIRK_NO_INIT_STATUS; - } - - ret = gb_interface_read_ara_dme(intf); - if (ret) - return ret; - - intf->dme_read = true; - - return 0; -} - -static int gb_interface_route_create(struct gb_interface *intf) -{ - struct gb_svc *svc = intf->hd->svc; - u8 intf_id = intf->interface_id; - u8 device_id; - int ret; - - /* Allocate an interface device id. */ - ret = ida_simple_get(&svc->device_id_map, - GB_SVC_DEVICE_ID_MIN, GB_SVC_DEVICE_ID_MAX + 1, - GFP_KERNEL); - if (ret < 0) { - dev_err(&intf->dev, "failed to allocate device id: %d\n", ret); - return ret; - } - device_id = ret; - - ret = gb_svc_intf_device_id(svc, intf_id, device_id); - if (ret) { - dev_err(&intf->dev, "failed to set device id %u: %d\n", - device_id, ret); - goto err_ida_remove; - } - - /* FIXME: Hard-coded AP device id. */ - ret = gb_svc_route_create(svc, svc->ap_intf_id, GB_SVC_DEVICE_ID_AP, - intf_id, device_id); - if (ret) { - dev_err(&intf->dev, "failed to create route: %d\n", ret); - goto err_svc_id_free; - } - - intf->device_id = device_id; - - return 0; - -err_svc_id_free: - /* - * XXX Should we tell SVC that this id doesn't belong to interface - * XXX anymore. - */ -err_ida_remove: - ida_simple_remove(&svc->device_id_map, device_id); - - return ret; -} - -static void gb_interface_route_destroy(struct gb_interface *intf) -{ - struct gb_svc *svc = intf->hd->svc; - - if (intf->device_id == GB_INTERFACE_DEVICE_ID_BAD) - return; - - gb_svc_route_destroy(svc, svc->ap_intf_id, intf->interface_id); - ida_simple_remove(&svc->device_id_map, intf->device_id); - intf->device_id = GB_INTERFACE_DEVICE_ID_BAD; -} - -/* Locking: Caller holds the interface mutex. */ -static int gb_interface_legacy_mode_switch(struct gb_interface *intf) -{ - int ret; - - dev_info(&intf->dev, "legacy mode switch detected\n"); - - /* Mark as disconnected to prevent I/O during disable. */ - intf->disconnected = true; - gb_interface_disable(intf); - intf->disconnected = false; - - ret = gb_interface_enable(intf); - if (ret) { - dev_err(&intf->dev, "failed to re-enable interface: %d\n", ret); - gb_interface_deactivate(intf); - } - - return ret; -} - -void gb_interface_mailbox_event(struct gb_interface *intf, u16 result, - u32 mailbox) -{ - mutex_lock(&intf->mutex); - - if (result) { - dev_warn(&intf->dev, - "mailbox event with UniPro error: 0x%04x\n", - result); - goto err_disable; - } - - if (mailbox != GB_SVC_INTF_MAILBOX_GREYBUS) { - dev_warn(&intf->dev, - "mailbox event with unexpected value: 0x%08x\n", - mailbox); - goto err_disable; - } - - if (intf->quirks & GB_INTERFACE_QUIRK_LEGACY_MODE_SWITCH) { - gb_interface_legacy_mode_switch(intf); - goto out_unlock; - } - - if (!intf->mode_switch) { - dev_warn(&intf->dev, "unexpected mailbox event: 0x%08x\n", - mailbox); - goto err_disable; - } - - dev_info(&intf->dev, "mode switch detected\n"); - - complete(&intf->mode_switch_completion); - -out_unlock: - mutex_unlock(&intf->mutex); - - return; - -err_disable: - gb_interface_disable(intf); - gb_interface_deactivate(intf); - mutex_unlock(&intf->mutex); -} - -static void gb_interface_mode_switch_work(struct work_struct *work) -{ - struct gb_interface *intf; - struct gb_control *control; - unsigned long timeout; - int ret; - - intf = container_of(work, struct gb_interface, mode_switch_work); - - mutex_lock(&intf->mutex); - /* Make sure interface is still enabled. */ - if (!intf->enabled) { - dev_dbg(&intf->dev, "mode switch aborted\n"); - intf->mode_switch = false; - mutex_unlock(&intf->mutex); - goto out_interface_put; - } - - /* - * Prepare the control device for mode switch and make sure to get an - * extra reference before it goes away during interface disable. - */ - control = gb_control_get(intf->control); - gb_control_mode_switch_prepare(control); - gb_interface_disable(intf); - mutex_unlock(&intf->mutex); - - timeout = msecs_to_jiffies(GB_INTERFACE_MODE_SWITCH_TIMEOUT); - ret = wait_for_completion_interruptible_timeout( - &intf->mode_switch_completion, timeout); - - /* Finalise control-connection mode switch. */ - gb_control_mode_switch_complete(control); - gb_control_put(control); - - if (ret < 0) { - dev_err(&intf->dev, "mode switch interrupted\n"); - goto err_deactivate; - } else if (ret == 0) { - dev_err(&intf->dev, "mode switch timed out\n"); - goto err_deactivate; - } - - /* Re-enable (re-enumerate) interface if still active. */ - mutex_lock(&intf->mutex); - intf->mode_switch = false; - if (intf->active) { - ret = gb_interface_enable(intf); - if (ret) { - dev_err(&intf->dev, "failed to re-enable interface: %d\n", - ret); - gb_interface_deactivate(intf); - } - } - mutex_unlock(&intf->mutex); - -out_interface_put: - gb_interface_put(intf); - - return; - -err_deactivate: - mutex_lock(&intf->mutex); - intf->mode_switch = false; - gb_interface_deactivate(intf); - mutex_unlock(&intf->mutex); - - gb_interface_put(intf); -} - -int gb_interface_request_mode_switch(struct gb_interface *intf) -{ - int ret = 0; - - mutex_lock(&intf->mutex); - if (intf->mode_switch) { - ret = -EBUSY; - goto out_unlock; - } - - intf->mode_switch = true; - reinit_completion(&intf->mode_switch_completion); - - /* - * Get a reference to the interface device, which will be put once the - * mode switch is complete. - */ - get_device(&intf->dev); - - if (!queue_work(system_long_wq, &intf->mode_switch_work)) { - put_device(&intf->dev); - ret = -EBUSY; - goto out_unlock; - } - -out_unlock: - mutex_unlock(&intf->mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(gb_interface_request_mode_switch); - -/* - * T_TstSrcIncrement is written by the module on ES2 as a stand-in for the - * init-status attribute DME_TOSHIBA_INIT_STATUS. The AP needs to read and - * clear it after reading a non-zero value from it. - * - * FIXME: This is module-hardware dependent and needs to be extended for every - * type of module we want to support. - */ -static int gb_interface_read_and_clear_init_status(struct gb_interface *intf) -{ - struct gb_host_device *hd = intf->hd; - unsigned long bootrom_quirks; - unsigned long s2l_quirks; - int ret; - u32 value; - u16 attr; - u8 init_status; - - /* - * ES2 bridges use T_TstSrcIncrement for the init status. - * - * FIXME: Remove ES2 support - */ - if (intf->quirks & GB_INTERFACE_QUIRK_NO_INIT_STATUS) - attr = DME_T_TST_SRC_INCREMENT; - else - attr = DME_TOSHIBA_GMP_INIT_STATUS; - - ret = gb_svc_dme_peer_get(hd->svc, intf->interface_id, attr, - DME_SELECTOR_INDEX_NULL, &value); - if (ret) - return ret; - - /* - * A nonzero init status indicates the module has finished - * initializing. - */ - if (!value) { - dev_err(&intf->dev, "invalid init status\n"); - return -ENODEV; - } - - /* - * Extract the init status. - * - * For ES2: We need to check lowest 8 bits of 'value'. - * For ES3: We need to check highest 8 bits out of 32 of 'value'. - * - * FIXME: Remove ES2 support - */ - if (intf->quirks & GB_INTERFACE_QUIRK_NO_INIT_STATUS) - init_status = value & 0xff; - else - init_status = value >> 24; - - /* - * Check if the interface is executing the quirky ES3 bootrom that, - * for example, requires E2EFC, CSD and CSV to be disabled. - */ - bootrom_quirks = GB_INTERFACE_QUIRK_NO_CPORT_FEATURES | - GB_INTERFACE_QUIRK_FORCED_DISABLE | - GB_INTERFACE_QUIRK_LEGACY_MODE_SWITCH | - GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE; - - s2l_quirks = GB_INTERFACE_QUIRK_NO_PM; - - switch (init_status) { - case GB_INIT_BOOTROM_UNIPRO_BOOT_STARTED: - case GB_INIT_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED: - intf->quirks |= bootrom_quirks; - break; - case GB_INIT_S2_LOADER_BOOT_STARTED: - /* S2 Loader doesn't support runtime PM */ - intf->quirks &= ~bootrom_quirks; - intf->quirks |= s2l_quirks; - break; - default: - intf->quirks &= ~bootrom_quirks; - intf->quirks &= ~s2l_quirks; - } - - /* Clear the init status. */ - return gb_svc_dme_peer_set(hd->svc, intf->interface_id, attr, - DME_SELECTOR_INDEX_NULL, 0); -} - -/* interface sysfs attributes */ -#define gb_interface_attr(field, type) \ -static ssize_t field##_show(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct gb_interface *intf = to_gb_interface(dev); \ - return scnprintf(buf, PAGE_SIZE, type"\n", intf->field); \ -} \ -static DEVICE_ATTR_RO(field) - -gb_interface_attr(ddbl1_manufacturer_id, "0x%08x"); -gb_interface_attr(ddbl1_product_id, "0x%08x"); -gb_interface_attr(interface_id, "%u"); -gb_interface_attr(vendor_id, "0x%08x"); -gb_interface_attr(product_id, "0x%08x"); -gb_interface_attr(serial_number, "0x%016llx"); - -static ssize_t voltage_now_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_interface *intf = to_gb_interface(dev); - int ret; - u32 measurement; - - ret = gb_svc_pwrmon_intf_sample_get(intf->hd->svc, intf->interface_id, - GB_SVC_PWRMON_TYPE_VOL, - &measurement); - if (ret) { - dev_err(&intf->dev, "failed to get voltage sample (%d)\n", ret); - return ret; - } - - return sprintf(buf, "%u\n", measurement); -} -static DEVICE_ATTR_RO(voltage_now); - -static ssize_t current_now_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_interface *intf = to_gb_interface(dev); - int ret; - u32 measurement; - - ret = gb_svc_pwrmon_intf_sample_get(intf->hd->svc, intf->interface_id, - GB_SVC_PWRMON_TYPE_CURR, - &measurement); - if (ret) { - dev_err(&intf->dev, "failed to get current sample (%d)\n", ret); - return ret; - } - - return sprintf(buf, "%u\n", measurement); -} -static DEVICE_ATTR_RO(current_now); - -static ssize_t power_now_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_interface *intf = to_gb_interface(dev); - int ret; - u32 measurement; - - ret = gb_svc_pwrmon_intf_sample_get(intf->hd->svc, intf->interface_id, - GB_SVC_PWRMON_TYPE_PWR, - &measurement); - if (ret) { - dev_err(&intf->dev, "failed to get power sample (%d)\n", ret); - return ret; - } - - return sprintf(buf, "%u\n", measurement); -} -static DEVICE_ATTR_RO(power_now); - -static ssize_t power_state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_interface *intf = to_gb_interface(dev); - - if (intf->active) - return scnprintf(buf, PAGE_SIZE, "on\n"); - else - return scnprintf(buf, PAGE_SIZE, "off\n"); -} - -static ssize_t power_state_store(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t len) -{ - struct gb_interface *intf = to_gb_interface(dev); - bool activate; - int ret = 0; - - if (kstrtobool(buf, &activate)) - return -EINVAL; - - mutex_lock(&intf->mutex); - - if (activate == intf->active) - goto unlock; - - if (activate) { - ret = gb_interface_activate(intf); - if (ret) { - dev_err(&intf->dev, - "failed to activate interface: %d\n", ret); - goto unlock; - } - - ret = gb_interface_enable(intf); - if (ret) { - dev_err(&intf->dev, - "failed to enable interface: %d\n", ret); - gb_interface_deactivate(intf); - goto unlock; - } - } else { - gb_interface_disable(intf); - gb_interface_deactivate(intf); - } - -unlock: - mutex_unlock(&intf->mutex); - - if (ret) - return ret; - - return len; -} -static DEVICE_ATTR_RW(power_state); - -static const char *gb_interface_type_string(struct gb_interface *intf) -{ - static const char * const types[] = { - [GB_INTERFACE_TYPE_INVALID] = "invalid", - [GB_INTERFACE_TYPE_UNKNOWN] = "unknown", - [GB_INTERFACE_TYPE_DUMMY] = "dummy", - [GB_INTERFACE_TYPE_UNIPRO] = "unipro", - [GB_INTERFACE_TYPE_GREYBUS] = "greybus", - }; - - return types[intf->type]; -} - -static ssize_t interface_type_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_interface *intf = to_gb_interface(dev); - - return sprintf(buf, "%s\n", gb_interface_type_string(intf)); -} -static DEVICE_ATTR_RO(interface_type); - -static struct attribute *interface_unipro_attrs[] = { - &dev_attr_ddbl1_manufacturer_id.attr, - &dev_attr_ddbl1_product_id.attr, - NULL -}; - -static struct attribute *interface_greybus_attrs[] = { - &dev_attr_vendor_id.attr, - &dev_attr_product_id.attr, - &dev_attr_serial_number.attr, - NULL -}; - -static struct attribute *interface_power_attrs[] = { - &dev_attr_voltage_now.attr, - &dev_attr_current_now.attr, - &dev_attr_power_now.attr, - &dev_attr_power_state.attr, - NULL -}; - -static struct attribute *interface_common_attrs[] = { - &dev_attr_interface_id.attr, - &dev_attr_interface_type.attr, - NULL -}; - -static umode_t interface_unipro_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct gb_interface *intf = to_gb_interface(dev); - - switch (intf->type) { - case GB_INTERFACE_TYPE_UNIPRO: - case GB_INTERFACE_TYPE_GREYBUS: - return attr->mode; - default: - return 0; - } -} - -static umode_t interface_greybus_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct gb_interface *intf = to_gb_interface(dev); - - switch (intf->type) { - case GB_INTERFACE_TYPE_GREYBUS: - return attr->mode; - default: - return 0; - } -} - -static umode_t interface_power_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct gb_interface *intf = to_gb_interface(dev); - - switch (intf->type) { - case GB_INTERFACE_TYPE_UNIPRO: - case GB_INTERFACE_TYPE_GREYBUS: - return attr->mode; - default: - return 0; - } -} - -static const struct attribute_group interface_unipro_group = { - .is_visible = interface_unipro_is_visible, - .attrs = interface_unipro_attrs, -}; - -static const struct attribute_group interface_greybus_group = { - .is_visible = interface_greybus_is_visible, - .attrs = interface_greybus_attrs, -}; - -static const struct attribute_group interface_power_group = { - .is_visible = interface_power_is_visible, - .attrs = interface_power_attrs, -}; - -static const struct attribute_group interface_common_group = { - .attrs = interface_common_attrs, -}; - -static const struct attribute_group *interface_groups[] = { - &interface_unipro_group, - &interface_greybus_group, - &interface_power_group, - &interface_common_group, - NULL -}; - -static void gb_interface_release(struct device *dev) -{ - struct gb_interface *intf = to_gb_interface(dev); - - trace_gb_interface_release(intf); - - kfree(intf); -} - -#ifdef CONFIG_PM -static int gb_interface_suspend(struct device *dev) -{ - struct gb_interface *intf = to_gb_interface(dev); - int ret; - - ret = gb_control_interface_suspend_prepare(intf->control); - if (ret) - return ret; - - ret = gb_control_suspend(intf->control); - if (ret) - goto err_hibernate_abort; - - ret = gb_interface_hibernate_link(intf); - if (ret) - return ret; - - /* Delay to allow interface to enter standby before disabling refclk */ - msleep(GB_INTERFACE_SUSPEND_HIBERNATE_DELAY_MS); - - ret = gb_interface_refclk_set(intf, false); - if (ret) - return ret; - - return 0; - -err_hibernate_abort: - gb_control_interface_hibernate_abort(intf->control); - - return ret; -} - -static int gb_interface_resume(struct device *dev) -{ - struct gb_interface *intf = to_gb_interface(dev); - struct gb_svc *svc = intf->hd->svc; - int ret; - - ret = gb_interface_refclk_set(intf, true); - if (ret) - return ret; - - ret = gb_svc_intf_resume(svc, intf->interface_id); - if (ret) - return ret; - - ret = gb_control_resume(intf->control); - if (ret) - return ret; - - return 0; -} - -static int gb_interface_runtime_idle(struct device *dev) -{ - pm_runtime_mark_last_busy(dev); - pm_request_autosuspend(dev); - - return 0; -} -#endif - -static const struct dev_pm_ops gb_interface_pm_ops = { - SET_RUNTIME_PM_OPS(gb_interface_suspend, gb_interface_resume, - gb_interface_runtime_idle) -}; - -struct device_type greybus_interface_type = { - .name = "greybus_interface", - .release = gb_interface_release, - .pm = &gb_interface_pm_ops, -}; - -/* - * A Greybus module represents a user-replaceable component on a GMP - * phone. An interface is the physical connection on that module. A - * module may have more than one interface. - * - * Create a gb_interface structure to represent a discovered interface. - * The position of interface within the Endo is encoded in "interface_id" - * argument. - * - * Returns a pointer to the new interfce or a null pointer if a - * failure occurs due to memory exhaustion. - */ -struct gb_interface *gb_interface_create(struct gb_module *module, - u8 interface_id) -{ - struct gb_host_device *hd = module->hd; - struct gb_interface *intf; - - intf = kzalloc(sizeof(*intf), GFP_KERNEL); - if (!intf) - return NULL; - - intf->hd = hd; /* XXX refcount? */ - intf->module = module; - intf->interface_id = interface_id; - INIT_LIST_HEAD(&intf->bundles); - INIT_LIST_HEAD(&intf->manifest_descs); - mutex_init(&intf->mutex); - INIT_WORK(&intf->mode_switch_work, gb_interface_mode_switch_work); - init_completion(&intf->mode_switch_completion); - - /* Invalid device id to start with */ - intf->device_id = GB_INTERFACE_DEVICE_ID_BAD; - - intf->dev.parent = &module->dev; - intf->dev.bus = &greybus_bus_type; - intf->dev.type = &greybus_interface_type; - intf->dev.groups = interface_groups; - intf->dev.dma_mask = module->dev.dma_mask; - device_initialize(&intf->dev); - dev_set_name(&intf->dev, "%s.%u", dev_name(&module->dev), - interface_id); - - pm_runtime_set_autosuspend_delay(&intf->dev, - GB_INTERFACE_AUTOSUSPEND_MS); - - trace_gb_interface_create(intf); - - return intf; -} - -static int gb_interface_vsys_set(struct gb_interface *intf, bool enable) -{ - struct gb_svc *svc = intf->hd->svc; - int ret; - - dev_dbg(&intf->dev, "%s - %d\n", __func__, enable); - - ret = gb_svc_intf_vsys_set(svc, intf->interface_id, enable); - if (ret) { - dev_err(&intf->dev, "failed to set v_sys: %d\n", ret); - return ret; - } - - return 0; -} - -static int gb_interface_refclk_set(struct gb_interface *intf, bool enable) -{ - struct gb_svc *svc = intf->hd->svc; - int ret; - - dev_dbg(&intf->dev, "%s - %d\n", __func__, enable); - - ret = gb_svc_intf_refclk_set(svc, intf->interface_id, enable); - if (ret) { - dev_err(&intf->dev, "failed to set refclk: %d\n", ret); - return ret; - } - - return 0; -} - -static int gb_interface_unipro_set(struct gb_interface *intf, bool enable) -{ - struct gb_svc *svc = intf->hd->svc; - int ret; - - dev_dbg(&intf->dev, "%s - %d\n", __func__, enable); - - ret = gb_svc_intf_unipro_set(svc, intf->interface_id, enable); - if (ret) { - dev_err(&intf->dev, "failed to set UniPro: %d\n", ret); - return ret; - } - - return 0; -} - -static int gb_interface_activate_operation(struct gb_interface *intf, - enum gb_interface_type *intf_type) -{ - struct gb_svc *svc = intf->hd->svc; - u8 type; - int ret; - - dev_dbg(&intf->dev, "%s\n", __func__); - - ret = gb_svc_intf_activate(svc, intf->interface_id, &type); - if (ret) { - dev_err(&intf->dev, "failed to activate: %d\n", ret); - return ret; - } - - switch (type) { - case GB_SVC_INTF_TYPE_DUMMY: - *intf_type = GB_INTERFACE_TYPE_DUMMY; - /* FIXME: handle as an error for now */ - return -ENODEV; - case GB_SVC_INTF_TYPE_UNIPRO: - *intf_type = GB_INTERFACE_TYPE_UNIPRO; - dev_err(&intf->dev, "interface type UniPro not supported\n"); - /* FIXME: handle as an error for now */ - return -ENODEV; - case GB_SVC_INTF_TYPE_GREYBUS: - *intf_type = GB_INTERFACE_TYPE_GREYBUS; - break; - default: - dev_err(&intf->dev, "unknown interface type: %u\n", type); - *intf_type = GB_INTERFACE_TYPE_UNKNOWN; - return -ENODEV; - } - - return 0; -} - -static int gb_interface_hibernate_link(struct gb_interface *intf) -{ - struct gb_svc *svc = intf->hd->svc; - - return gb_svc_intf_set_power_mode_hibernate(svc, intf->interface_id); -} - -static int _gb_interface_activate(struct gb_interface *intf, - enum gb_interface_type *type) -{ - int ret; - - *type = GB_INTERFACE_TYPE_UNKNOWN; - - if (intf->ejected || intf->removed) - return -ENODEV; - - ret = gb_interface_vsys_set(intf, true); - if (ret) - return ret; - - ret = gb_interface_refclk_set(intf, true); - if (ret) - goto err_vsys_disable; - - ret = gb_interface_unipro_set(intf, true); - if (ret) - goto err_refclk_disable; - - ret = gb_interface_activate_operation(intf, type); - if (ret) { - switch (*type) { - case GB_INTERFACE_TYPE_UNIPRO: - case GB_INTERFACE_TYPE_GREYBUS: - goto err_hibernate_link; - default: - goto err_unipro_disable; - } - } - - ret = gb_interface_read_dme(intf); - if (ret) - goto err_hibernate_link; - - ret = gb_interface_route_create(intf); - if (ret) - goto err_hibernate_link; - - intf->active = true; - - trace_gb_interface_activate(intf); - - return 0; - -err_hibernate_link: - gb_interface_hibernate_link(intf); -err_unipro_disable: - gb_interface_unipro_set(intf, false); -err_refclk_disable: - gb_interface_refclk_set(intf, false); -err_vsys_disable: - gb_interface_vsys_set(intf, false); - - return ret; -} - -/* - * At present, we assume a UniPro-only module to be a Greybus module that - * failed to send its mailbox poke. There is some reason to believe that this - * is because of a bug in the ES3 bootrom. - * - * FIXME: Check if this is a Toshiba bridge before retrying? - */ -static int _gb_interface_activate_es3_hack(struct gb_interface *intf, - enum gb_interface_type *type) -{ - int retries = 3; - int ret; - - while (retries--) { - ret = _gb_interface_activate(intf, type); - if (ret == -ENODEV && *type == GB_INTERFACE_TYPE_UNIPRO) - continue; - - break; - } - - return ret; -} - -/* - * Activate an interface. - * - * Locking: Caller holds the interface mutex. - */ -int gb_interface_activate(struct gb_interface *intf) -{ - enum gb_interface_type type; - int ret; - - switch (intf->type) { - case GB_INTERFACE_TYPE_INVALID: - case GB_INTERFACE_TYPE_GREYBUS: - ret = _gb_interface_activate_es3_hack(intf, &type); - break; - default: - ret = _gb_interface_activate(intf, &type); - } - - /* Make sure type is detected correctly during reactivation. */ - if (intf->type != GB_INTERFACE_TYPE_INVALID) { - if (type != intf->type) { - dev_err(&intf->dev, "failed to detect interface type\n"); - - if (!ret) - gb_interface_deactivate(intf); - - return -EIO; - } - } else { - intf->type = type; - } - - return ret; -} - -/* - * Deactivate an interface. - * - * Locking: Caller holds the interface mutex. - */ -void gb_interface_deactivate(struct gb_interface *intf) -{ - if (!intf->active) - return; - - trace_gb_interface_deactivate(intf); - - /* Abort any ongoing mode switch. */ - if (intf->mode_switch) - complete(&intf->mode_switch_completion); - - gb_interface_route_destroy(intf); - gb_interface_hibernate_link(intf); - gb_interface_unipro_set(intf, false); - gb_interface_refclk_set(intf, false); - gb_interface_vsys_set(intf, false); - - intf->active = false; -} - -/* - * Enable an interface by enabling its control connection, fetching the - * manifest and other information over it, and finally registering its child - * devices. - * - * Locking: Caller holds the interface mutex. - */ -int gb_interface_enable(struct gb_interface *intf) -{ - struct gb_control *control; - struct gb_bundle *bundle, *tmp; - int ret, size; - void *manifest; - - ret = gb_interface_read_and_clear_init_status(intf); - if (ret) { - dev_err(&intf->dev, "failed to clear init status: %d\n", ret); - return ret; - } - - /* Establish control connection */ - control = gb_control_create(intf); - if (IS_ERR(control)) { - dev_err(&intf->dev, "failed to create control device: %ld\n", - PTR_ERR(control)); - return PTR_ERR(control); - } - intf->control = control; - - ret = gb_control_enable(intf->control); - if (ret) - goto err_put_control; - - /* Get manifest size using control protocol on CPort */ - size = gb_control_get_manifest_size_operation(intf); - if (size <= 0) { - dev_err(&intf->dev, "failed to get manifest size: %d\n", size); - - if (size) - ret = size; - else - ret = -EINVAL; - - goto err_disable_control; - } - - manifest = kmalloc(size, GFP_KERNEL); - if (!manifest) { - ret = -ENOMEM; - goto err_disable_control; - } - - /* Get manifest using control protocol on CPort */ - ret = gb_control_get_manifest_operation(intf, manifest, size); - if (ret) { - dev_err(&intf->dev, "failed to get manifest: %d\n", ret); - goto err_free_manifest; - } - - /* - * Parse the manifest and build up our data structures representing - * what's in it. - */ - if (!gb_manifest_parse(intf, manifest, size)) { - dev_err(&intf->dev, "failed to parse manifest\n"); - ret = -EINVAL; - goto err_destroy_bundles; - } - - ret = gb_control_get_bundle_versions(intf->control); - if (ret) - goto err_destroy_bundles; - - /* Register the control device and any bundles */ - ret = gb_control_add(intf->control); - if (ret) - goto err_destroy_bundles; - - pm_runtime_use_autosuspend(&intf->dev); - pm_runtime_get_noresume(&intf->dev); - pm_runtime_set_active(&intf->dev); - pm_runtime_enable(&intf->dev); - - list_for_each_entry_safe_reverse(bundle, tmp, &intf->bundles, links) { - ret = gb_bundle_add(bundle); - if (ret) { - gb_bundle_destroy(bundle); - continue; - } - } - - kfree(manifest); - - intf->enabled = true; - - pm_runtime_put(&intf->dev); - - trace_gb_interface_enable(intf); - - return 0; - -err_destroy_bundles: - list_for_each_entry_safe(bundle, tmp, &intf->bundles, links) - gb_bundle_destroy(bundle); -err_free_manifest: - kfree(manifest); -err_disable_control: - gb_control_disable(intf->control); -err_put_control: - gb_control_put(intf->control); - intf->control = NULL; - - return ret; -} - -/* - * Disable an interface and destroy its bundles. - * - * Locking: Caller holds the interface mutex. - */ -void gb_interface_disable(struct gb_interface *intf) -{ - struct gb_bundle *bundle; - struct gb_bundle *next; - - if (!intf->enabled) - return; - - trace_gb_interface_disable(intf); - - pm_runtime_get_sync(&intf->dev); - - /* Set disconnected flag to avoid I/O during connection tear down. */ - if (intf->quirks & GB_INTERFACE_QUIRK_FORCED_DISABLE) - intf->disconnected = true; - - list_for_each_entry_safe(bundle, next, &intf->bundles, links) - gb_bundle_destroy(bundle); - - if (!intf->mode_switch && !intf->disconnected) - gb_control_interface_deactivate_prepare(intf->control); - - gb_control_del(intf->control); - gb_control_disable(intf->control); - gb_control_put(intf->control); - intf->control = NULL; - - intf->enabled = false; - - pm_runtime_disable(&intf->dev); - pm_runtime_set_suspended(&intf->dev); - pm_runtime_dont_use_autosuspend(&intf->dev); - pm_runtime_put_noidle(&intf->dev); -} - -/* Register an interface. */ -int gb_interface_add(struct gb_interface *intf) -{ - int ret; - - ret = device_add(&intf->dev); - if (ret) { - dev_err(&intf->dev, "failed to register interface: %d\n", ret); - return ret; - } - - trace_gb_interface_add(intf); - - dev_info(&intf->dev, "Interface added (%s)\n", - gb_interface_type_string(intf)); - - switch (intf->type) { - case GB_INTERFACE_TYPE_GREYBUS: - dev_info(&intf->dev, "GMP VID=0x%08x, PID=0x%08x\n", - intf->vendor_id, intf->product_id); - /* fall-through */ - case GB_INTERFACE_TYPE_UNIPRO: - dev_info(&intf->dev, "DDBL1 Manufacturer=0x%08x, Product=0x%08x\n", - intf->ddbl1_manufacturer_id, - intf->ddbl1_product_id); - break; - default: - break; - } - - return 0; -} - -/* Deregister an interface. */ -void gb_interface_del(struct gb_interface *intf) -{ - if (device_is_registered(&intf->dev)) { - trace_gb_interface_del(intf); - - device_del(&intf->dev); - dev_info(&intf->dev, "Interface removed\n"); - } -} - -void gb_interface_put(struct gb_interface *intf) -{ - put_device(&intf->dev); -} diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h deleted file mode 100644 index 1c00c5bb3ec9..000000000000 --- a/drivers/staging/greybus/interface.h +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus Interface Block code - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#ifndef __INTERFACE_H -#define __INTERFACE_H - -enum gb_interface_type { - GB_INTERFACE_TYPE_INVALID = 0, - GB_INTERFACE_TYPE_UNKNOWN, - GB_INTERFACE_TYPE_DUMMY, - GB_INTERFACE_TYPE_UNIPRO, - GB_INTERFACE_TYPE_GREYBUS, -}; - -#define GB_INTERFACE_QUIRK_NO_CPORT_FEATURES BIT(0) -#define GB_INTERFACE_QUIRK_NO_INIT_STATUS BIT(1) -#define GB_INTERFACE_QUIRK_NO_GMP_IDS BIT(2) -#define GB_INTERFACE_QUIRK_FORCED_DISABLE BIT(3) -#define GB_INTERFACE_QUIRK_LEGACY_MODE_SWITCH BIT(4) -#define GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE BIT(5) -#define GB_INTERFACE_QUIRK_NO_PM BIT(6) - -struct gb_interface { - struct device dev; - struct gb_control *control; - - struct list_head bundles; - struct list_head module_node; - struct list_head manifest_descs; - u8 interface_id; /* Physical location within the Endo */ - u8 device_id; - u8 features; /* Feature flags set in the manifest */ - - enum gb_interface_type type; - - u32 ddbl1_manufacturer_id; - u32 ddbl1_product_id; - u32 vendor_id; - u32 product_id; - u64 serial_number; - - struct gb_host_device *hd; - struct gb_module *module; - - unsigned long quirks; - - struct mutex mutex; - - bool disconnected; - - bool ejected; - bool removed; - bool active; - bool enabled; - bool mode_switch; - bool dme_read; - - struct work_struct mode_switch_work; - struct completion mode_switch_completion; -}; -#define to_gb_interface(d) container_of(d, struct gb_interface, dev) - -struct gb_interface *gb_interface_create(struct gb_module *module, - u8 interface_id); -int gb_interface_activate(struct gb_interface *intf); -void gb_interface_deactivate(struct gb_interface *intf); -int gb_interface_enable(struct gb_interface *intf); -void gb_interface_disable(struct gb_interface *intf); -int gb_interface_add(struct gb_interface *intf); -void gb_interface_del(struct gb_interface *intf); -void gb_interface_put(struct gb_interface *intf); -void gb_interface_mailbox_event(struct gb_interface *intf, u16 result, - u32 mailbox); - -int gb_interface_request_mode_switch(struct gb_interface *intf); - -#endif /* __INTERFACE_H */ diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c index 010ae1e9c7fb..d6ba25f21d80 100644 --- a/drivers/staging/greybus/light.c +++ b/drivers/staging/greybus/light.c @@ -11,11 +11,9 @@ #include <linux/led-class-flash.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/greybus.h> #include <media/v4l2-flash-led-class.h> -#include "greybus.h" -#include "greybus_protocols.h" - #define NAMES_MAX 32 struct gb_channel { @@ -1098,21 +1096,21 @@ static void gb_lights_channel_release(struct gb_channel *channel) static void gb_lights_light_release(struct gb_light *light) { int i; - int count; light->ready = false; - count = light->channels_count; - if (light->has_flash) gb_lights_light_v4l2_unregister(light); + light->has_flash = false; - for (i = 0; i < count; i++) { + for (i = 0; i < light->channels_count; i++) gb_lights_channel_release(&light->channels[i]); - light->channels_count--; - } + light->channels_count = 0; + kfree(light->channels); + light->channels = NULL; kfree(light->name); + light->name = NULL; } static void gb_lights_release(struct gb_lights *glights) diff --git a/drivers/staging/greybus/log.c b/drivers/staging/greybus/log.c index 15a88574dbb0..971f36dccac6 100644 --- a/drivers/staging/greybus/log.c +++ b/drivers/staging/greybus/log.c @@ -9,8 +9,7 @@ #include <linux/slab.h> #include <linux/sizes.h> #include <linux/uaccess.h> - -#include "greybus.h" +#include <linux/greybus.h> struct gb_log { struct gb_connection *connection; @@ -31,14 +30,14 @@ static int gb_log_request_handler(struct gb_operation *op) /* Verify size of payload */ if (op->request->payload_size < sizeof(*receive)) { dev_err(dev, "log request too small (%zu < %zu)\n", - op->request->payload_size, sizeof(*receive)); + op->request->payload_size, sizeof(*receive)); return -EINVAL; } receive = op->request->payload; len = le16_to_cpu(receive->len); if (len != (op->request->payload_size - sizeof(*receive))) { dev_err(dev, "log request wrong size %d vs %zu\n", len, - (op->request->payload_size - sizeof(*receive))); + (op->request->payload_size - sizeof(*receive))); return -EINVAL; } if (len == 0) { @@ -83,7 +82,7 @@ static int gb_log_probe(struct gb_bundle *bundle, return -ENOMEM; connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id), - gb_log_request_handler); + gb_log_request_handler); if (IS_ERR(connection)) { retval = PTR_ERR(connection); goto error_free; diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 48d85ebe404a..583d9708a191 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -25,12 +25,9 @@ #include <linux/workqueue.h> #include <linux/atomic.h> #include <linux/pm_runtime.h> - +#include <linux/greybus.h> #include <asm/div64.h> -#include "greybus.h" -#include "connection.h" - #define NSEC_PER_DAY 86400000000000ULL struct gb_loopback_stats { @@ -882,7 +879,7 @@ static int gb_loopback_fn(void *data) gb->type = 0; gb->send_count = 0; sysfs_notify(&gb->dev->kobj, NULL, - "iteration_count"); + "iteration_count"); dev_dbg(&bundle->dev, "load test complete\n"); } else { dev_dbg(&bundle->dev, @@ -1054,7 +1051,7 @@ static int gb_loopback_probe(struct gb_bundle *bundle, /* Allocate kfifo */ if (kfifo_alloc(&gb->kfifo_lat, kfifo_depth * sizeof(u32), - GFP_KERNEL)) { + GFP_KERNEL)) { retval = -ENOMEM; goto out_conn; } diff --git a/drivers/staging/greybus/manifest.c b/drivers/staging/greybus/manifest.c deleted file mode 100644 index 08db49264f2b..000000000000 --- a/drivers/staging/greybus/manifest.c +++ /dev/null @@ -1,534 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus manifest parsing - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#include "greybus.h" - -static const char *get_descriptor_type_string(u8 type) -{ - switch (type) { - case GREYBUS_TYPE_INVALID: - return "invalid"; - case GREYBUS_TYPE_STRING: - return "string"; - case GREYBUS_TYPE_INTERFACE: - return "interface"; - case GREYBUS_TYPE_CPORT: - return "cport"; - case GREYBUS_TYPE_BUNDLE: - return "bundle"; - default: - WARN_ON(1); - return "unknown"; - } -} - -/* - * We scan the manifest once to identify where all the descriptors - * are. The result is a list of these manifest_desc structures. We - * then pick through them for what we're looking for (starting with - * the interface descriptor). As each is processed we remove it from - * the list. When we're done the list should (probably) be empty. - */ -struct manifest_desc { - struct list_head links; - - size_t size; - void *data; - enum greybus_descriptor_type type; -}; - -static void release_manifest_descriptor(struct manifest_desc *descriptor) -{ - list_del(&descriptor->links); - kfree(descriptor); -} - -static void release_manifest_descriptors(struct gb_interface *intf) -{ - struct manifest_desc *descriptor; - struct manifest_desc *next; - - list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links) - release_manifest_descriptor(descriptor); -} - -static void release_cport_descriptors(struct list_head *head, u8 bundle_id) -{ - struct manifest_desc *desc, *tmp; - struct greybus_descriptor_cport *desc_cport; - - list_for_each_entry_safe(desc, tmp, head, links) { - desc_cport = desc->data; - - if (desc->type != GREYBUS_TYPE_CPORT) - continue; - - if (desc_cport->bundle == bundle_id) - release_manifest_descriptor(desc); - } -} - -static struct manifest_desc *get_next_bundle_desc(struct gb_interface *intf) -{ - struct manifest_desc *descriptor; - struct manifest_desc *next; - - list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links) - if (descriptor->type == GREYBUS_TYPE_BUNDLE) - return descriptor; - - return NULL; -} - -/* - * Validate the given descriptor. Its reported size must fit within - * the number of bytes remaining, and it must have a recognized - * type. Check that the reported size is at least as big as what - * we expect to see. (It could be bigger, perhaps for a new version - * of the format.) - * - * Returns the (non-zero) number of bytes consumed by the descriptor, - * or a negative errno. - */ -static int identify_descriptor(struct gb_interface *intf, - struct greybus_descriptor *desc, size_t size) -{ - struct greybus_descriptor_header *desc_header = &desc->header; - struct manifest_desc *descriptor; - size_t desc_size; - size_t expected_size; - - if (size < sizeof(*desc_header)) { - dev_err(&intf->dev, "manifest too small (%zu < %zu)\n", - size, sizeof(*desc_header)); - return -EINVAL; /* Must at least have header */ - } - - desc_size = le16_to_cpu(desc_header->size); - if (desc_size > size) { - dev_err(&intf->dev, "descriptor too big (%zu > %zu)\n", - desc_size, size); - return -EINVAL; - } - - /* Descriptor needs to at least have a header */ - expected_size = sizeof(*desc_header); - - switch (desc_header->type) { - case GREYBUS_TYPE_STRING: - expected_size += sizeof(struct greybus_descriptor_string); - expected_size += desc->string.length; - - /* String descriptors are padded to 4 byte boundaries */ - expected_size = ALIGN(expected_size, 4); - break; - case GREYBUS_TYPE_INTERFACE: - expected_size += sizeof(struct greybus_descriptor_interface); - break; - case GREYBUS_TYPE_BUNDLE: - expected_size += sizeof(struct greybus_descriptor_bundle); - break; - case GREYBUS_TYPE_CPORT: - expected_size += sizeof(struct greybus_descriptor_cport); - break; - case GREYBUS_TYPE_INVALID: - default: - dev_err(&intf->dev, "invalid descriptor type (%u)\n", - desc_header->type); - return -EINVAL; - } - - if (desc_size < expected_size) { - dev_err(&intf->dev, "%s descriptor too small (%zu < %zu)\n", - get_descriptor_type_string(desc_header->type), - desc_size, expected_size); - return -EINVAL; - } - - /* Descriptor bigger than what we expect */ - if (desc_size > expected_size) { - dev_warn(&intf->dev, "%s descriptor size mismatch (want %zu got %zu)\n", - get_descriptor_type_string(desc_header->type), - expected_size, desc_size); - } - - descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL); - if (!descriptor) - return -ENOMEM; - - descriptor->size = desc_size; - descriptor->data = (char *)desc + sizeof(*desc_header); - descriptor->type = desc_header->type; - list_add_tail(&descriptor->links, &intf->manifest_descs); - - /* desc_size is positive and is known to fit in a signed int */ - - return desc_size; -} - -/* - * Find the string descriptor having the given id, validate it, and - * allocate a duplicate copy of it. The duplicate has an extra byte - * which guarantees the returned string is NUL-terminated. - * - * String index 0 is valid (it represents "no string"), and for - * that a null pointer is returned. - * - * Otherwise returns a pointer to a newly-allocated copy of the - * descriptor string, or an error-coded pointer on failure. - */ -static char *gb_string_get(struct gb_interface *intf, u8 string_id) -{ - struct greybus_descriptor_string *desc_string; - struct manifest_desc *descriptor; - bool found = false; - char *string; - - /* A zero string id means no string (but no error) */ - if (!string_id) - return NULL; - - list_for_each_entry(descriptor, &intf->manifest_descs, links) { - if (descriptor->type != GREYBUS_TYPE_STRING) - continue; - - desc_string = descriptor->data; - if (desc_string->id == string_id) { - found = true; - break; - } - } - if (!found) - return ERR_PTR(-ENOENT); - - /* Allocate an extra byte so we can guarantee it's NUL-terminated */ - string = kmemdup(&desc_string->string, desc_string->length + 1, - GFP_KERNEL); - if (!string) - return ERR_PTR(-ENOMEM); - string[desc_string->length] = '\0'; - - /* Ok we've used this string, so we're done with it */ - release_manifest_descriptor(descriptor); - - return string; -} - -/* - * Find cport descriptors in the manifest associated with the given - * bundle, and set up data structures for the functions that use - * them. Returns the number of cports set up for the bundle, or 0 - * if there is an error. - */ -static u32 gb_manifest_parse_cports(struct gb_bundle *bundle) -{ - struct gb_interface *intf = bundle->intf; - struct greybus_descriptor_cport *desc_cport; - struct manifest_desc *desc, *next, *tmp; - LIST_HEAD(list); - u8 bundle_id = bundle->id; - u16 cport_id; - u32 count = 0; - int i; - - /* Set up all cport descriptors associated with this bundle */ - list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) { - if (desc->type != GREYBUS_TYPE_CPORT) - continue; - - desc_cport = desc->data; - if (desc_cport->bundle != bundle_id) - continue; - - cport_id = le16_to_cpu(desc_cport->id); - if (cport_id > CPORT_ID_MAX) - goto exit; - - /* Nothing else should have its cport_id as control cport id */ - if (cport_id == GB_CONTROL_CPORT_ID) { - dev_err(&bundle->dev, "invalid cport id found (%02u)\n", - cport_id); - goto exit; - } - - /* - * Found one, move it to our temporary list after checking for - * duplicates. - */ - list_for_each_entry(tmp, &list, links) { - desc_cport = tmp->data; - if (cport_id == le16_to_cpu(desc_cport->id)) { - dev_err(&bundle->dev, - "duplicate CPort %u found\n", - cport_id); - goto exit; - } - } - list_move_tail(&desc->links, &list); - count++; - } - - if (!count) - return 0; - - bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc), - GFP_KERNEL); - if (!bundle->cport_desc) - goto exit; - - bundle->num_cports = count; - - i = 0; - list_for_each_entry_safe(desc, next, &list, links) { - desc_cport = desc->data; - memcpy(&bundle->cport_desc[i++], desc_cport, - sizeof(*desc_cport)); - - /* Release the cport descriptor */ - release_manifest_descriptor(desc); - } - - return count; -exit: - release_cport_descriptors(&list, bundle_id); - /* - * Free all cports for this bundle to avoid 'excess descriptors' - * warnings. - */ - release_cport_descriptors(&intf->manifest_descs, bundle_id); - - return 0; /* Error; count should also be 0 */ -} - -/* - * Find bundle descriptors in the manifest and set up their data - * structures. Returns the number of bundles set up for the - * given interface. - */ -static u32 gb_manifest_parse_bundles(struct gb_interface *intf) -{ - struct manifest_desc *desc; - struct gb_bundle *bundle; - struct gb_bundle *bundle_next; - u32 count = 0; - u8 bundle_id; - u8 class; - - while ((desc = get_next_bundle_desc(intf))) { - struct greybus_descriptor_bundle *desc_bundle; - - /* Found one. Set up its bundle structure*/ - desc_bundle = desc->data; - bundle_id = desc_bundle->id; - class = desc_bundle->class; - - /* Done with this bundle descriptor */ - release_manifest_descriptor(desc); - - /* Ignore any legacy control bundles */ - if (bundle_id == GB_CONTROL_BUNDLE_ID) { - dev_dbg(&intf->dev, "%s - ignoring control bundle\n", - __func__); - release_cport_descriptors(&intf->manifest_descs, - bundle_id); - continue; - } - - /* Nothing else should have its class set to control class */ - if (class == GREYBUS_CLASS_CONTROL) { - dev_err(&intf->dev, - "bundle %u cannot use control class\n", - bundle_id); - goto cleanup; - } - - bundle = gb_bundle_create(intf, bundle_id, class); - if (!bundle) - goto cleanup; - - /* - * Now go set up this bundle's functions and cports. - * - * A 'bundle' represents a device in greybus. It may require - * multiple cports for its functioning. If we fail to setup any - * cport of a bundle, we better reject the complete bundle as - * the device may not be able to function properly then. - * - * But, failing to setup a cport of bundle X doesn't mean that - * the device corresponding to bundle Y will not work properly. - * Bundles should be treated as separate independent devices. - * - * While parsing manifest for an interface, treat bundles as - * separate entities and don't reject entire interface and its - * bundles on failing to initialize a cport. But make sure the - * bundle which needs the cport, gets destroyed properly. - */ - if (!gb_manifest_parse_cports(bundle)) { - gb_bundle_destroy(bundle); - continue; - } - - count++; - } - - return count; -cleanup: - /* An error occurred; undo any changes we've made */ - list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) { - gb_bundle_destroy(bundle); - count--; - } - return 0; /* Error; count should also be 0 */ -} - -static bool gb_manifest_parse_interface(struct gb_interface *intf, - struct manifest_desc *interface_desc) -{ - struct greybus_descriptor_interface *desc_intf = interface_desc->data; - struct gb_control *control = intf->control; - char *str; - - /* Handle the strings first--they can fail */ - str = gb_string_get(intf, desc_intf->vendor_stringid); - if (IS_ERR(str)) - return false; - control->vendor_string = str; - - str = gb_string_get(intf, desc_intf->product_stringid); - if (IS_ERR(str)) - goto out_free_vendor_string; - control->product_string = str; - - /* Assign feature flags communicated via manifest */ - intf->features = desc_intf->features; - - /* Release the interface descriptor, now that we're done with it */ - release_manifest_descriptor(interface_desc); - - /* An interface must have at least one bundle descriptor */ - if (!gb_manifest_parse_bundles(intf)) { - dev_err(&intf->dev, "manifest bundle descriptors not valid\n"); - goto out_err; - } - - return true; -out_err: - kfree(control->product_string); - control->product_string = NULL; -out_free_vendor_string: - kfree(control->vendor_string); - control->vendor_string = NULL; - - return false; -} - -/* - * Parse a buffer containing an interface manifest. - * - * If we find anything wrong with the content/format of the buffer - * we reject it. - * - * The first requirement is that the manifest's version is - * one we can parse. - * - * We make an initial pass through the buffer and identify all of - * the descriptors it contains, keeping track for each its type - * and the location size of its data in the buffer. - * - * Next we scan the descriptors, looking for an interface descriptor; - * there must be exactly one of those. When found, we record the - * information it contains, and then remove that descriptor (and any - * string descriptors it refers to) from further consideration. - * - * After that we look for the interface's bundles--there must be at - * least one of those. - * - * Returns true if parsing was successful, false otherwise. - */ -bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size) -{ - struct greybus_manifest *manifest; - struct greybus_manifest_header *header; - struct greybus_descriptor *desc; - struct manifest_desc *descriptor; - struct manifest_desc *interface_desc = NULL; - u16 manifest_size; - u32 found = 0; - bool result; - - /* Manifest descriptor list should be empty here */ - if (WARN_ON(!list_empty(&intf->manifest_descs))) - return false; - - /* we have to have at _least_ the manifest header */ - if (size < sizeof(*header)) { - dev_err(&intf->dev, "short manifest (%zu < %zu)\n", - size, sizeof(*header)); - return false; - } - - /* Make sure the size is right */ - manifest = data; - header = &manifest->header; - manifest_size = le16_to_cpu(header->size); - if (manifest_size != size) { - dev_err(&intf->dev, "manifest size mismatch (%zu != %u)\n", - size, manifest_size); - return false; - } - - /* Validate major/minor number */ - if (header->version_major > GREYBUS_VERSION_MAJOR) { - dev_err(&intf->dev, "manifest version too new (%u.%u > %u.%u)\n", - header->version_major, header->version_minor, - GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR); - return false; - } - - /* OK, find all the descriptors */ - desc = manifest->descriptors; - size -= sizeof(*header); - while (size) { - int desc_size; - - desc_size = identify_descriptor(intf, desc, size); - if (desc_size < 0) { - result = false; - goto out; - } - desc = (struct greybus_descriptor *)((char *)desc + desc_size); - size -= desc_size; - } - - /* There must be a single interface descriptor */ - list_for_each_entry(descriptor, &intf->manifest_descs, links) { - if (descriptor->type == GREYBUS_TYPE_INTERFACE) - if (!found++) - interface_desc = descriptor; - } - if (found != 1) { - dev_err(&intf->dev, "manifest must have 1 interface descriptor (%u found)\n", - found); - result = false; - goto out; - } - - /* Parse the manifest, starting with the interface descriptor */ - result = gb_manifest_parse_interface(intf, interface_desc); - - /* - * We really should have no remaining descriptors, but we - * don't know what newer format manifests might leave. - */ - if (result && !list_empty(&intf->manifest_descs)) - dev_info(&intf->dev, "excess descriptors in interface manifest\n"); -out: - release_manifest_descriptors(intf); - - return result; -} diff --git a/drivers/staging/greybus/manifest.h b/drivers/staging/greybus/manifest.h deleted file mode 100644 index f3c95a255631..000000000000 --- a/drivers/staging/greybus/manifest.h +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus manifest parsing - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#ifndef __MANIFEST_H -#define __MANIFEST_H - -struct gb_interface; -bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size); - -#endif /* __MANIFEST_H */ diff --git a/drivers/staging/greybus/module.c b/drivers/staging/greybus/module.c deleted file mode 100644 index b251a53d0e8e..000000000000 --- a/drivers/staging/greybus/module.c +++ /dev/null @@ -1,236 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus Module code - * - * Copyright 2016 Google Inc. - * Copyright 2016 Linaro Ltd. - */ - -#include "greybus.h" -#include "greybus_trace.h" - -static ssize_t eject_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct gb_module *module = to_gb_module(dev); - struct gb_interface *intf; - size_t i; - long val; - int ret; - - ret = kstrtol(buf, 0, &val); - if (ret) - return ret; - - if (!val) - return len; - - for (i = 0; i < module->num_interfaces; ++i) { - intf = module->interfaces[i]; - - mutex_lock(&intf->mutex); - /* Set flag to prevent concurrent activation. */ - intf->ejected = true; - gb_interface_disable(intf); - gb_interface_deactivate(intf); - mutex_unlock(&intf->mutex); - } - - /* Tell the SVC to eject the primary interface. */ - ret = gb_svc_intf_eject(module->hd->svc, module->module_id); - if (ret) - return ret; - - return len; -} -static DEVICE_ATTR_WO(eject); - -static ssize_t module_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_module *module = to_gb_module(dev); - - return sprintf(buf, "%u\n", module->module_id); -} -static DEVICE_ATTR_RO(module_id); - -static ssize_t num_interfaces_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_module *module = to_gb_module(dev); - - return sprintf(buf, "%zu\n", module->num_interfaces); -} -static DEVICE_ATTR_RO(num_interfaces); - -static struct attribute *module_attrs[] = { - &dev_attr_eject.attr, - &dev_attr_module_id.attr, - &dev_attr_num_interfaces.attr, - NULL, -}; -ATTRIBUTE_GROUPS(module); - -static void gb_module_release(struct device *dev) -{ - struct gb_module *module = to_gb_module(dev); - - trace_gb_module_release(module); - - kfree(module); -} - -struct device_type greybus_module_type = { - .name = "greybus_module", - .release = gb_module_release, -}; - -struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id, - size_t num_interfaces) -{ - struct gb_interface *intf; - struct gb_module *module; - int i; - - module = kzalloc(struct_size(module, interfaces, num_interfaces), - GFP_KERNEL); - if (!module) - return NULL; - - module->hd = hd; - module->module_id = module_id; - module->num_interfaces = num_interfaces; - - module->dev.parent = &hd->dev; - module->dev.bus = &greybus_bus_type; - module->dev.type = &greybus_module_type; - module->dev.groups = module_groups; - module->dev.dma_mask = hd->dev.dma_mask; - device_initialize(&module->dev); - dev_set_name(&module->dev, "%d-%u", hd->bus_id, module_id); - - trace_gb_module_create(module); - - for (i = 0; i < num_interfaces; ++i) { - intf = gb_interface_create(module, module_id + i); - if (!intf) { - dev_err(&module->dev, "failed to create interface %u\n", - module_id + i); - goto err_put_interfaces; - } - module->interfaces[i] = intf; - } - - return module; - -err_put_interfaces: - for (--i; i >= 0; --i) - gb_interface_put(module->interfaces[i]); - - put_device(&module->dev); - - return NULL; -} - -/* - * Register and enable an interface after first attempting to activate it. - */ -static void gb_module_register_interface(struct gb_interface *intf) -{ - struct gb_module *module = intf->module; - u8 intf_id = intf->interface_id; - int ret; - - mutex_lock(&intf->mutex); - - ret = gb_interface_activate(intf); - if (ret) { - if (intf->type != GB_INTERFACE_TYPE_DUMMY) { - dev_err(&module->dev, - "failed to activate interface %u: %d\n", - intf_id, ret); - } - - gb_interface_add(intf); - goto err_unlock; - } - - ret = gb_interface_add(intf); - if (ret) - goto err_interface_deactivate; - - ret = gb_interface_enable(intf); - if (ret) { - dev_err(&module->dev, "failed to enable interface %u: %d\n", - intf_id, ret); - goto err_interface_deactivate; - } - - mutex_unlock(&intf->mutex); - - return; - -err_interface_deactivate: - gb_interface_deactivate(intf); -err_unlock: - mutex_unlock(&intf->mutex); -} - -static void gb_module_deregister_interface(struct gb_interface *intf) -{ - /* Mark as disconnected to prevent I/O during disable. */ - if (intf->module->disconnected) - intf->disconnected = true; - - mutex_lock(&intf->mutex); - intf->removed = true; - gb_interface_disable(intf); - gb_interface_deactivate(intf); - mutex_unlock(&intf->mutex); - - gb_interface_del(intf); -} - -/* Register a module and its interfaces. */ -int gb_module_add(struct gb_module *module) -{ - size_t i; - int ret; - - ret = device_add(&module->dev); - if (ret) { - dev_err(&module->dev, "failed to register module: %d\n", ret); - return ret; - } - - trace_gb_module_add(module); - - for (i = 0; i < module->num_interfaces; ++i) - gb_module_register_interface(module->interfaces[i]); - - return 0; -} - -/* Deregister a module and its interfaces. */ -void gb_module_del(struct gb_module *module) -{ - size_t i; - - for (i = 0; i < module->num_interfaces; ++i) - gb_module_deregister_interface(module->interfaces[i]); - - trace_gb_module_del(module); - - device_del(&module->dev); -} - -void gb_module_put(struct gb_module *module) -{ - size_t i; - - for (i = 0; i < module->num_interfaces; ++i) - gb_interface_put(module->interfaces[i]); - - put_device(&module->dev); -} diff --git a/drivers/staging/greybus/module.h b/drivers/staging/greybus/module.h deleted file mode 100644 index b1ebcc6636db..000000000000 --- a/drivers/staging/greybus/module.h +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus Module code - * - * Copyright 2016 Google Inc. - * Copyright 2016 Linaro Ltd. - */ - -#ifndef __MODULE_H -#define __MODULE_H - -struct gb_module { - struct device dev; - struct gb_host_device *hd; - - struct list_head hd_node; - - u8 module_id; - size_t num_interfaces; - - bool disconnected; - - struct gb_interface *interfaces[0]; -}; -#define to_gb_module(d) container_of(d, struct gb_module, dev) - -struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id, - size_t num_interfaces); -int gb_module_add(struct gb_module *module); -void gb_module_del(struct gb_module *module); -void gb_module_put(struct gb_module *module); - -#endif /* __MODULE_H */ diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c deleted file mode 100644 index fe268f7b63ed..000000000000 --- a/drivers/staging/greybus/operation.c +++ /dev/null @@ -1,1264 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus operations - * - * Copyright 2014-2015 Google Inc. - * Copyright 2014-2015 Linaro Ltd. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/workqueue.h> - -#include "greybus.h" -#include "greybus_trace.h" - -static struct kmem_cache *gb_operation_cache; -static struct kmem_cache *gb_message_cache; - -/* Workqueue to handle Greybus operation completions. */ -static struct workqueue_struct *gb_operation_completion_wq; - -/* Wait queue for synchronous cancellations. */ -static DECLARE_WAIT_QUEUE_HEAD(gb_operation_cancellation_queue); - -/* - * Protects updates to operation->errno. - */ -static DEFINE_SPINLOCK(gb_operations_lock); - -static int gb_operation_response_send(struct gb_operation *operation, - int errno); - -/* - * Increment operation active count and add to connection list unless the - * connection is going away. - * - * Caller holds operation reference. - */ -static int gb_operation_get_active(struct gb_operation *operation) -{ - struct gb_connection *connection = operation->connection; - unsigned long flags; - - spin_lock_irqsave(&connection->lock, flags); - switch (connection->state) { - case GB_CONNECTION_STATE_ENABLED: - break; - case GB_CONNECTION_STATE_ENABLED_TX: - if (gb_operation_is_incoming(operation)) - goto err_unlock; - break; - case GB_CONNECTION_STATE_DISCONNECTING: - if (!gb_operation_is_core(operation)) - goto err_unlock; - break; - default: - goto err_unlock; - } - - if (operation->active++ == 0) - list_add_tail(&operation->links, &connection->operations); - - trace_gb_operation_get_active(operation); - - spin_unlock_irqrestore(&connection->lock, flags); - - return 0; - -err_unlock: - spin_unlock_irqrestore(&connection->lock, flags); - - return -ENOTCONN; -} - -/* Caller holds operation reference. */ -static void gb_operation_put_active(struct gb_operation *operation) -{ - struct gb_connection *connection = operation->connection; - unsigned long flags; - - spin_lock_irqsave(&connection->lock, flags); - - trace_gb_operation_put_active(operation); - - if (--operation->active == 0) { - list_del(&operation->links); - if (atomic_read(&operation->waiters)) - wake_up(&gb_operation_cancellation_queue); - } - spin_unlock_irqrestore(&connection->lock, flags); -} - -static bool gb_operation_is_active(struct gb_operation *operation) -{ - struct gb_connection *connection = operation->connection; - unsigned long flags; - bool ret; - - spin_lock_irqsave(&connection->lock, flags); - ret = operation->active; - spin_unlock_irqrestore(&connection->lock, flags); - - return ret; -} - -/* - * Set an operation's result. - * - * Initially an outgoing operation's errno value is -EBADR. - * If no error occurs before sending the request message the only - * valid value operation->errno can be set to is -EINPROGRESS, - * indicating the request has been (or rather is about to be) sent. - * At that point nobody should be looking at the result until the - * response arrives. - * - * The first time the result gets set after the request has been - * sent, that result "sticks." That is, if two concurrent threads - * race to set the result, the first one wins. The return value - * tells the caller whether its result was recorded; if not the - * caller has nothing more to do. - * - * The result value -EILSEQ is reserved to signal an implementation - * error; if it's ever observed, the code performing the request has - * done something fundamentally wrong. It is an error to try to set - * the result to -EBADR, and attempts to do so result in a warning, - * and -EILSEQ is used instead. Similarly, the only valid result - * value to set for an operation in initial state is -EINPROGRESS. - * Attempts to do otherwise will also record a (successful) -EILSEQ - * operation result. - */ -static bool gb_operation_result_set(struct gb_operation *operation, int result) -{ - unsigned long flags; - int prev; - - if (result == -EINPROGRESS) { - /* - * -EINPROGRESS is used to indicate the request is - * in flight. It should be the first result value - * set after the initial -EBADR. Issue a warning - * and record an implementation error if it's - * set at any other time. - */ - spin_lock_irqsave(&gb_operations_lock, flags); - prev = operation->errno; - if (prev == -EBADR) - operation->errno = result; - else - operation->errno = -EILSEQ; - spin_unlock_irqrestore(&gb_operations_lock, flags); - WARN_ON(prev != -EBADR); - - return true; - } - - /* - * The first result value set after a request has been sent - * will be the final result of the operation. Subsequent - * attempts to set the result are ignored. - * - * Note that -EBADR is a reserved "initial state" result - * value. Attempts to set this value result in a warning, - * and the result code is set to -EILSEQ instead. - */ - if (WARN_ON(result == -EBADR)) - result = -EILSEQ; /* Nobody should be setting -EBADR */ - - spin_lock_irqsave(&gb_operations_lock, flags); - prev = operation->errno; - if (prev == -EINPROGRESS) - operation->errno = result; /* First and final result */ - spin_unlock_irqrestore(&gb_operations_lock, flags); - - return prev == -EINPROGRESS; -} - -int gb_operation_result(struct gb_operation *operation) -{ - int result = operation->errno; - - WARN_ON(result == -EBADR); - WARN_ON(result == -EINPROGRESS); - - return result; -} -EXPORT_SYMBOL_GPL(gb_operation_result); - -/* - * Looks up an outgoing operation on a connection and returns a refcounted - * pointer if found, or NULL otherwise. - */ -static struct gb_operation * -gb_operation_find_outgoing(struct gb_connection *connection, u16 operation_id) -{ - struct gb_operation *operation; - unsigned long flags; - bool found = false; - - spin_lock_irqsave(&connection->lock, flags); - list_for_each_entry(operation, &connection->operations, links) - if (operation->id == operation_id && - !gb_operation_is_incoming(operation)) { - gb_operation_get(operation); - found = true; - break; - } - spin_unlock_irqrestore(&connection->lock, flags); - - return found ? operation : NULL; -} - -static int gb_message_send(struct gb_message *message, gfp_t gfp) -{ - struct gb_connection *connection = message->operation->connection; - - trace_gb_message_send(message); - return connection->hd->driver->message_send(connection->hd, - connection->hd_cport_id, - message, - gfp); -} - -/* - * Cancel a message we have passed to the host device layer to be sent. - */ -static void gb_message_cancel(struct gb_message *message) -{ - struct gb_host_device *hd = message->operation->connection->hd; - - hd->driver->message_cancel(message); -} - -static void gb_operation_request_handle(struct gb_operation *operation) -{ - struct gb_connection *connection = operation->connection; - int status; - int ret; - - if (connection->handler) { - status = connection->handler(operation); - } else { - dev_err(&connection->hd->dev, - "%s: unexpected incoming request of type 0x%02x\n", - connection->name, operation->type); - - status = -EPROTONOSUPPORT; - } - - ret = gb_operation_response_send(operation, status); - if (ret) { - dev_err(&connection->hd->dev, - "%s: failed to send response %d for type 0x%02x: %d\n", - connection->name, status, operation->type, ret); - return; - } -} - -/* - * Process operation work. - * - * For incoming requests, call the protocol request handler. The operation - * result should be -EINPROGRESS at this point. - * - * For outgoing requests, the operation result value should have - * been set before queueing this. The operation callback function - * allows the original requester to know the request has completed - * and its result is available. - */ -static void gb_operation_work(struct work_struct *work) -{ - struct gb_operation *operation; - int ret; - - operation = container_of(work, struct gb_operation, work); - - if (gb_operation_is_incoming(operation)) { - gb_operation_request_handle(operation); - } else { - ret = del_timer_sync(&operation->timer); - if (!ret) { - /* Cancel request message if scheduled by timeout. */ - if (gb_operation_result(operation) == -ETIMEDOUT) - gb_message_cancel(operation->request); - } - - operation->callback(operation); - } - - gb_operation_put_active(operation); - gb_operation_put(operation); -} - -static void gb_operation_timeout(struct timer_list *t) -{ - struct gb_operation *operation = from_timer(operation, t, timer); - - if (gb_operation_result_set(operation, -ETIMEDOUT)) { - /* - * A stuck request message will be cancelled from the - * workqueue. - */ - queue_work(gb_operation_completion_wq, &operation->work); - } -} - -static void gb_operation_message_init(struct gb_host_device *hd, - struct gb_message *message, - u16 operation_id, - size_t payload_size, u8 type) -{ - struct gb_operation_msg_hdr *header; - - header = message->buffer; - - message->header = header; - message->payload = payload_size ? header + 1 : NULL; - message->payload_size = payload_size; - - /* - * The type supplied for incoming message buffers will be - * GB_REQUEST_TYPE_INVALID. Such buffers will be overwritten by - * arriving data so there's no need to initialize the message header. - */ - if (type != GB_REQUEST_TYPE_INVALID) { - u16 message_size = (u16)(sizeof(*header) + payload_size); - - /* - * For a request, the operation id gets filled in - * when the message is sent. For a response, it - * will be copied from the request by the caller. - * - * The result field in a request message must be - * zero. It will be set just prior to sending for - * a response. - */ - header->size = cpu_to_le16(message_size); - header->operation_id = 0; - header->type = type; - header->result = 0; - } -} - -/* - * Allocate a message to be used for an operation request or response. - * Both types of message contain a common header. The request message - * for an outgoing operation is outbound, as is the response message - * for an incoming operation. The message header for an outbound - * message is partially initialized here. - * - * The headers for inbound messages don't need to be initialized; - * they'll be filled in by arriving data. - * - * Our message buffers have the following layout: - * message header \_ these combined are - * message payload / the message size - */ -static struct gb_message * -gb_operation_message_alloc(struct gb_host_device *hd, u8 type, - size_t payload_size, gfp_t gfp_flags) -{ - struct gb_message *message; - struct gb_operation_msg_hdr *header; - size_t message_size = payload_size + sizeof(*header); - - if (message_size > hd->buffer_size_max) { - dev_warn(&hd->dev, "requested message size too big (%zu > %zu)\n", - message_size, hd->buffer_size_max); - return NULL; - } - - /* Allocate the message structure and buffer. */ - message = kmem_cache_zalloc(gb_message_cache, gfp_flags); - if (!message) - return NULL; - - message->buffer = kzalloc(message_size, gfp_flags); - if (!message->buffer) - goto err_free_message; - - /* Initialize the message. Operation id is filled in later. */ - gb_operation_message_init(hd, message, 0, payload_size, type); - - return message; - -err_free_message: - kmem_cache_free(gb_message_cache, message); - - return NULL; -} - -static void gb_operation_message_free(struct gb_message *message) -{ - kfree(message->buffer); - kmem_cache_free(gb_message_cache, message); -} - -/* - * Map an enum gb_operation_status value (which is represented in a - * message as a single byte) to an appropriate Linux negative errno. - */ -static int gb_operation_status_map(u8 status) -{ - switch (status) { - case GB_OP_SUCCESS: - return 0; - case GB_OP_INTERRUPTED: - return -EINTR; - case GB_OP_TIMEOUT: - return -ETIMEDOUT; - case GB_OP_NO_MEMORY: - return -ENOMEM; - case GB_OP_PROTOCOL_BAD: - return -EPROTONOSUPPORT; - case GB_OP_OVERFLOW: - return -EMSGSIZE; - case GB_OP_INVALID: - return -EINVAL; - case GB_OP_RETRY: - return -EAGAIN; - case GB_OP_NONEXISTENT: - return -ENODEV; - case GB_OP_MALFUNCTION: - return -EILSEQ; - case GB_OP_UNKNOWN_ERROR: - default: - return -EIO; - } -} - -/* - * Map a Linux errno value (from operation->errno) into the value - * that should represent it in a response message status sent - * over the wire. Returns an enum gb_operation_status value (which - * is represented in a message as a single byte). - */ -static u8 gb_operation_errno_map(int errno) -{ - switch (errno) { - case 0: - return GB_OP_SUCCESS; - case -EINTR: - return GB_OP_INTERRUPTED; - case -ETIMEDOUT: - return GB_OP_TIMEOUT; - case -ENOMEM: - return GB_OP_NO_MEMORY; - case -EPROTONOSUPPORT: - return GB_OP_PROTOCOL_BAD; - case -EMSGSIZE: - return GB_OP_OVERFLOW; /* Could be underflow too */ - case -EINVAL: - return GB_OP_INVALID; - case -EAGAIN: - return GB_OP_RETRY; - case -EILSEQ: - return GB_OP_MALFUNCTION; - case -ENODEV: - return GB_OP_NONEXISTENT; - case -EIO: - default: - return GB_OP_UNKNOWN_ERROR; - } -} - -bool gb_operation_response_alloc(struct gb_operation *operation, - size_t response_size, gfp_t gfp) -{ - struct gb_host_device *hd = operation->connection->hd; - struct gb_operation_msg_hdr *request_header; - struct gb_message *response; - u8 type; - - type = operation->type | GB_MESSAGE_TYPE_RESPONSE; - response = gb_operation_message_alloc(hd, type, response_size, gfp); - if (!response) - return false; - response->operation = operation; - - /* - * Size and type get initialized when the message is - * allocated. The errno will be set before sending. All - * that's left is the operation id, which we copy from the - * request message header (as-is, in little-endian order). - */ - request_header = operation->request->header; - response->header->operation_id = request_header->operation_id; - operation->response = response; - - return true; -} -EXPORT_SYMBOL_GPL(gb_operation_response_alloc); - -/* - * Create a Greybus operation to be sent over the given connection. - * The request buffer will be big enough for a payload of the given - * size. - * - * For outgoing requests, the request message's header will be - * initialized with the type of the request and the message size. - * Outgoing operations must also specify the response buffer size, - * which must be sufficient to hold all expected response data. The - * response message header will eventually be overwritten, so there's - * no need to initialize it here. - * - * Request messages for incoming operations can arrive in interrupt - * context, so they must be allocated with GFP_ATOMIC. In this case - * the request buffer will be immediately overwritten, so there is - * no need to initialize the message header. Responsibility for - * allocating a response buffer lies with the incoming request - * handler for a protocol. So we don't allocate that here. - * - * Returns a pointer to the new operation or a null pointer if an - * error occurs. - */ -static struct gb_operation * -gb_operation_create_common(struct gb_connection *connection, u8 type, - size_t request_size, size_t response_size, - unsigned long op_flags, gfp_t gfp_flags) -{ - struct gb_host_device *hd = connection->hd; - struct gb_operation *operation; - - operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags); - if (!operation) - return NULL; - operation->connection = connection; - - operation->request = gb_operation_message_alloc(hd, type, request_size, - gfp_flags); - if (!operation->request) - goto err_cache; - operation->request->operation = operation; - - /* Allocate the response buffer for outgoing operations */ - if (!(op_flags & GB_OPERATION_FLAG_INCOMING)) { - if (!gb_operation_response_alloc(operation, response_size, - gfp_flags)) { - goto err_request; - } - - timer_setup(&operation->timer, gb_operation_timeout, 0); - } - - operation->flags = op_flags; - operation->type = type; - operation->errno = -EBADR; /* Initial value--means "never set" */ - - INIT_WORK(&operation->work, gb_operation_work); - init_completion(&operation->completion); - kref_init(&operation->kref); - atomic_set(&operation->waiters, 0); - - return operation; - -err_request: - gb_operation_message_free(operation->request); -err_cache: - kmem_cache_free(gb_operation_cache, operation); - - return NULL; -} - -/* - * Create a new operation associated with the given connection. The - * request and response sizes provided are the number of bytes - * required to hold the request/response payload only. Both of - * these are allowed to be 0. Note that 0x00 is reserved as an - * invalid operation type for all protocols, and this is enforced - * here. - */ -struct gb_operation * -gb_operation_create_flags(struct gb_connection *connection, - u8 type, size_t request_size, - size_t response_size, unsigned long flags, - gfp_t gfp) -{ - struct gb_operation *operation; - - if (WARN_ON_ONCE(type == GB_REQUEST_TYPE_INVALID)) - return NULL; - if (WARN_ON_ONCE(type & GB_MESSAGE_TYPE_RESPONSE)) - type &= ~GB_MESSAGE_TYPE_RESPONSE; - - if (WARN_ON_ONCE(flags & ~GB_OPERATION_FLAG_USER_MASK)) - flags &= GB_OPERATION_FLAG_USER_MASK; - - operation = gb_operation_create_common(connection, type, - request_size, response_size, - flags, gfp); - if (operation) - trace_gb_operation_create(operation); - - return operation; -} -EXPORT_SYMBOL_GPL(gb_operation_create_flags); - -struct gb_operation * -gb_operation_create_core(struct gb_connection *connection, - u8 type, size_t request_size, - size_t response_size, unsigned long flags, - gfp_t gfp) -{ - struct gb_operation *operation; - - flags |= GB_OPERATION_FLAG_CORE; - - operation = gb_operation_create_common(connection, type, - request_size, response_size, - flags, gfp); - if (operation) - trace_gb_operation_create_core(operation); - - return operation; -} - -/* Do not export this function. */ - -size_t gb_operation_get_payload_size_max(struct gb_connection *connection) -{ - struct gb_host_device *hd = connection->hd; - - return hd->buffer_size_max - sizeof(struct gb_operation_msg_hdr); -} -EXPORT_SYMBOL_GPL(gb_operation_get_payload_size_max); - -static struct gb_operation * -gb_operation_create_incoming(struct gb_connection *connection, u16 id, - u8 type, void *data, size_t size) -{ - struct gb_operation *operation; - size_t request_size; - unsigned long flags = GB_OPERATION_FLAG_INCOMING; - - /* Caller has made sure we at least have a message header. */ - request_size = size - sizeof(struct gb_operation_msg_hdr); - - if (!id) - flags |= GB_OPERATION_FLAG_UNIDIRECTIONAL; - - operation = gb_operation_create_common(connection, type, - request_size, - GB_REQUEST_TYPE_INVALID, - flags, GFP_ATOMIC); - if (!operation) - return NULL; - - operation->id = id; - memcpy(operation->request->header, data, size); - trace_gb_operation_create_incoming(operation); - - return operation; -} - -/* - * Get an additional reference on an operation. - */ -void gb_operation_get(struct gb_operation *operation) -{ - kref_get(&operation->kref); -} -EXPORT_SYMBOL_GPL(gb_operation_get); - -/* - * Destroy a previously created operation. - */ -static void _gb_operation_destroy(struct kref *kref) -{ - struct gb_operation *operation; - - operation = container_of(kref, struct gb_operation, kref); - - trace_gb_operation_destroy(operation); - - if (operation->response) - gb_operation_message_free(operation->response); - gb_operation_message_free(operation->request); - - kmem_cache_free(gb_operation_cache, operation); -} - -/* - * Drop a reference on an operation, and destroy it when the last - * one is gone. - */ -void gb_operation_put(struct gb_operation *operation) -{ - if (WARN_ON(!operation)) - return; - - kref_put(&operation->kref, _gb_operation_destroy); -} -EXPORT_SYMBOL_GPL(gb_operation_put); - -/* Tell the requester we're done */ -static void gb_operation_sync_callback(struct gb_operation *operation) -{ - complete(&operation->completion); -} - -/** - * gb_operation_request_send() - send an operation request message - * @operation: the operation to initiate - * @callback: the operation completion callback - * @timeout: operation timeout in milliseconds, or zero for no timeout - * @gfp: the memory flags to use for any allocations - * - * The caller has filled in any payload so the request message is ready to go. - * The callback function supplied will be called when the response message has - * arrived, a unidirectional request has been sent, or the operation is - * cancelled, indicating that the operation is complete. The callback function - * can fetch the result of the operation using gb_operation_result() if - * desired. - * - * Return: 0 if the request was successfully queued in the host-driver queues, - * or a negative errno. - */ -int gb_operation_request_send(struct gb_operation *operation, - gb_operation_callback callback, - unsigned int timeout, - gfp_t gfp) -{ - struct gb_connection *connection = operation->connection; - struct gb_operation_msg_hdr *header; - unsigned int cycle; - int ret; - - if (gb_connection_is_offloaded(connection)) - return -EBUSY; - - if (!callback) - return -EINVAL; - - /* - * Record the callback function, which is executed in - * non-atomic (workqueue) context when the final result - * of an operation has been set. - */ - operation->callback = callback; - - /* - * Assign the operation's id, and store it in the request header. - * Zero is a reserved operation id for unidirectional operations. - */ - if (gb_operation_is_unidirectional(operation)) { - operation->id = 0; - } else { - cycle = (unsigned int)atomic_inc_return(&connection->op_cycle); - operation->id = (u16)(cycle % U16_MAX + 1); - } - - header = operation->request->header; - header->operation_id = cpu_to_le16(operation->id); - - gb_operation_result_set(operation, -EINPROGRESS); - - /* - * Get an extra reference on the operation. It'll be dropped when the - * operation completes. - */ - gb_operation_get(operation); - ret = gb_operation_get_active(operation); - if (ret) - goto err_put; - - ret = gb_message_send(operation->request, gfp); - if (ret) - goto err_put_active; - - if (timeout) { - operation->timer.expires = jiffies + msecs_to_jiffies(timeout); - add_timer(&operation->timer); - } - - return 0; - -err_put_active: - gb_operation_put_active(operation); -err_put: - gb_operation_put(operation); - - return ret; -} -EXPORT_SYMBOL_GPL(gb_operation_request_send); - -/* - * Send a synchronous operation. This function is expected to - * block, returning only when the response has arrived, (or when an - * error is detected. The return value is the result of the - * operation. - */ -int gb_operation_request_send_sync_timeout(struct gb_operation *operation, - unsigned int timeout) -{ - int ret; - - ret = gb_operation_request_send(operation, gb_operation_sync_callback, - timeout, GFP_KERNEL); - if (ret) - return ret; - - ret = wait_for_completion_interruptible(&operation->completion); - if (ret < 0) { - /* Cancel the operation if interrupted */ - gb_operation_cancel(operation, -ECANCELED); - } - - return gb_operation_result(operation); -} -EXPORT_SYMBOL_GPL(gb_operation_request_send_sync_timeout); - -/* - * Send a response for an incoming operation request. A non-zero - * errno indicates a failed operation. - * - * If there is any response payload, the incoming request handler is - * responsible for allocating the response message. Otherwise the - * it can simply supply the result errno; this function will - * allocate the response message if necessary. - */ -static int gb_operation_response_send(struct gb_operation *operation, - int errno) -{ - struct gb_connection *connection = operation->connection; - int ret; - - if (!operation->response && - !gb_operation_is_unidirectional(operation)) { - if (!gb_operation_response_alloc(operation, 0, GFP_KERNEL)) - return -ENOMEM; - } - - /* Record the result */ - if (!gb_operation_result_set(operation, errno)) { - dev_err(&connection->hd->dev, "request result already set\n"); - return -EIO; /* Shouldn't happen */ - } - - /* Sender of request does not care about response. */ - if (gb_operation_is_unidirectional(operation)) - return 0; - - /* Reference will be dropped when message has been sent. */ - gb_operation_get(operation); - ret = gb_operation_get_active(operation); - if (ret) - goto err_put; - - /* Fill in the response header and send it */ - operation->response->header->result = gb_operation_errno_map(errno); - - ret = gb_message_send(operation->response, GFP_KERNEL); - if (ret) - goto err_put_active; - - return 0; - -err_put_active: - gb_operation_put_active(operation); -err_put: - gb_operation_put(operation); - - return ret; -} - -/* - * This function is called when a message send request has completed. - */ -void greybus_message_sent(struct gb_host_device *hd, - struct gb_message *message, int status) -{ - struct gb_operation *operation = message->operation; - struct gb_connection *connection = operation->connection; - - /* - * If the message was a response, we just need to drop our - * reference to the operation. If an error occurred, report - * it. - * - * For requests, if there's no error and the operation in not - * unidirectional, there's nothing more to do until the response - * arrives. If an error occurred attempting to send it, or if the - * operation is unidrectional, record the result of the operation and - * schedule its completion. - */ - if (message == operation->response) { - if (status) { - dev_err(&connection->hd->dev, - "%s: error sending response 0x%02x: %d\n", - connection->name, operation->type, status); - } - - gb_operation_put_active(operation); - gb_operation_put(operation); - } else if (status || gb_operation_is_unidirectional(operation)) { - if (gb_operation_result_set(operation, status)) { - queue_work(gb_operation_completion_wq, - &operation->work); - } - } -} -EXPORT_SYMBOL_GPL(greybus_message_sent); - -/* - * We've received data on a connection, and it doesn't look like a - * response, so we assume it's a request. - * - * This is called in interrupt context, so just copy the incoming - * data into the request buffer and handle the rest via workqueue. - */ -static void gb_connection_recv_request(struct gb_connection *connection, - const struct gb_operation_msg_hdr *header, - void *data, size_t size) -{ - struct gb_operation *operation; - u16 operation_id; - u8 type; - int ret; - - operation_id = le16_to_cpu(header->operation_id); - type = header->type; - - operation = gb_operation_create_incoming(connection, operation_id, - type, data, size); - if (!operation) { - dev_err(&connection->hd->dev, - "%s: can't create incoming operation\n", - connection->name); - return; - } - - ret = gb_operation_get_active(operation); - if (ret) { - gb_operation_put(operation); - return; - } - trace_gb_message_recv_request(operation->request); - - /* - * The initial reference to the operation will be dropped when the - * request handler returns. - */ - if (gb_operation_result_set(operation, -EINPROGRESS)) - queue_work(connection->wq, &operation->work); -} - -/* - * We've received data that appears to be an operation response - * message. Look up the operation, and record that we've received - * its response. - * - * This is called in interrupt context, so just copy the incoming - * data into the response buffer and handle the rest via workqueue. - */ -static void gb_connection_recv_response(struct gb_connection *connection, - const struct gb_operation_msg_hdr *header, - void *data, size_t size) -{ - struct gb_operation *operation; - struct gb_message *message; - size_t message_size; - u16 operation_id; - int errno; - - operation_id = le16_to_cpu(header->operation_id); - - if (!operation_id) { - dev_err_ratelimited(&connection->hd->dev, - "%s: invalid response id 0 received\n", - connection->name); - return; - } - - operation = gb_operation_find_outgoing(connection, operation_id); - if (!operation) { - dev_err_ratelimited(&connection->hd->dev, - "%s: unexpected response id 0x%04x received\n", - connection->name, operation_id); - return; - } - - errno = gb_operation_status_map(header->result); - message = operation->response; - message_size = sizeof(*header) + message->payload_size; - if (!errno && size > message_size) { - dev_err_ratelimited(&connection->hd->dev, - "%s: malformed response 0x%02x received (%zu > %zu)\n", - connection->name, header->type, - size, message_size); - errno = -EMSGSIZE; - } else if (!errno && size < message_size) { - if (gb_operation_short_response_allowed(operation)) { - message->payload_size = size - sizeof(*header); - } else { - dev_err_ratelimited(&connection->hd->dev, - "%s: short response 0x%02x received (%zu < %zu)\n", - connection->name, header->type, - size, message_size); - errno = -EMSGSIZE; - } - } - - /* We must ignore the payload if a bad status is returned */ - if (errno) - size = sizeof(*header); - - /* The rest will be handled in work queue context */ - if (gb_operation_result_set(operation, errno)) { - memcpy(message->buffer, data, size); - - trace_gb_message_recv_response(message); - - queue_work(gb_operation_completion_wq, &operation->work); - } - - gb_operation_put(operation); -} - -/* - * Handle data arriving on a connection. As soon as we return the - * supplied data buffer will be reused (so unless we do something - * with, it's effectively dropped). - */ -void gb_connection_recv(struct gb_connection *connection, - void *data, size_t size) -{ - struct gb_operation_msg_hdr header; - struct device *dev = &connection->hd->dev; - size_t msg_size; - - if (connection->state == GB_CONNECTION_STATE_DISABLED || - gb_connection_is_offloaded(connection)) { - dev_warn_ratelimited(dev, "%s: dropping %zu received bytes\n", - connection->name, size); - return; - } - - if (size < sizeof(header)) { - dev_err_ratelimited(dev, "%s: short message received\n", - connection->name); - return; - } - - /* Use memcpy as data may be unaligned */ - memcpy(&header, data, sizeof(header)); - msg_size = le16_to_cpu(header.size); - if (size < msg_size) { - dev_err_ratelimited(dev, - "%s: incomplete message 0x%04x of type 0x%02x received (%zu < %zu)\n", - connection->name, - le16_to_cpu(header.operation_id), - header.type, size, msg_size); - return; /* XXX Should still complete operation */ - } - - if (header.type & GB_MESSAGE_TYPE_RESPONSE) { - gb_connection_recv_response(connection, &header, data, - msg_size); - } else { - gb_connection_recv_request(connection, &header, data, - msg_size); - } -} - -/* - * Cancel an outgoing operation synchronously, and record the given error to - * indicate why. - */ -void gb_operation_cancel(struct gb_operation *operation, int errno) -{ - if (WARN_ON(gb_operation_is_incoming(operation))) - return; - - if (gb_operation_result_set(operation, errno)) { - gb_message_cancel(operation->request); - queue_work(gb_operation_completion_wq, &operation->work); - } - trace_gb_message_cancel_outgoing(operation->request); - - atomic_inc(&operation->waiters); - wait_event(gb_operation_cancellation_queue, - !gb_operation_is_active(operation)); - atomic_dec(&operation->waiters); -} -EXPORT_SYMBOL_GPL(gb_operation_cancel); - -/* - * Cancel an incoming operation synchronously. Called during connection tear - * down. - */ -void gb_operation_cancel_incoming(struct gb_operation *operation, int errno) -{ - if (WARN_ON(!gb_operation_is_incoming(operation))) - return; - - if (!gb_operation_is_unidirectional(operation)) { - /* - * Make sure the request handler has submitted the response - * before cancelling it. - */ - flush_work(&operation->work); - if (!gb_operation_result_set(operation, errno)) - gb_message_cancel(operation->response); - } - trace_gb_message_cancel_incoming(operation->response); - - atomic_inc(&operation->waiters); - wait_event(gb_operation_cancellation_queue, - !gb_operation_is_active(operation)); - atomic_dec(&operation->waiters); -} - -/** - * gb_operation_sync_timeout() - implement a "simple" synchronous operation - * @connection: the Greybus connection to send this to - * @type: the type of operation to send - * @request: pointer to a memory buffer to copy the request from - * @request_size: size of @request - * @response: pointer to a memory buffer to copy the response to - * @response_size: the size of @response. - * @timeout: operation timeout in milliseconds - * - * This function implements a simple synchronous Greybus operation. It sends - * the provided operation request and waits (sleeps) until the corresponding - * operation response message has been successfully received, or an error - * occurs. @request and @response are buffers to hold the request and response - * data respectively, and if they are not NULL, their size must be specified in - * @request_size and @response_size. - * - * If a response payload is to come back, and @response is not NULL, - * @response_size number of bytes will be copied into @response if the operation - * is successful. - * - * If there is an error, the response buffer is left alone. - */ -int gb_operation_sync_timeout(struct gb_connection *connection, int type, - void *request, int request_size, - void *response, int response_size, - unsigned int timeout) -{ - struct gb_operation *operation; - int ret; - - if ((response_size && !response) || - (request_size && !request)) - return -EINVAL; - - operation = gb_operation_create(connection, type, - request_size, response_size, - GFP_KERNEL); - if (!operation) - return -ENOMEM; - - if (request_size) - memcpy(operation->request->payload, request, request_size); - - ret = gb_operation_request_send_sync_timeout(operation, timeout); - if (ret) { - dev_err(&connection->hd->dev, - "%s: synchronous operation id 0x%04x of type 0x%02x failed: %d\n", - connection->name, operation->id, type, ret); - } else { - if (response_size) { - memcpy(response, operation->response->payload, - response_size); - } - } - - gb_operation_put(operation); - - return ret; -} -EXPORT_SYMBOL_GPL(gb_operation_sync_timeout); - -/** - * gb_operation_unidirectional_timeout() - initiate a unidirectional operation - * @connection: connection to use - * @type: type of operation to send - * @request: memory buffer to copy the request from - * @request_size: size of @request - * @timeout: send timeout in milliseconds - * - * Initiate a unidirectional operation by sending a request message and - * waiting for it to be acknowledged as sent by the host device. - * - * Note that successful send of a unidirectional operation does not imply that - * the request as actually reached the remote end of the connection. - */ -int gb_operation_unidirectional_timeout(struct gb_connection *connection, - int type, void *request, - int request_size, - unsigned int timeout) -{ - struct gb_operation *operation; - int ret; - - if (request_size && !request) - return -EINVAL; - - operation = gb_operation_create_flags(connection, type, - request_size, 0, - GB_OPERATION_FLAG_UNIDIRECTIONAL, - GFP_KERNEL); - if (!operation) - return -ENOMEM; - - if (request_size) - memcpy(operation->request->payload, request, request_size); - - ret = gb_operation_request_send_sync_timeout(operation, timeout); - if (ret) { - dev_err(&connection->hd->dev, - "%s: unidirectional operation of type 0x%02x failed: %d\n", - connection->name, type, ret); - } - - gb_operation_put(operation); - - return ret; -} -EXPORT_SYMBOL_GPL(gb_operation_unidirectional_timeout); - -int __init gb_operation_init(void) -{ - gb_message_cache = kmem_cache_create("gb_message_cache", - sizeof(struct gb_message), 0, 0, - NULL); - if (!gb_message_cache) - return -ENOMEM; - - gb_operation_cache = kmem_cache_create("gb_operation_cache", - sizeof(struct gb_operation), 0, - 0, NULL); - if (!gb_operation_cache) - goto err_destroy_message_cache; - - gb_operation_completion_wq = alloc_workqueue("greybus_completion", - 0, 0); - if (!gb_operation_completion_wq) - goto err_destroy_operation_cache; - - return 0; - -err_destroy_operation_cache: - kmem_cache_destroy(gb_operation_cache); - gb_operation_cache = NULL; -err_destroy_message_cache: - kmem_cache_destroy(gb_message_cache); - gb_message_cache = NULL; - - return -ENOMEM; -} - -void gb_operation_exit(void) -{ - destroy_workqueue(gb_operation_completion_wq); - gb_operation_completion_wq = NULL; - kmem_cache_destroy(gb_operation_cache); - gb_operation_cache = NULL; - kmem_cache_destroy(gb_message_cache); - gb_message_cache = NULL; -} diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h deleted file mode 100644 index 40b7b02fff88..000000000000 --- a/drivers/staging/greybus/operation.h +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus operations - * - * Copyright 2014 Google Inc. - * Copyright 2014 Linaro Ltd. - */ - -#ifndef __OPERATION_H -#define __OPERATION_H - -#include <linux/completion.h> - -struct gb_operation; - -/* The default amount of time a request is given to complete */ -#define GB_OPERATION_TIMEOUT_DEFAULT 1000 /* milliseconds */ - -/* - * The top bit of the type in an operation message header indicates - * whether the message is a request (bit clear) or response (bit set) - */ -#define GB_MESSAGE_TYPE_RESPONSE ((u8)0x80) - -enum gb_operation_result { - GB_OP_SUCCESS = 0x00, - GB_OP_INTERRUPTED = 0x01, - GB_OP_TIMEOUT = 0x02, - GB_OP_NO_MEMORY = 0x03, - GB_OP_PROTOCOL_BAD = 0x04, - GB_OP_OVERFLOW = 0x05, - GB_OP_INVALID = 0x06, - GB_OP_RETRY = 0x07, - GB_OP_NONEXISTENT = 0x08, - GB_OP_UNKNOWN_ERROR = 0xfe, - GB_OP_MALFUNCTION = 0xff, -}; - -#define GB_OPERATION_MESSAGE_SIZE_MIN sizeof(struct gb_operation_msg_hdr) -#define GB_OPERATION_MESSAGE_SIZE_MAX U16_MAX - -/* - * Protocol code should only examine the payload and payload_size fields, and - * host-controller drivers may use the hcpriv field. All other fields are - * intended to be private to the operations core code. - */ -struct gb_message { - struct gb_operation *operation; - struct gb_operation_msg_hdr *header; - - void *payload; - size_t payload_size; - - void *buffer; - - void *hcpriv; -}; - -#define GB_OPERATION_FLAG_INCOMING BIT(0) -#define GB_OPERATION_FLAG_UNIDIRECTIONAL BIT(1) -#define GB_OPERATION_FLAG_SHORT_RESPONSE BIT(2) -#define GB_OPERATION_FLAG_CORE BIT(3) - -#define GB_OPERATION_FLAG_USER_MASK (GB_OPERATION_FLAG_SHORT_RESPONSE | \ - GB_OPERATION_FLAG_UNIDIRECTIONAL) - -/* - * A Greybus operation is a remote procedure call performed over a - * connection between two UniPro interfaces. - * - * Every operation consists of a request message sent to the other - * end of the connection coupled with a reply message returned to - * the sender. Every operation has a type, whose interpretation is - * dependent on the protocol associated with the connection. - * - * Only four things in an operation structure are intended to be - * directly usable by protocol handlers: the operation's connection - * pointer; the operation type; the request message payload (and - * size); and the response message payload (and size). Note that a - * message with a 0-byte payload has a null message payload pointer. - * - * In addition, every operation has a result, which is an errno - * value. Protocol handlers access the operation result using - * gb_operation_result(). - */ -typedef void (*gb_operation_callback)(struct gb_operation *); -struct gb_operation { - struct gb_connection *connection; - struct gb_message *request; - struct gb_message *response; - - unsigned long flags; - u8 type; - u16 id; - int errno; /* Operation result */ - - struct work_struct work; - gb_operation_callback callback; - struct completion completion; - struct timer_list timer; - - struct kref kref; - atomic_t waiters; - - int active; - struct list_head links; /* connection->operations */ - - void *private; -}; - -static inline bool -gb_operation_is_incoming(struct gb_operation *operation) -{ - return operation->flags & GB_OPERATION_FLAG_INCOMING; -} - -static inline bool -gb_operation_is_unidirectional(struct gb_operation *operation) -{ - return operation->flags & GB_OPERATION_FLAG_UNIDIRECTIONAL; -} - -static inline bool -gb_operation_short_response_allowed(struct gb_operation *operation) -{ - return operation->flags & GB_OPERATION_FLAG_SHORT_RESPONSE; -} - -static inline bool gb_operation_is_core(struct gb_operation *operation) -{ - return operation->flags & GB_OPERATION_FLAG_CORE; -} - -void gb_connection_recv(struct gb_connection *connection, - void *data, size_t size); - -int gb_operation_result(struct gb_operation *operation); - -size_t gb_operation_get_payload_size_max(struct gb_connection *connection); -struct gb_operation * -gb_operation_create_flags(struct gb_connection *connection, - u8 type, size_t request_size, - size_t response_size, unsigned long flags, - gfp_t gfp); - -static inline struct gb_operation * -gb_operation_create(struct gb_connection *connection, - u8 type, size_t request_size, - size_t response_size, gfp_t gfp) -{ - return gb_operation_create_flags(connection, type, request_size, - response_size, 0, gfp); -} - -struct gb_operation * -gb_operation_create_core(struct gb_connection *connection, - u8 type, size_t request_size, - size_t response_size, unsigned long flags, - gfp_t gfp); - -void gb_operation_get(struct gb_operation *operation); -void gb_operation_put(struct gb_operation *operation); - -bool gb_operation_response_alloc(struct gb_operation *operation, - size_t response_size, gfp_t gfp); - -int gb_operation_request_send(struct gb_operation *operation, - gb_operation_callback callback, - unsigned int timeout, - gfp_t gfp); -int gb_operation_request_send_sync_timeout(struct gb_operation *operation, - unsigned int timeout); -static inline int -gb_operation_request_send_sync(struct gb_operation *operation) -{ - return gb_operation_request_send_sync_timeout(operation, - GB_OPERATION_TIMEOUT_DEFAULT); -} - -void gb_operation_cancel(struct gb_operation *operation, int errno); -void gb_operation_cancel_incoming(struct gb_operation *operation, int errno); - -void greybus_message_sent(struct gb_host_device *hd, - struct gb_message *message, int status); - -int gb_operation_sync_timeout(struct gb_connection *connection, int type, - void *request, int request_size, - void *response, int response_size, - unsigned int timeout); -int gb_operation_unidirectional_timeout(struct gb_connection *connection, - int type, void *request, int request_size, - unsigned int timeout); - -static inline int gb_operation_sync(struct gb_connection *connection, int type, - void *request, int request_size, - void *response, int response_size) -{ - return gb_operation_sync_timeout(connection, type, - request, request_size, response, response_size, - GB_OPERATION_TIMEOUT_DEFAULT); -} - -static inline int gb_operation_unidirectional(struct gb_connection *connection, - int type, void *request, int request_size) -{ - return gb_operation_unidirectional_timeout(connection, type, - request, request_size, GB_OPERATION_TIMEOUT_DEFAULT); -} - -static inline void *gb_operation_get_data(struct gb_operation *operation) -{ - return operation->private; -} - -static inline void gb_operation_set_data(struct gb_operation *operation, - void *data) -{ - operation->private = data; -} - -int gb_operation_init(void); -void gb_operation_exit(void); - -#endif /* !__OPERATION_H */ diff --git a/drivers/staging/greybus/power_supply.c b/drivers/staging/greybus/power_supply.c index 34b40a409ea3..ec96f28887f9 100644 --- a/drivers/staging/greybus/power_supply.c +++ b/drivers/staging/greybus/power_supply.c @@ -10,8 +10,7 @@ #include <linux/module.h> #include <linux/power_supply.h> #include <linux/slab.h> - -#include "greybus.h" +#include <linux/greybus.h> #define PROP_MAX 32 diff --git a/drivers/staging/greybus/pwm.c b/drivers/staging/greybus/pwm.c index 4a6d394b6c44..891a6a672378 100644 --- a/drivers/staging/greybus/pwm.c +++ b/drivers/staging/greybus/pwm.c @@ -10,8 +10,8 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/pwm.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" struct gb_pwm_chip { diff --git a/drivers/staging/greybus/raw.c b/drivers/staging/greybus/raw.c index 838acbe84ca0..64a17dfe3b6e 100644 --- a/drivers/staging/greybus/raw.c +++ b/drivers/staging/greybus/raw.c @@ -13,8 +13,7 @@ #include <linux/fs.h> #include <linux/idr.h> #include <linux/uaccess.h> - -#include "greybus.h" +#include <linux/greybus.h> struct gb_raw { struct gb_connection *connection; diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c index a097a8916b3b..68c5718be827 100644 --- a/drivers/staging/greybus/sdio.c +++ b/drivers/staging/greybus/sdio.c @@ -12,8 +12,8 @@ #include <linux/mmc/mmc.h> #include <linux/scatterlist.h> #include <linux/workqueue.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" struct gb_sdio_host { diff --git a/drivers/staging/greybus/spi.c b/drivers/staging/greybus/spi.c index 47d896992b35..68e8d272db6d 100644 --- a/drivers/staging/greybus/spi.c +++ b/drivers/staging/greybus/spi.c @@ -7,8 +7,8 @@ */ #include <linux/module.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" #include "spilib.h" diff --git a/drivers/staging/greybus/spilib.c b/drivers/staging/greybus/spilib.c index 2e07c6b41334..fc27c52de74a 100644 --- a/drivers/staging/greybus/spilib.c +++ b/drivers/staging/greybus/spilib.c @@ -10,9 +10,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/greybus.h> #include <linux/spi/spi.h> -#include "greybus.h" #include "spilib.h" struct gb_spilib { diff --git a/drivers/staging/greybus/spilib.h b/drivers/staging/greybus/spilib.h index 043d4d32c3ee..9d416839e3be 100644 --- a/drivers/staging/greybus/spilib.h +++ b/drivers/staging/greybus/spilib.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Greybus SPI library header * diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c deleted file mode 100644 index 05bc45287b87..000000000000 --- a/drivers/staging/greybus/svc.c +++ /dev/null @@ -1,1398 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * SVC Greybus driver. - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - */ - -#include <linux/debugfs.h> -#include <linux/workqueue.h> - -#include "greybus.h" - -#define SVC_INTF_EJECT_TIMEOUT 9000 -#define SVC_INTF_ACTIVATE_TIMEOUT 6000 -#define SVC_INTF_RESUME_TIMEOUT 3000 - -struct gb_svc_deferred_request { - struct work_struct work; - struct gb_operation *operation; -}; - -static int gb_svc_queue_deferred_request(struct gb_operation *operation); - -static ssize_t endo_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_svc *svc = to_gb_svc(dev); - - return sprintf(buf, "0x%04x\n", svc->endo_id); -} -static DEVICE_ATTR_RO(endo_id); - -static ssize_t ap_intf_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_svc *svc = to_gb_svc(dev); - - return sprintf(buf, "%u\n", svc->ap_intf_id); -} -static DEVICE_ATTR_RO(ap_intf_id); - -// FIXME -// This is a hack, we need to do this "right" and clean the interface up -// properly, not just forcibly yank the thing out of the system and hope for the -// best. But for now, people want their modules to come out without having to -// throw the thing to the ground or get out a screwdriver. -static ssize_t intf_eject_store(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t len) -{ - struct gb_svc *svc = to_gb_svc(dev); - unsigned short intf_id; - int ret; - - ret = kstrtou16(buf, 10, &intf_id); - if (ret < 0) - return ret; - - dev_warn(dev, "Forcibly trying to eject interface %d\n", intf_id); - - ret = gb_svc_intf_eject(svc, intf_id); - if (ret < 0) - return ret; - - return len; -} -static DEVICE_ATTR_WO(intf_eject); - -static ssize_t watchdog_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct gb_svc *svc = to_gb_svc(dev); - - return sprintf(buf, "%s\n", - gb_svc_watchdog_enabled(svc) ? "enabled" : "disabled"); -} - -static ssize_t watchdog_store(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t len) -{ - struct gb_svc *svc = to_gb_svc(dev); - int retval; - bool user_request; - - retval = strtobool(buf, &user_request); - if (retval) - return retval; - - if (user_request) - retval = gb_svc_watchdog_enable(svc); - else - retval = gb_svc_watchdog_disable(svc); - if (retval) - return retval; - return len; -} -static DEVICE_ATTR_RW(watchdog); - -static ssize_t watchdog_action_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gb_svc *svc = to_gb_svc(dev); - - if (svc->action == GB_SVC_WATCHDOG_BITE_PANIC_KERNEL) - return sprintf(buf, "panic\n"); - else if (svc->action == GB_SVC_WATCHDOG_BITE_RESET_UNIPRO) - return sprintf(buf, "reset\n"); - - return -EINVAL; -} - -static ssize_t watchdog_action_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct gb_svc *svc = to_gb_svc(dev); - - if (sysfs_streq(buf, "panic")) - svc->action = GB_SVC_WATCHDOG_BITE_PANIC_KERNEL; - else if (sysfs_streq(buf, "reset")) - svc->action = GB_SVC_WATCHDOG_BITE_RESET_UNIPRO; - else - return -EINVAL; - - return len; -} -static DEVICE_ATTR_RW(watchdog_action); - -static int gb_svc_pwrmon_rail_count_get(struct gb_svc *svc, u8 *value) -{ - struct gb_svc_pwrmon_rail_count_get_response response; - int ret; - - ret = gb_operation_sync(svc->connection, - GB_SVC_TYPE_PWRMON_RAIL_COUNT_GET, NULL, 0, - &response, sizeof(response)); - if (ret) { - dev_err(&svc->dev, "failed to get rail count: %d\n", ret); - return ret; - } - - *value = response.rail_count; - - return 0; -} - -static int gb_svc_pwrmon_rail_names_get(struct gb_svc *svc, - struct gb_svc_pwrmon_rail_names_get_response *response, - size_t bufsize) -{ - int ret; - - ret = gb_operation_sync(svc->connection, - GB_SVC_TYPE_PWRMON_RAIL_NAMES_GET, NULL, 0, - response, bufsize); - if (ret) { - dev_err(&svc->dev, "failed to get rail names: %d\n", ret); - return ret; - } - - if (response->status != GB_SVC_OP_SUCCESS) { - dev_err(&svc->dev, - "SVC error while getting rail names: %u\n", - response->status); - return -EREMOTEIO; - } - - return 0; -} - -static int gb_svc_pwrmon_sample_get(struct gb_svc *svc, u8 rail_id, - u8 measurement_type, u32 *value) -{ - struct gb_svc_pwrmon_sample_get_request request; - struct gb_svc_pwrmon_sample_get_response response; - int ret; - - request.rail_id = rail_id; - request.measurement_type = measurement_type; - - ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_PWRMON_SAMPLE_GET, - &request, sizeof(request), - &response, sizeof(response)); - if (ret) { - dev_err(&svc->dev, "failed to get rail sample: %d\n", ret); - return ret; - } - - if (response.result) { - dev_err(&svc->dev, - "UniPro error while getting rail power sample (%d %d): %d\n", - rail_id, measurement_type, response.result); - switch (response.result) { - case GB_SVC_PWRMON_GET_SAMPLE_INVAL: - return -EINVAL; - case GB_SVC_PWRMON_GET_SAMPLE_NOSUPP: - return -ENOMSG; - default: - return -EREMOTEIO; - } - } - - *value = le32_to_cpu(response.measurement); - - return 0; -} - -int gb_svc_pwrmon_intf_sample_get(struct gb_svc *svc, u8 intf_id, - u8 measurement_type, u32 *value) -{ - struct gb_svc_pwrmon_intf_sample_get_request request; - struct gb_svc_pwrmon_intf_sample_get_response response; - int ret; - - request.intf_id = intf_id; - request.measurement_type = measurement_type; - - ret = gb_operation_sync(svc->connection, - GB_SVC_TYPE_PWRMON_INTF_SAMPLE_GET, - &request, sizeof(request), - &response, sizeof(response)); - if (ret) { - dev_err(&svc->dev, "failed to get intf sample: %d\n", ret); - return ret; - } - - if (response.result) { - dev_err(&svc->dev, - "UniPro error while getting intf power sample (%d %d): %d\n", - intf_id, measurement_type, response.result); - switch (response.result) { - case GB_SVC_PWRMON_GET_SAMPLE_INVAL: - return -EINVAL; - case GB_SVC_PWRMON_GET_SAMPLE_NOSUPP: - return -ENOMSG; - default: - return -EREMOTEIO; - } - } - - *value = le32_to_cpu(response.measurement); - - return 0; -} - -static struct attribute *svc_attrs[] = { - &dev_attr_endo_id.attr, - &dev_attr_ap_intf_id.attr, - &dev_attr_intf_eject.attr, - &dev_attr_watchdog.attr, - &dev_attr_watchdog_action.attr, - NULL, -}; -ATTRIBUTE_GROUPS(svc); - -int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id) -{ - struct gb_svc_intf_device_id_request request; - - request.intf_id = intf_id; - request.device_id = device_id; - - return gb_operation_sync(svc->connection, GB_SVC_TYPE_INTF_DEVICE_ID, - &request, sizeof(request), NULL, 0); -} - -int gb_svc_intf_eject(struct gb_svc *svc, u8 intf_id) -{ - struct gb_svc_intf_eject_request request; - int ret; - - request.intf_id = intf_id; - - /* - * The pulse width for module release in svc is long so we need to - * increase the timeout so the operation will not return to soon. - */ - ret = gb_operation_sync_timeout(svc->connection, - GB_SVC_TYPE_INTF_EJECT, &request, - sizeof(request), NULL, 0, - SVC_INTF_EJECT_TIMEOUT); - if (ret) { - dev_err(&svc->dev, "failed to eject interface %u\n", intf_id); - return ret; - } - - return 0; -} - -int gb_svc_intf_vsys_set(struct gb_svc *svc, u8 intf_id, bool enable) -{ - struct gb_svc_intf_vsys_request request; - struct gb_svc_intf_vsys_response response; - int type, ret; - - request.intf_id = intf_id; - - if (enable) - type = GB_SVC_TYPE_INTF_VSYS_ENABLE; - else - type = GB_SVC_TYPE_INTF_VSYS_DISABLE; - - ret = gb_operation_sync(svc->connection, type, - &request, sizeof(request), - &response, sizeof(response)); - if (ret < 0) - return ret; - if (response.result_code != GB_SVC_INTF_VSYS_OK) - return -EREMOTEIO; - return 0; -} - -int gb_svc_intf_refclk_set(struct gb_svc *svc, u8 intf_id, bool enable) -{ - struct gb_svc_intf_refclk_request request; - struct gb_svc_intf_refclk_response response; - int type, ret; - - request.intf_id = intf_id; - - if (enable) - type = GB_SVC_TYPE_INTF_REFCLK_ENABLE; - else - type = GB_SVC_TYPE_INTF_REFCLK_DISABLE; - - ret = gb_operation_sync(svc->connection, type, - &request, sizeof(request), - &response, sizeof(response)); - if (ret < 0) - return ret; - if (response.result_code != GB_SVC_INTF_REFCLK_OK) - return -EREMOTEIO; - return 0; -} - -int gb_svc_intf_unipro_set(struct gb_svc *svc, u8 intf_id, bool enable) -{ - struct gb_svc_intf_unipro_request request; - struct gb_svc_intf_unipro_response response; - int type, ret; - - request.intf_id = intf_id; - - if (enable) - type = GB_SVC_TYPE_INTF_UNIPRO_ENABLE; - else - type = GB_SVC_TYPE_INTF_UNIPRO_DISABLE; - - ret = gb_operation_sync(svc->connection, type, - &request, sizeof(request), - &response, sizeof(response)); - if (ret < 0) - return ret; - if (response.result_code != GB_SVC_INTF_UNIPRO_OK) - return -EREMOTEIO; - return 0; -} - -int gb_svc_intf_activate(struct gb_svc *svc, u8 intf_id, u8 *intf_type) -{ - struct gb_svc_intf_activate_request request; - struct gb_svc_intf_activate_response response; - int ret; - - request.intf_id = intf_id; - - ret = gb_operation_sync_timeout(svc->connection, - GB_SVC_TYPE_INTF_ACTIVATE, - &request, sizeof(request), - &response, sizeof(response), - SVC_INTF_ACTIVATE_TIMEOUT); - if (ret < 0) - return ret; - if (response.status != GB_SVC_OP_SUCCESS) { - dev_err(&svc->dev, "failed to activate interface %u: %u\n", - intf_id, response.status); - return -EREMOTEIO; - } - - *intf_type = response.intf_type; - - return 0; -} - -int gb_svc_intf_resume(struct gb_svc *svc, u8 intf_id) -{ - struct gb_svc_intf_resume_request request; - struct gb_svc_intf_resume_response response; - int ret; - - request.intf_id = intf_id; - - ret = gb_operation_sync_timeout(svc->connection, - GB_SVC_TYPE_INTF_RESUME, - &request, sizeof(request), - &response, sizeof(response), - SVC_INTF_RESUME_TIMEOUT); - if (ret < 0) { - dev_err(&svc->dev, "failed to send interface resume %u: %d\n", - intf_id, ret); - return ret; - } - - if (response.status != GB_SVC_OP_SUCCESS) { - dev_err(&svc->dev, "failed to resume interface %u: %u\n", - intf_id, response.status); - return -EREMOTEIO; - } - - return 0; -} - -int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector, - u32 *value) -{ - struct gb_svc_dme_peer_get_request request; - struct gb_svc_dme_peer_get_response response; - u16 result; - int ret; - - request.intf_id = intf_id; - request.attr = cpu_to_le16(attr); - request.selector = cpu_to_le16(selector); - - ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_DME_PEER_GET, - &request, sizeof(request), - &response, sizeof(response)); - if (ret) { - dev_err(&svc->dev, "failed to get DME attribute (%u 0x%04x %u): %d\n", - intf_id, attr, selector, ret); - return ret; - } - - result = le16_to_cpu(response.result_code); - if (result) { - dev_err(&svc->dev, "UniPro error while getting DME attribute (%u 0x%04x %u): %u\n", - intf_id, attr, selector, result); - return -EREMOTEIO; - } - - if (value) - *value = le32_to_cpu(response.attr_value); - - return 0; -} - -int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector, - u32 value) -{ - struct gb_svc_dme_peer_set_request request; - struct gb_svc_dme_peer_set_response response; - u16 result; - int ret; - - request.intf_id = intf_id; - request.attr = cpu_to_le16(attr); - request.selector = cpu_to_le16(selector); - request.value = cpu_to_le32(value); - - ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_DME_PEER_SET, - &request, sizeof(request), - &response, sizeof(response)); - if (ret) { - dev_err(&svc->dev, "failed to set DME attribute (%u 0x%04x %u %u): %d\n", - intf_id, attr, selector, value, ret); - return ret; - } - - result = le16_to_cpu(response.result_code); - if (result) { - dev_err(&svc->dev, "UniPro error while setting DME attribute (%u 0x%04x %u %u): %u\n", - intf_id, attr, selector, value, result); - return -EREMOTEIO; - } - - return 0; -} - -int gb_svc_connection_create(struct gb_svc *svc, - u8 intf1_id, u16 cport1_id, - u8 intf2_id, u16 cport2_id, - u8 cport_flags) -{ - struct gb_svc_conn_create_request request; - - request.intf1_id = intf1_id; - request.cport1_id = cpu_to_le16(cport1_id); - request.intf2_id = intf2_id; - request.cport2_id = cpu_to_le16(cport2_id); - request.tc = 0; /* TC0 */ - request.flags = cport_flags; - - return gb_operation_sync(svc->connection, GB_SVC_TYPE_CONN_CREATE, - &request, sizeof(request), NULL, 0); -} - -void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id, - u8 intf2_id, u16 cport2_id) -{ - struct gb_svc_conn_destroy_request request; - struct gb_connection *connection = svc->connection; - int ret; - - request.intf1_id = intf1_id; - request.cport1_id = cpu_to_le16(cport1_id); - request.intf2_id = intf2_id; - request.cport2_id = cpu_to_le16(cport2_id); - - ret = gb_operation_sync(connection, GB_SVC_TYPE_CONN_DESTROY, - &request, sizeof(request), NULL, 0); - if (ret) { - dev_err(&svc->dev, "failed to destroy connection (%u:%u %u:%u): %d\n", - intf1_id, cport1_id, intf2_id, cport2_id, ret); - } -} - -/* Creates bi-directional routes between the devices */ -int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id, - u8 intf2_id, u8 dev2_id) -{ - struct gb_svc_route_create_request request; - - request.intf1_id = intf1_id; - request.dev1_id = dev1_id; - request.intf2_id = intf2_id; - request.dev2_id = dev2_id; - - return gb_operation_sync(svc->connection, GB_SVC_TYPE_ROUTE_CREATE, - &request, sizeof(request), NULL, 0); -} - -/* Destroys bi-directional routes between the devices */ -void gb_svc_route_destroy(struct gb_svc *svc, u8 intf1_id, u8 intf2_id) -{ - struct gb_svc_route_destroy_request request; - int ret; - - request.intf1_id = intf1_id; - request.intf2_id = intf2_id; - - ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_ROUTE_DESTROY, - &request, sizeof(request), NULL, 0); - if (ret) { - dev_err(&svc->dev, "failed to destroy route (%u %u): %d\n", - intf1_id, intf2_id, ret); - } -} - -int gb_svc_intf_set_power_mode(struct gb_svc *svc, u8 intf_id, u8 hs_series, - u8 tx_mode, u8 tx_gear, u8 tx_nlanes, - u8 tx_amplitude, u8 tx_hs_equalizer, - u8 rx_mode, u8 rx_gear, u8 rx_nlanes, - u8 flags, u32 quirks, - struct gb_svc_l2_timer_cfg *local, - struct gb_svc_l2_timer_cfg *remote) -{ - struct gb_svc_intf_set_pwrm_request request; - struct gb_svc_intf_set_pwrm_response response; - int ret; - u16 result_code; - - memset(&request, 0, sizeof(request)); - - request.intf_id = intf_id; - request.hs_series = hs_series; - request.tx_mode = tx_mode; - request.tx_gear = tx_gear; - request.tx_nlanes = tx_nlanes; - request.tx_amplitude = tx_amplitude; - request.tx_hs_equalizer = tx_hs_equalizer; - request.rx_mode = rx_mode; - request.rx_gear = rx_gear; - request.rx_nlanes = rx_nlanes; - request.flags = flags; - request.quirks = cpu_to_le32(quirks); - if (local) - request.local_l2timerdata = *local; - if (remote) - request.remote_l2timerdata = *remote; - - ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_INTF_SET_PWRM, - &request, sizeof(request), - &response, sizeof(response)); - if (ret < 0) - return ret; - - result_code = response.result_code; - if (result_code != GB_SVC_SETPWRM_PWR_LOCAL) { - dev_err(&svc->dev, "set power mode = %d\n", result_code); - return -EIO; - } - - return 0; -} -EXPORT_SYMBOL_GPL(gb_svc_intf_set_power_mode); - -int gb_svc_intf_set_power_mode_hibernate(struct gb_svc *svc, u8 intf_id) -{ - struct gb_svc_intf_set_pwrm_request request; - struct gb_svc_intf_set_pwrm_response response; - int ret; - u16 result_code; - - memset(&request, 0, sizeof(request)); - - request.intf_id = intf_id; - request.hs_series = GB_SVC_UNIPRO_HS_SERIES_A; - request.tx_mode = GB_SVC_UNIPRO_HIBERNATE_MODE; - request.rx_mode = GB_SVC_UNIPRO_HIBERNATE_MODE; - - ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_INTF_SET_PWRM, - &request, sizeof(request), - &response, sizeof(response)); - if (ret < 0) { - dev_err(&svc->dev, - "failed to send set power mode operation to interface %u: %d\n", - intf_id, ret); - return ret; - } - - result_code = response.result_code; - if (result_code != GB_SVC_SETPWRM_PWR_OK) { - dev_err(&svc->dev, - "failed to hibernate the link for interface %u: %u\n", - intf_id, result_code); - return -EIO; - } - - return 0; -} - -int gb_svc_ping(struct gb_svc *svc) -{ - return gb_operation_sync_timeout(svc->connection, GB_SVC_TYPE_PING, - NULL, 0, NULL, 0, - GB_OPERATION_TIMEOUT_DEFAULT * 2); -} - -static int gb_svc_version_request(struct gb_operation *op) -{ - struct gb_connection *connection = op->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - struct gb_svc_version_request *request; - struct gb_svc_version_response *response; - - if (op->request->payload_size < sizeof(*request)) { - dev_err(&svc->dev, "short version request (%zu < %zu)\n", - op->request->payload_size, - sizeof(*request)); - return -EINVAL; - } - - request = op->request->payload; - - if (request->major > GB_SVC_VERSION_MAJOR) { - dev_warn(&svc->dev, "unsupported major version (%u > %u)\n", - request->major, GB_SVC_VERSION_MAJOR); - return -ENOTSUPP; - } - - svc->protocol_major = request->major; - svc->protocol_minor = request->minor; - - if (!gb_operation_response_alloc(op, sizeof(*response), GFP_KERNEL)) - return -ENOMEM; - - response = op->response->payload; - response->major = svc->protocol_major; - response->minor = svc->protocol_minor; - - return 0; -} - -static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - struct svc_debugfs_pwrmon_rail *pwrmon_rails = - file_inode(file)->i_private; - struct gb_svc *svc = pwrmon_rails->svc; - int ret, desc; - u32 value; - char buff[16]; - - ret = gb_svc_pwrmon_sample_get(svc, pwrmon_rails->id, - GB_SVC_PWRMON_TYPE_VOL, &value); - if (ret) { - dev_err(&svc->dev, - "failed to get voltage sample %u: %d\n", - pwrmon_rails->id, ret); - return ret; - } - - desc = scnprintf(buff, sizeof(buff), "%u\n", value); - - return simple_read_from_buffer(buf, len, offset, buff, desc); -} - -static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - struct svc_debugfs_pwrmon_rail *pwrmon_rails = - file_inode(file)->i_private; - struct gb_svc *svc = pwrmon_rails->svc; - int ret, desc; - u32 value; - char buff[16]; - - ret = gb_svc_pwrmon_sample_get(svc, pwrmon_rails->id, - GB_SVC_PWRMON_TYPE_CURR, &value); - if (ret) { - dev_err(&svc->dev, - "failed to get current sample %u: %d\n", - pwrmon_rails->id, ret); - return ret; - } - - desc = scnprintf(buff, sizeof(buff), "%u\n", value); - - return simple_read_from_buffer(buf, len, offset, buff, desc); -} - -static ssize_t pwr_debugfs_power_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - struct svc_debugfs_pwrmon_rail *pwrmon_rails = - file_inode(file)->i_private; - struct gb_svc *svc = pwrmon_rails->svc; - int ret, desc; - u32 value; - char buff[16]; - - ret = gb_svc_pwrmon_sample_get(svc, pwrmon_rails->id, - GB_SVC_PWRMON_TYPE_PWR, &value); - if (ret) { - dev_err(&svc->dev, "failed to get power sample %u: %d\n", - pwrmon_rails->id, ret); - return ret; - } - - desc = scnprintf(buff, sizeof(buff), "%u\n", value); - - return simple_read_from_buffer(buf, len, offset, buff, desc); -} - -static const struct file_operations pwrmon_debugfs_voltage_fops = { - .read = pwr_debugfs_voltage_read, -}; - -static const struct file_operations pwrmon_debugfs_current_fops = { - .read = pwr_debugfs_current_read, -}; - -static const struct file_operations pwrmon_debugfs_power_fops = { - .read = pwr_debugfs_power_read, -}; - -static void gb_svc_pwrmon_debugfs_init(struct gb_svc *svc) -{ - int i; - size_t bufsize; - struct dentry *dent; - struct gb_svc_pwrmon_rail_names_get_response *rail_names; - u8 rail_count; - - dent = debugfs_create_dir("pwrmon", svc->debugfs_dentry); - if (IS_ERR_OR_NULL(dent)) - return; - - if (gb_svc_pwrmon_rail_count_get(svc, &rail_count)) - goto err_pwrmon_debugfs; - - if (!rail_count || rail_count > GB_SVC_PWRMON_MAX_RAIL_COUNT) - goto err_pwrmon_debugfs; - - bufsize = sizeof(*rail_names) + - GB_SVC_PWRMON_RAIL_NAME_BUFSIZE * rail_count; - - rail_names = kzalloc(bufsize, GFP_KERNEL); - if (!rail_names) - goto err_pwrmon_debugfs; - - svc->pwrmon_rails = kcalloc(rail_count, sizeof(*svc->pwrmon_rails), - GFP_KERNEL); - if (!svc->pwrmon_rails) - goto err_pwrmon_debugfs_free; - - if (gb_svc_pwrmon_rail_names_get(svc, rail_names, bufsize)) - goto err_pwrmon_debugfs_free; - - for (i = 0; i < rail_count; i++) { - struct dentry *dir; - struct svc_debugfs_pwrmon_rail *rail = &svc->pwrmon_rails[i]; - char fname[GB_SVC_PWRMON_RAIL_NAME_BUFSIZE]; - - snprintf(fname, sizeof(fname), "%s", - (char *)&rail_names->name[i]); - - rail->id = i; - rail->svc = svc; - - dir = debugfs_create_dir(fname, dent); - debugfs_create_file("voltage_now", 0444, dir, rail, - &pwrmon_debugfs_voltage_fops); - debugfs_create_file("current_now", 0444, dir, rail, - &pwrmon_debugfs_current_fops); - debugfs_create_file("power_now", 0444, dir, rail, - &pwrmon_debugfs_power_fops); - } - - kfree(rail_names); - return; - -err_pwrmon_debugfs_free: - kfree(rail_names); - kfree(svc->pwrmon_rails); - svc->pwrmon_rails = NULL; - -err_pwrmon_debugfs: - debugfs_remove(dent); -} - -static void gb_svc_debugfs_init(struct gb_svc *svc) -{ - svc->debugfs_dentry = debugfs_create_dir(dev_name(&svc->dev), - gb_debugfs_get()); - gb_svc_pwrmon_debugfs_init(svc); -} - -static void gb_svc_debugfs_exit(struct gb_svc *svc) -{ - debugfs_remove_recursive(svc->debugfs_dentry); - kfree(svc->pwrmon_rails); - svc->pwrmon_rails = NULL; -} - -static int gb_svc_hello(struct gb_operation *op) -{ - struct gb_connection *connection = op->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - struct gb_svc_hello_request *hello_request; - int ret; - - if (op->request->payload_size < sizeof(*hello_request)) { - dev_warn(&svc->dev, "short hello request (%zu < %zu)\n", - op->request->payload_size, - sizeof(*hello_request)); - return -EINVAL; - } - - hello_request = op->request->payload; - svc->endo_id = le16_to_cpu(hello_request->endo_id); - svc->ap_intf_id = hello_request->interface_id; - - ret = device_add(&svc->dev); - if (ret) { - dev_err(&svc->dev, "failed to register svc device: %d\n", ret); - return ret; - } - - ret = gb_svc_watchdog_create(svc); - if (ret) { - dev_err(&svc->dev, "failed to create watchdog: %d\n", ret); - goto err_unregister_device; - } - - gb_svc_debugfs_init(svc); - - return gb_svc_queue_deferred_request(op); - -err_unregister_device: - gb_svc_watchdog_destroy(svc); - device_del(&svc->dev); - return ret; -} - -static struct gb_interface *gb_svc_interface_lookup(struct gb_svc *svc, - u8 intf_id) -{ - struct gb_host_device *hd = svc->hd; - struct gb_module *module; - size_t num_interfaces; - u8 module_id; - - list_for_each_entry(module, &hd->modules, hd_node) { - module_id = module->module_id; - num_interfaces = module->num_interfaces; - - if (intf_id >= module_id && - intf_id < module_id + num_interfaces) { - return module->interfaces[intf_id - module_id]; - } - } - - return NULL; -} - -static struct gb_module *gb_svc_module_lookup(struct gb_svc *svc, u8 module_id) -{ - struct gb_host_device *hd = svc->hd; - struct gb_module *module; - - list_for_each_entry(module, &hd->modules, hd_node) { - if (module->module_id == module_id) - return module; - } - - return NULL; -} - -static void gb_svc_process_hello_deferred(struct gb_operation *operation) -{ - struct gb_connection *connection = operation->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - int ret; - - /* - * XXX This is a hack/work-around to reconfigure the APBridgeA-Switch - * link to PWM G2, 1 Lane, Slow Auto, so that it has sufficient - * bandwidth for 3 audio streams plus boot-over-UniPro of a hot-plugged - * module. - * - * The code should be removed once SW-2217, Heuristic for UniPro - * Power Mode Changes is resolved. - */ - ret = gb_svc_intf_set_power_mode(svc, svc->ap_intf_id, - GB_SVC_UNIPRO_HS_SERIES_A, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - GB_SVC_SMALL_AMPLITUDE, - GB_SVC_NO_DE_EMPHASIS, - GB_SVC_UNIPRO_SLOW_AUTO_MODE, - 2, 1, - 0, 0, - NULL, NULL); - - if (ret) - dev_warn(&svc->dev, - "power mode change failed on AP to switch link: %d\n", - ret); -} - -static void gb_svc_process_module_inserted(struct gb_operation *operation) -{ - struct gb_svc_module_inserted_request *request; - struct gb_connection *connection = operation->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - struct gb_host_device *hd = svc->hd; - struct gb_module *module; - size_t num_interfaces; - u8 module_id; - u16 flags; - int ret; - - /* The request message size has already been verified. */ - request = operation->request->payload; - module_id = request->primary_intf_id; - num_interfaces = request->intf_count; - flags = le16_to_cpu(request->flags); - - dev_dbg(&svc->dev, "%s - id = %u, num_interfaces = %zu, flags = 0x%04x\n", - __func__, module_id, num_interfaces, flags); - - if (flags & GB_SVC_MODULE_INSERTED_FLAG_NO_PRIMARY) { - dev_warn(&svc->dev, "no primary interface detected on module %u\n", - module_id); - } - - module = gb_svc_module_lookup(svc, module_id); - if (module) { - dev_warn(&svc->dev, "unexpected module-inserted event %u\n", - module_id); - return; - } - - module = gb_module_create(hd, module_id, num_interfaces); - if (!module) { - dev_err(&svc->dev, "failed to create module\n"); - return; - } - - ret = gb_module_add(module); - if (ret) { - gb_module_put(module); - return; - } - - list_add(&module->hd_node, &hd->modules); -} - -static void gb_svc_process_module_removed(struct gb_operation *operation) -{ - struct gb_svc_module_removed_request *request; - struct gb_connection *connection = operation->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - struct gb_module *module; - u8 module_id; - - /* The request message size has already been verified. */ - request = operation->request->payload; - module_id = request->primary_intf_id; - - dev_dbg(&svc->dev, "%s - id = %u\n", __func__, module_id); - - module = gb_svc_module_lookup(svc, module_id); - if (!module) { - dev_warn(&svc->dev, "unexpected module-removed event %u\n", - module_id); - return; - } - - module->disconnected = true; - - gb_module_del(module); - list_del(&module->hd_node); - gb_module_put(module); -} - -static void gb_svc_process_intf_oops(struct gb_operation *operation) -{ - struct gb_svc_intf_oops_request *request; - struct gb_connection *connection = operation->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - struct gb_interface *intf; - u8 intf_id; - u8 reason; - - /* The request message size has already been verified. */ - request = operation->request->payload; - intf_id = request->intf_id; - reason = request->reason; - - intf = gb_svc_interface_lookup(svc, intf_id); - if (!intf) { - dev_warn(&svc->dev, "unexpected interface-oops event %u\n", - intf_id); - return; - } - - dev_info(&svc->dev, "Deactivating interface %u, interface oops reason = %u\n", - intf_id, reason); - - mutex_lock(&intf->mutex); - intf->disconnected = true; - gb_interface_disable(intf); - gb_interface_deactivate(intf); - mutex_unlock(&intf->mutex); -} - -static void gb_svc_process_intf_mailbox_event(struct gb_operation *operation) -{ - struct gb_svc_intf_mailbox_event_request *request; - struct gb_connection *connection = operation->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - struct gb_interface *intf; - u8 intf_id; - u16 result_code; - u32 mailbox; - - /* The request message size has already been verified. */ - request = operation->request->payload; - intf_id = request->intf_id; - result_code = le16_to_cpu(request->result_code); - mailbox = le32_to_cpu(request->mailbox); - - dev_dbg(&svc->dev, "%s - id = %u, result = 0x%04x, mailbox = 0x%08x\n", - __func__, intf_id, result_code, mailbox); - - intf = gb_svc_interface_lookup(svc, intf_id); - if (!intf) { - dev_warn(&svc->dev, "unexpected mailbox event %u\n", intf_id); - return; - } - - gb_interface_mailbox_event(intf, result_code, mailbox); -} - -static void gb_svc_process_deferred_request(struct work_struct *work) -{ - struct gb_svc_deferred_request *dr; - struct gb_operation *operation; - struct gb_svc *svc; - u8 type; - - dr = container_of(work, struct gb_svc_deferred_request, work); - operation = dr->operation; - svc = gb_connection_get_data(operation->connection); - type = operation->request->header->type; - - switch (type) { - case GB_SVC_TYPE_SVC_HELLO: - gb_svc_process_hello_deferred(operation); - break; - case GB_SVC_TYPE_MODULE_INSERTED: - gb_svc_process_module_inserted(operation); - break; - case GB_SVC_TYPE_MODULE_REMOVED: - gb_svc_process_module_removed(operation); - break; - case GB_SVC_TYPE_INTF_MAILBOX_EVENT: - gb_svc_process_intf_mailbox_event(operation); - break; - case GB_SVC_TYPE_INTF_OOPS: - gb_svc_process_intf_oops(operation); - break; - default: - dev_err(&svc->dev, "bad deferred request type: 0x%02x\n", type); - } - - gb_operation_put(operation); - kfree(dr); -} - -static int gb_svc_queue_deferred_request(struct gb_operation *operation) -{ - struct gb_svc *svc = gb_connection_get_data(operation->connection); - struct gb_svc_deferred_request *dr; - - dr = kmalloc(sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - gb_operation_get(operation); - - dr->operation = operation; - INIT_WORK(&dr->work, gb_svc_process_deferred_request); - - queue_work(svc->wq, &dr->work); - - return 0; -} - -static int gb_svc_intf_reset_recv(struct gb_operation *op) -{ - struct gb_svc *svc = gb_connection_get_data(op->connection); - struct gb_message *request = op->request; - struct gb_svc_intf_reset_request *reset; - - if (request->payload_size < sizeof(*reset)) { - dev_warn(&svc->dev, "short reset request received (%zu < %zu)\n", - request->payload_size, sizeof(*reset)); - return -EINVAL; - } - reset = request->payload; - - /* FIXME Reset the interface here */ - - return 0; -} - -static int gb_svc_module_inserted_recv(struct gb_operation *op) -{ - struct gb_svc *svc = gb_connection_get_data(op->connection); - struct gb_svc_module_inserted_request *request; - - if (op->request->payload_size < sizeof(*request)) { - dev_warn(&svc->dev, "short module-inserted request received (%zu < %zu)\n", - op->request->payload_size, sizeof(*request)); - return -EINVAL; - } - - request = op->request->payload; - - dev_dbg(&svc->dev, "%s - id = %u\n", __func__, - request->primary_intf_id); - - return gb_svc_queue_deferred_request(op); -} - -static int gb_svc_module_removed_recv(struct gb_operation *op) -{ - struct gb_svc *svc = gb_connection_get_data(op->connection); - struct gb_svc_module_removed_request *request; - - if (op->request->payload_size < sizeof(*request)) { - dev_warn(&svc->dev, "short module-removed request received (%zu < %zu)\n", - op->request->payload_size, sizeof(*request)); - return -EINVAL; - } - - request = op->request->payload; - - dev_dbg(&svc->dev, "%s - id = %u\n", __func__, - request->primary_intf_id); - - return gb_svc_queue_deferred_request(op); -} - -static int gb_svc_intf_oops_recv(struct gb_operation *op) -{ - struct gb_svc *svc = gb_connection_get_data(op->connection); - struct gb_svc_intf_oops_request *request; - - if (op->request->payload_size < sizeof(*request)) { - dev_warn(&svc->dev, "short intf-oops request received (%zu < %zu)\n", - op->request->payload_size, sizeof(*request)); - return -EINVAL; - } - - return gb_svc_queue_deferred_request(op); -} - -static int gb_svc_intf_mailbox_event_recv(struct gb_operation *op) -{ - struct gb_svc *svc = gb_connection_get_data(op->connection); - struct gb_svc_intf_mailbox_event_request *request; - - if (op->request->payload_size < sizeof(*request)) { - dev_warn(&svc->dev, "short mailbox request received (%zu < %zu)\n", - op->request->payload_size, sizeof(*request)); - return -EINVAL; - } - - request = op->request->payload; - - dev_dbg(&svc->dev, "%s - id = %u\n", __func__, request->intf_id); - - return gb_svc_queue_deferred_request(op); -} - -static int gb_svc_request_handler(struct gb_operation *op) -{ - struct gb_connection *connection = op->connection; - struct gb_svc *svc = gb_connection_get_data(connection); - u8 type = op->type; - int ret = 0; - - /* - * SVC requests need to follow a specific order (at least initially) and - * below code takes care of enforcing that. The expected order is: - * - PROTOCOL_VERSION - * - SVC_HELLO - * - Any other request, but the earlier two. - * - * Incoming requests are guaranteed to be serialized and so we don't - * need to protect 'state' for any races. - */ - switch (type) { - case GB_SVC_TYPE_PROTOCOL_VERSION: - if (svc->state != GB_SVC_STATE_RESET) - ret = -EINVAL; - break; - case GB_SVC_TYPE_SVC_HELLO: - if (svc->state != GB_SVC_STATE_PROTOCOL_VERSION) - ret = -EINVAL; - break; - default: - if (svc->state != GB_SVC_STATE_SVC_HELLO) - ret = -EINVAL; - break; - } - - if (ret) { - dev_warn(&svc->dev, "unexpected request 0x%02x received (state %u)\n", - type, svc->state); - return ret; - } - - switch (type) { - case GB_SVC_TYPE_PROTOCOL_VERSION: - ret = gb_svc_version_request(op); - if (!ret) - svc->state = GB_SVC_STATE_PROTOCOL_VERSION; - return ret; - case GB_SVC_TYPE_SVC_HELLO: - ret = gb_svc_hello(op); - if (!ret) - svc->state = GB_SVC_STATE_SVC_HELLO; - return ret; - case GB_SVC_TYPE_INTF_RESET: - return gb_svc_intf_reset_recv(op); - case GB_SVC_TYPE_MODULE_INSERTED: - return gb_svc_module_inserted_recv(op); - case GB_SVC_TYPE_MODULE_REMOVED: - return gb_svc_module_removed_recv(op); - case GB_SVC_TYPE_INTF_MAILBOX_EVENT: - return gb_svc_intf_mailbox_event_recv(op); - case GB_SVC_TYPE_INTF_OOPS: - return gb_svc_intf_oops_recv(op); - default: - dev_warn(&svc->dev, "unsupported request 0x%02x\n", type); - return -EINVAL; - } -} - -static void gb_svc_release(struct device *dev) -{ - struct gb_svc *svc = to_gb_svc(dev); - - if (svc->connection) - gb_connection_destroy(svc->connection); - ida_destroy(&svc->device_id_map); - destroy_workqueue(svc->wq); - kfree(svc); -} - -struct device_type greybus_svc_type = { - .name = "greybus_svc", - .release = gb_svc_release, -}; - -struct gb_svc *gb_svc_create(struct gb_host_device *hd) -{ - struct gb_svc *svc; - - svc = kzalloc(sizeof(*svc), GFP_KERNEL); - if (!svc) - return NULL; - - svc->wq = alloc_workqueue("%s:svc", WQ_UNBOUND, 1, dev_name(&hd->dev)); - if (!svc->wq) { - kfree(svc); - return NULL; - } - - svc->dev.parent = &hd->dev; - svc->dev.bus = &greybus_bus_type; - svc->dev.type = &greybus_svc_type; - svc->dev.groups = svc_groups; - svc->dev.dma_mask = svc->dev.parent->dma_mask; - device_initialize(&svc->dev); - - dev_set_name(&svc->dev, "%d-svc", hd->bus_id); - - ida_init(&svc->device_id_map); - svc->state = GB_SVC_STATE_RESET; - svc->hd = hd; - - svc->connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID, - gb_svc_request_handler); - if (IS_ERR(svc->connection)) { - dev_err(&svc->dev, "failed to create connection: %ld\n", - PTR_ERR(svc->connection)); - goto err_put_device; - } - - gb_connection_set_data(svc->connection, svc); - - return svc; - -err_put_device: - put_device(&svc->dev); - return NULL; -} - -int gb_svc_add(struct gb_svc *svc) -{ - int ret; - - /* - * The SVC protocol is currently driven by the SVC, so the SVC device - * is added from the connection request handler when enough - * information has been received. - */ - ret = gb_connection_enable(svc->connection); - if (ret) - return ret; - - return 0; -} - -static void gb_svc_remove_modules(struct gb_svc *svc) -{ - struct gb_host_device *hd = svc->hd; - struct gb_module *module, *tmp; - - list_for_each_entry_safe(module, tmp, &hd->modules, hd_node) { - gb_module_del(module); - list_del(&module->hd_node); - gb_module_put(module); - } -} - -void gb_svc_del(struct gb_svc *svc) -{ - gb_connection_disable_rx(svc->connection); - - /* - * The SVC device may have been registered from the request handler. - */ - if (device_is_registered(&svc->dev)) { - gb_svc_debugfs_exit(svc); - gb_svc_watchdog_destroy(svc); - device_del(&svc->dev); - } - - flush_workqueue(svc->wq); - - gb_svc_remove_modules(svc); - - gb_connection_disable(svc->connection); -} - -void gb_svc_put(struct gb_svc *svc) -{ - put_device(&svc->dev); -} diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h deleted file mode 100644 index ad01783bac9c..000000000000 --- a/drivers/staging/greybus/svc.h +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Greybus SVC code - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - */ - -#ifndef __SVC_H -#define __SVC_H - -#define GB_SVC_CPORT_FLAG_E2EFC BIT(0) -#define GB_SVC_CPORT_FLAG_CSD_N BIT(1) -#define GB_SVC_CPORT_FLAG_CSV_N BIT(2) - -enum gb_svc_state { - GB_SVC_STATE_RESET, - GB_SVC_STATE_PROTOCOL_VERSION, - GB_SVC_STATE_SVC_HELLO, -}; - -enum gb_svc_watchdog_bite { - GB_SVC_WATCHDOG_BITE_RESET_UNIPRO = 0, - GB_SVC_WATCHDOG_BITE_PANIC_KERNEL, -}; - -struct gb_svc_watchdog; - -struct svc_debugfs_pwrmon_rail { - u8 id; - struct gb_svc *svc; -}; - -struct gb_svc { - struct device dev; - - struct gb_host_device *hd; - struct gb_connection *connection; - enum gb_svc_state state; - struct ida device_id_map; - struct workqueue_struct *wq; - - u16 endo_id; - u8 ap_intf_id; - - u8 protocol_major; - u8 protocol_minor; - - struct gb_svc_watchdog *watchdog; - enum gb_svc_watchdog_bite action; - - struct dentry *debugfs_dentry; - struct svc_debugfs_pwrmon_rail *pwrmon_rails; -}; -#define to_gb_svc(d) container_of(d, struct gb_svc, dev) - -struct gb_svc *gb_svc_create(struct gb_host_device *hd); -int gb_svc_add(struct gb_svc *svc); -void gb_svc_del(struct gb_svc *svc); -void gb_svc_put(struct gb_svc *svc); - -int gb_svc_pwrmon_intf_sample_get(struct gb_svc *svc, u8 intf_id, - u8 measurement_type, u32 *value); -int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id); -int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id, - u8 intf2_id, u8 dev2_id); -void gb_svc_route_destroy(struct gb_svc *svc, u8 intf1_id, u8 intf2_id); -int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_id, - u8 intf2_id, u16 cport2_id, u8 cport_flags); -void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id, - u8 intf2_id, u16 cport2_id); -int gb_svc_intf_eject(struct gb_svc *svc, u8 intf_id); -int gb_svc_intf_vsys_set(struct gb_svc *svc, u8 intf_id, bool enable); -int gb_svc_intf_refclk_set(struct gb_svc *svc, u8 intf_id, bool enable); -int gb_svc_intf_unipro_set(struct gb_svc *svc, u8 intf_id, bool enable); -int gb_svc_intf_activate(struct gb_svc *svc, u8 intf_id, u8 *intf_type); -int gb_svc_intf_resume(struct gb_svc *svc, u8 intf_id); - -int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector, - u32 *value); -int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector, - u32 value); -int gb_svc_intf_set_power_mode(struct gb_svc *svc, u8 intf_id, u8 hs_series, - u8 tx_mode, u8 tx_gear, u8 tx_nlanes, - u8 tx_amplitude, u8 tx_hs_equalizer, - u8 rx_mode, u8 rx_gear, u8 rx_nlanes, - u8 flags, u32 quirks, - struct gb_svc_l2_timer_cfg *local, - struct gb_svc_l2_timer_cfg *remote); -int gb_svc_intf_set_power_mode_hibernate(struct gb_svc *svc, u8 intf_id); -int gb_svc_ping(struct gb_svc *svc); -int gb_svc_watchdog_create(struct gb_svc *svc); -void gb_svc_watchdog_destroy(struct gb_svc *svc); -bool gb_svc_watchdog_enabled(struct gb_svc *svc); -int gb_svc_watchdog_enable(struct gb_svc *svc); -int gb_svc_watchdog_disable(struct gb_svc *svc); - -int gb_svc_protocol_init(void); -void gb_svc_protocol_exit(void); - -#endif /* __SVC_H */ diff --git a/drivers/staging/greybus/svc_watchdog.c b/drivers/staging/greybus/svc_watchdog.c deleted file mode 100644 index 7868ad8211c5..000000000000 --- a/drivers/staging/greybus/svc_watchdog.c +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * SVC Greybus "watchdog" driver. - * - * Copyright 2016 Google Inc. - */ - -#include <linux/delay.h> -#include <linux/suspend.h> -#include <linux/workqueue.h> -#include "greybus.h" - -#define SVC_WATCHDOG_PERIOD (2 * HZ) - -struct gb_svc_watchdog { - struct delayed_work work; - struct gb_svc *svc; - bool enabled; - struct notifier_block pm_notifier; -}; - -static struct delayed_work reset_work; - -static int svc_watchdog_pm_notifier(struct notifier_block *notifier, - unsigned long pm_event, void *unused) -{ - struct gb_svc_watchdog *watchdog = - container_of(notifier, struct gb_svc_watchdog, pm_notifier); - - switch (pm_event) { - case PM_SUSPEND_PREPARE: - gb_svc_watchdog_disable(watchdog->svc); - break; - case PM_POST_SUSPEND: - gb_svc_watchdog_enable(watchdog->svc); - break; - default: - break; - } - - return NOTIFY_DONE; -} - -static void greybus_reset(struct work_struct *work) -{ - static char const start_path[] = "/system/bin/start"; - static char *envp[] = { - "HOME=/", - "PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin", - NULL, - }; - static char *argv[] = { - (char *)start_path, - "unipro_reset", - NULL, - }; - - pr_err("svc_watchdog: calling \"%s %s\" to reset greybus network!\n", - argv[0], argv[1]); - call_usermodehelper(start_path, argv, envp, UMH_WAIT_EXEC); -} - -static void do_work(struct work_struct *work) -{ - struct gb_svc_watchdog *watchdog; - struct gb_svc *svc; - int retval; - - watchdog = container_of(work, struct gb_svc_watchdog, work.work); - svc = watchdog->svc; - - dev_dbg(&svc->dev, "%s: ping.\n", __func__); - retval = gb_svc_ping(svc); - if (retval) { - /* - * Something went really wrong, let's warn userspace and then - * pull the plug and reset the whole greybus network. - * We need to do this outside of this workqueue as we will be - * tearing down the svc device itself. So queue up - * yet-another-callback to do that. - */ - dev_err(&svc->dev, - "SVC ping has returned %d, something is wrong!!!\n", - retval); - - if (svc->action == GB_SVC_WATCHDOG_BITE_PANIC_KERNEL) { - panic("SVC is not responding\n"); - } else if (svc->action == GB_SVC_WATCHDOG_BITE_RESET_UNIPRO) { - dev_err(&svc->dev, "Resetting the greybus network, watch out!!!\n"); - - INIT_DELAYED_WORK(&reset_work, greybus_reset); - schedule_delayed_work(&reset_work, HZ / 2); - - /* - * Disable ourselves, we don't want to trip again unless - * userspace wants us to. - */ - watchdog->enabled = false; - } - } - - /* resubmit our work to happen again, if we are still "alive" */ - if (watchdog->enabled) - schedule_delayed_work(&watchdog->work, SVC_WATCHDOG_PERIOD); -} - -int gb_svc_watchdog_create(struct gb_svc *svc) -{ - struct gb_svc_watchdog *watchdog; - int retval; - - if (svc->watchdog) - return 0; - - watchdog = kmalloc(sizeof(*watchdog), GFP_KERNEL); - if (!watchdog) - return -ENOMEM; - - watchdog->enabled = false; - watchdog->svc = svc; - INIT_DELAYED_WORK(&watchdog->work, do_work); - svc->watchdog = watchdog; - - watchdog->pm_notifier.notifier_call = svc_watchdog_pm_notifier; - retval = register_pm_notifier(&watchdog->pm_notifier); - if (retval) { - dev_err(&svc->dev, "error registering pm notifier(%d)\n", - retval); - goto svc_watchdog_create_err; - } - - retval = gb_svc_watchdog_enable(svc); - if (retval) { - dev_err(&svc->dev, "error enabling watchdog (%d)\n", retval); - unregister_pm_notifier(&watchdog->pm_notifier); - goto svc_watchdog_create_err; - } - return retval; - -svc_watchdog_create_err: - svc->watchdog = NULL; - kfree(watchdog); - - return retval; -} - -void gb_svc_watchdog_destroy(struct gb_svc *svc) -{ - struct gb_svc_watchdog *watchdog = svc->watchdog; - - if (!watchdog) - return; - - unregister_pm_notifier(&watchdog->pm_notifier); - gb_svc_watchdog_disable(svc); - svc->watchdog = NULL; - kfree(watchdog); -} - -bool gb_svc_watchdog_enabled(struct gb_svc *svc) -{ - if (!svc || !svc->watchdog) - return false; - return svc->watchdog->enabled; -} - -int gb_svc_watchdog_enable(struct gb_svc *svc) -{ - struct gb_svc_watchdog *watchdog; - - if (!svc->watchdog) - return -ENODEV; - - watchdog = svc->watchdog; - if (watchdog->enabled) - return 0; - - watchdog->enabled = true; - schedule_delayed_work(&watchdog->work, SVC_WATCHDOG_PERIOD); - return 0; -} - -int gb_svc_watchdog_disable(struct gb_svc *svc) -{ - struct gb_svc_watchdog *watchdog; - - if (!svc->watchdog) - return -ENODEV; - - watchdog = svc->watchdog; - if (!watchdog->enabled) - return 0; - - watchdog->enabled = false; - cancel_delayed_work_sync(&watchdog->work); - return 0; -} diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c index cebc1d90a180..ba6f905f26fa 100644 --- a/drivers/staging/greybus/tools/loopback_test.c +++ b/drivers/staging/greybus/tools/loopback_test.c @@ -4,8 +4,6 @@ * * Copyright 2015 Google Inc. * Copyright 2015 Linaro Ltd. - * - * Provided under the three clause BSD license found in the LICENSE file. */ #include <errno.h> #include <fcntl.h> diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index b3bffe91ae99..55c51143bb09 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -28,8 +28,8 @@ #include <linux/kfifo.h> #include <linux/workqueue.h> #include <linux/completion.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" #define GB_NUM_MINORS 16 /* 16 is more than enough */ diff --git a/drivers/staging/greybus/usb.c b/drivers/staging/greybus/usb.c index 1c246c73a085..8e9d9d59a357 100644 --- a/drivers/staging/greybus/usb.c +++ b/drivers/staging/greybus/usb.c @@ -10,8 +10,8 @@ #include <linux/slab.h> #include <linux/usb.h> #include <linux/usb/hcd.h> +#include <linux/greybus.h> -#include "greybus.h" #include "gbphy.h" /* Greybus USB request types */ diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c index 3e5dedeacd5c..0e2b188e5ca3 100644 --- a/drivers/staging/greybus/vibrator.c +++ b/drivers/staging/greybus/vibrator.c @@ -13,8 +13,7 @@ #include <linux/kdev_t.h> #include <linux/idr.h> #include <linux/pm_runtime.h> - -#include "greybus.h" +#include <linux/greybus.h> struct gb_vibrator_device { struct gb_connection *connection; diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index 62f4b3b1b457..82099db4bf0c 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c @@ -309,15 +309,12 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, long mask) { struct adis *st = iio_priv(indio_dev); - int bits = 10; - s16 val16; u8 addr; switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: - val16 = val & ((1 << bits) - 1); addr = adis16240_addresses[chan->scan_index][0]; - return adis_write_reg_16(st, addr, val16); + return adis_write_reg_16(st, addr, val & GENMASK(9, 0)); } return -EINVAL; } diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index b6d12fe7c12a..e6b660489165 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -25,8 +25,6 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/adc/ad_sigma_delta.h> -#include "ad7192.h" - /* Registers */ #define AD7192_REG_COMM 0 /* Communications Register (WO, 8-bit) */ #define AD7192_REG_STAT 0 /* Status Register (RO, 8-bit) */ @@ -145,6 +143,10 @@ #define AD7192_EXT_FREQ_MHZ_MAX 5120000 #define AD7192_INT_FREQ_MHZ 4915200 +#define AD7192_NO_SYNC_FILTER 1 +#define AD7192_SYNC3_FILTER 3 +#define AD7192_SYNC4_FILTER 4 + /* NOTE: * The AD7190/2/5 features a dual use data out ready DOUT/RDY output. * In order to avoid contentions on the SPI bus, it's therefore necessary @@ -252,7 +254,7 @@ static int ad7192_of_clock_select(struct ad7192_state *st) static int ad7192_setup(struct ad7192_state *st, struct device_node *np) { struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); - bool rej60_en, sinc3_en, refin2_en, chop_en; + bool rej60_en, refin2_en; bool buf_en, bipolar, burnout_curr_en; unsigned long long scale_uv; int i, ret, id; @@ -284,24 +286,12 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np) if (rej60_en) st->mode |= AD7192_MODE_REJ60; - sinc3_en = of_property_read_bool(np, "adi,sinc3-filter-enable"); - if (sinc3_en) - st->mode |= AD7192_MODE_SINC3; - refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable"); if (refin2_en && st->devid != ID_AD7195) st->conf |= AD7192_CONF_REFSEL; - chop_en = of_property_read_bool(np, "adi,chop-enable"); - if (chop_en) { - st->conf |= AD7192_CONF_CHOP; - if (sinc3_en) - st->f_order = 3; /* SINC 3rd order */ - else - st->f_order = 4; /* SINC 4th order */ - } else { - st->f_order = 1; - } + st->conf &= ~AD7192_CONF_CHOP; + st->f_order = AD7192_NO_SYNC_FILTER; buf_en = of_property_read_bool(np, "adi,buffer-enable"); if (buf_en) @@ -313,7 +303,7 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np) burnout_curr_en = of_property_read_bool(np, "adi,burnout-currents-enable"); - if (burnout_curr_en && buf_en && !chop_en) { + if (burnout_curr_en && buf_en) { st->conf |= AD7192_CONF_BURN; } else if (burnout_curr_en) { dev_warn(&st->sd.spi->dev, @@ -411,6 +401,49 @@ static ssize_t ad7192_set(struct device *dev, return ret ? ret : len; } +static void ad7192_get_available_filter_freq(struct ad7192_state *st, + int *freq) +{ + unsigned int fadc; + + /* Formulas for filter at page 25 of the datasheet */ + fadc = DIV_ROUND_CLOSEST(st->fclk, + AD7192_SYNC4_FILTER * AD7192_MODE_RATE(st->mode)); + freq[0] = DIV_ROUND_CLOSEST(fadc * 240, 1024); + + fadc = DIV_ROUND_CLOSEST(st->fclk, + AD7192_SYNC3_FILTER * AD7192_MODE_RATE(st->mode)); + freq[1] = DIV_ROUND_CLOSEST(fadc * 240, 1024); + + fadc = DIV_ROUND_CLOSEST(st->fclk, AD7192_MODE_RATE(st->mode)); + freq[2] = DIV_ROUND_CLOSEST(fadc * 230, 1024); + freq[3] = DIV_ROUND_CLOSEST(fadc * 272, 1024); +} + +static ssize_t ad7192_show_filter_avail(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ad7192_state *st = iio_priv(indio_dev); + unsigned int freq_avail[4], i; + size_t len = 0; + + ad7192_get_available_filter_freq(st, freq_avail); + + for (i = 0; i < ARRAY_SIZE(freq_avail); i++) + len += scnprintf(buf + len, PAGE_SIZE - len, + "%d.%d ", freq_avail[i] / 1000, + freq_avail[i] % 1000); + + buf[len - 1] = '\n'; + + return len; +} + +static IIO_DEVICE_ATTR(filter_low_pass_3db_frequency_available, + 0444, ad7192_show_filter_avail, NULL, 0); + static IIO_DEVICE_ATTR(bridge_switch_en, 0644, ad7192_show_bridge_switch, ad7192_set, AD7192_REG_GPOCON); @@ -420,6 +453,7 @@ static IIO_DEVICE_ATTR(ac_excitation_en, 0644, AD7192_REG_MODE); static struct attribute *ad7192_attributes[] = { + &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, &iio_dev_attr_bridge_switch_en.dev_attr.attr, &iio_dev_attr_ac_excitation_en.dev_attr.attr, NULL @@ -430,6 +464,7 @@ static const struct attribute_group ad7192_attribute_group = { }; static struct attribute *ad7195_attributes[] = { + &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, &iio_dev_attr_bridge_switch_en.dev_attr.attr, NULL }; @@ -443,6 +478,75 @@ static unsigned int ad7192_get_temp_scale(bool unipolar) return unipolar ? 2815 * 2 : 2815; } +static int ad7192_set_3db_filter_freq(struct ad7192_state *st, + int val, int val2) +{ + int freq_avail[4], i, ret, freq; + unsigned int diff_new, diff_old; + int idx = 0; + + diff_old = U32_MAX; + freq = val * 1000 + val2; + + ad7192_get_available_filter_freq(st, freq_avail); + + for (i = 0; i < ARRAY_SIZE(freq_avail); i++) { + diff_new = abs(freq - freq_avail[i]); + if (diff_new < diff_old) { + diff_old = diff_new; + idx = i; + } + } + + switch (idx) { + case 0: + st->f_order = AD7192_SYNC4_FILTER; + st->mode &= ~AD7192_MODE_SINC3; + + st->conf |= AD7192_CONF_CHOP; + break; + case 1: + st->f_order = AD7192_SYNC3_FILTER; + st->mode |= AD7192_MODE_SINC3; + + st->conf |= AD7192_CONF_CHOP; + break; + case 2: + st->f_order = AD7192_NO_SYNC_FILTER; + st->mode &= ~AD7192_MODE_SINC3; + + st->conf &= ~AD7192_CONF_CHOP; + break; + case 3: + st->f_order = AD7192_NO_SYNC_FILTER; + st->mode |= AD7192_MODE_SINC3; + + st->conf &= ~AD7192_CONF_CHOP; + break; + } + + ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); + if (ret < 0) + return ret; + + return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); +} + +static int ad7192_get_3db_filter_freq(struct ad7192_state *st) +{ + unsigned int fadc; + + fadc = DIV_ROUND_CLOSEST(st->fclk, + st->f_order * AD7192_MODE_RATE(st->mode)); + + if (st->conf & AD7192_CONF_CHOP) + return DIV_ROUND_CLOSEST(fadc * 240, 1024); + if (st->mode & AD7192_MODE_SINC3) + return DIV_ROUND_CLOSEST(fadc * 272, 1024); + else + return DIV_ROUND_CLOSEST(fadc * 230, 1024); +} + static int ad7192_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, @@ -483,6 +587,10 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, *val = st->fclk / (st->f_order * 1024 * AD7192_MODE_RATE(st->mode)); return IIO_VAL_INT; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + *val = ad7192_get_3db_filter_freq(st); + *val2 = 1000; + return IIO_VAL_FRACTIONAL; } return -EINVAL; @@ -537,6 +645,9 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, st->mode |= AD7192_MODE_RATE(div); ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); break; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + ret = ad7192_set_3db_filter_freq(st, val, val2 / 1000); + break; default: ret = -EINVAL; } @@ -555,6 +666,8 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_NANO; case IIO_CHAN_INFO_SAMP_FREQ: return IIO_VAL_INT; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } @@ -655,6 +768,8 @@ static int ad7192_channels_config(struct iio_dev *indio_dev) for (i = 0; i < indio_dev->num_channels; i++) { *chan = channels[i]; + chan->info_mask_shared_by_all |= + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY); if (chan->type != IIO_TEMP) chan->info_mask_shared_by_type_available |= BIT(IIO_CHAN_INFO_SCALE); @@ -666,16 +781,10 @@ static int ad7192_channels_config(struct iio_dev *indio_dev) static int ad7192_probe(struct spi_device *spi) { - const struct ad7192_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad7192_state *st; struct iio_dev *indio_dev; int ret, voltage_uv = 0; - if (!pdata) { - dev_err(&spi->dev, "no platform data?\n"); - return -ENODEV; - } - if (!spi->irq) { dev_err(&spi->dev, "no IRQ?\n"); return -ENODEV; @@ -713,12 +822,10 @@ static int ad7192_probe(struct spi_device *spi) voltage_uv = regulator_get_voltage(st->avdd); - if (pdata->vref_mv) - st->int_vref_mv = pdata->vref_mv; - else if (voltage_uv) + if (voltage_uv) st->int_vref_mv = voltage_uv / 1000; else - dev_warn(&spi->dev, "reference voltage undefined\n"); + dev_err(&spi->dev, "Device tree error, reference voltage undefined\n"); spi_set_drvdata(spi, indio_dev); st->devid = spi_get_device_id(spi)->driver_data; @@ -809,11 +916,23 @@ static const struct spi_device_id ad7192_id[] = { {"ad7195", ID_AD7195}, {} }; + MODULE_DEVICE_TABLE(spi, ad7192_id); +static const struct of_device_id ad7192_of_match[] = { + { .compatible = "adi,ad7190" }, + { .compatible = "adi,ad7192" }, + { .compatible = "adi,ad7193" }, + { .compatible = "adi,ad7195" }, + {} +}; + +MODULE_DEVICE_TABLE(of, ad7192_of_match); + static struct spi_driver ad7192_driver = { .driver = { .name = "ad7192", + .of_match_table = ad7192_of_match, }, .probe = ad7192_probe, .remove = ad7192_remove, diff --git a/drivers/staging/iio/adc/ad7192.h b/drivers/staging/iio/adc/ad7192.h deleted file mode 100644 index f3669e1df084..000000000000 --- a/drivers/staging/iio/adc/ad7192.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * AD7190 AD7192 AD7195 SPI ADC driver - * - * Copyright 2011 Analog Devices Inc. - */ -#ifndef IIO_ADC_AD7192_H_ -#define IIO_ADC_AD7192_H_ - -/* - * TODO: struct ad7192_platform_data needs to go into include/linux/iio - */ - -/** - * struct ad7192_platform_data - platform/board specific information - * @vref_mv: the external reference voltage in millivolt - * @clock_source_sel: [0..3] - * 0 External 4.92 MHz clock connected from MCLK1 to MCLK2 - * 1 External Clock applied to MCLK2 - * 2 Internal 4.92 MHz Clock not available at the MCLK2 pin - * 3 Internal 4.92 MHz Clock available at the MCLK2 pin - * @ext_clk_Hz: the external clock frequency in Hz, if not set - * the driver uses the internal clock (16.776 MHz) - * @refin2_en: REFIN1/REFIN2 Reference Select (AD7190/2 only) - * @rej60_en: 50/60Hz notch filter enable - * @sinc3_en: SINC3 filter enable (default SINC4) - * @chop_en: CHOP mode enable - * @buf_en: buffered input mode enable - * @unipolar_en: unipolar mode enable - * @burnout_curr_en: constant current generators on AIN(+|-) enable - */ - -struct ad7192_platform_data { - u16 vref_mv; -}; - -#endif /* IIO_ADC_AD7192_H_ */ diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 0c1bd108c386..4b25a3a314ed 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -671,7 +671,7 @@ static int ad2s1210_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(ad2s1210_channels); indio_dev->name = spi_get_device_id(spi)->name; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; @@ -683,15 +683,6 @@ static int ad2s1210_probe(struct spi_device *spi) return 0; } -static int ad2s1210_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - - return 0; -} - static const struct of_device_id ad2s1210_of_match[] = { { .compatible = "adi,ad2s1210", }, { } @@ -710,7 +701,6 @@ static struct spi_driver ad2s1210_driver = { .of_match_table = of_match_ptr(ad2s1210_of_match), }, .probe = ad2s1210_probe, - .remove = ad2s1210_remove, .id_table = ad2s1210_id, }; module_spi_driver(ad2s1210_driver); diff --git a/drivers/staging/isdn/hysdn/hysdn_net.c b/drivers/staging/isdn/hysdn/hysdn_net.c index bea37ae30ebb..dcb9ef7a2651 100644 --- a/drivers/staging/isdn/hysdn/hysdn_net.c +++ b/drivers/staging/isdn/hysdn/hysdn_net.c @@ -286,7 +286,7 @@ hysdn_net_create(hysdn_card *card) if (card->debug_flags & LOG_NET_INIT) hysdn_addlog(card, "network device created"); - return (0); /* and return success */ + return 0; /* and return success */ } /* hysdn_net_create */ /***************************************************************************/ diff --git a/drivers/staging/isdn/hysdn/hysdn_procconf.c b/drivers/staging/isdn/hysdn/hysdn_procconf.c index 73079213ec94..48afd9f5316e 100644 --- a/drivers/staging/isdn/hysdn/hysdn_procconf.c +++ b/drivers/staging/isdn/hysdn/hysdn_procconf.c @@ -382,7 +382,7 @@ hysdn_procconf_init(void) } printk(KERN_NOTICE "HYSDN: procfs initialised\n"); - return (0); + return 0; } /* hysdn_procconf_init */ /*************************************************************************************/ diff --git a/drivers/staging/kpc2000/kpc2000/cell_probe.c b/drivers/staging/kpc2000/kpc2000/cell_probe.c index c124a836db27..738122afc2ae 100644 --- a/drivers/staging/kpc2000/kpc2000/cell_probe.c +++ b/drivers/staging/kpc2000/kpc2000/cell_probe.c @@ -53,15 +53,15 @@ struct core_table_entry { static void parse_core_table_entry_v0(struct core_table_entry *cte, const u64 read_val) { - cte->type = ((read_val & 0xFFF0000000000000) >> 52); - cte->offset = ((read_val & 0x00000000FFFF0000) >> 16) * 4096; - cte->length = ((read_val & 0x0000FFFF00000000) >> 32) * 8; - cte->s2c_dma_present = ((read_val & 0x0008000000000000) >> 51); - cte->s2c_dma_channel_num = ((read_val & 0x0007000000000000) >> 48); - cte->c2s_dma_present = ((read_val & 0x0000000000008000) >> 15); - cte->c2s_dma_channel_num = ((read_val & 0x0000000000007000) >> 12); - cte->irq_count = ((read_val & 0x0000000000000C00) >> 10); - cte->irq_base_num = ((read_val & 0x00000000000003F8) >> 3); + cte->type = ((read_val & 0xFFF0000000000000UL) >> 52); + cte->offset = ((read_val & 0x00000000FFFF0000UL) >> 16) * 4096; + cte->length = ((read_val & 0x0000FFFF00000000UL) >> 32) * 8; + cte->s2c_dma_present = ((read_val & 0x0008000000000000UL) >> 51); + cte->s2c_dma_channel_num = ((read_val & 0x0007000000000000UL) >> 48); + cte->c2s_dma_present = ((read_val & 0x0000000000008000UL) >> 15); + cte->c2s_dma_channel_num = ((read_val & 0x0000000000007000UL) >> 12); + cte->irq_count = ((read_val & 0x0000000000000C00UL) >> 10); + cte->irq_base_num = ((read_val & 0x00000000000003F8UL) >> 3); } static diff --git a/drivers/staging/kpc2000/kpc2000/core.c b/drivers/staging/kpc2000/kpc2000/core.c index cb05cca687e1..0a23727d0dc3 100644 --- a/drivers/staging/kpc2000/kpc2000/core.c +++ b/drivers/staging/kpc2000/kpc2000/core.c @@ -205,7 +205,7 @@ static void wait_and_read_ssid(struct kp2000_device *pcard) u64 read_val = readq(pcard->sysinfo_regs_base + REG_FPGA_SSID); unsigned long timeout; - if (read_val & 0x8000000000000000) { + if (read_val & 0x8000000000000000UL) { pcard->ssid = read_val; return; } @@ -213,7 +213,7 @@ static void wait_and_read_ssid(struct kp2000_device *pcard) timeout = jiffies + (HZ * 2); do { read_val = readq(pcard->sysinfo_regs_base + REG_FPGA_SSID); - if (read_val & 0x8000000000000000) { + if (read_val & 0x8000000000000000UL) { pcard->ssid = read_val; return; } @@ -241,16 +241,16 @@ static int read_system_regs(struct kp2000_device *pcard) } read_val = readq(pcard->sysinfo_regs_base + REG_CARD_ID_AND_BUILD); - pcard->card_id = (read_val & 0xFFFFFFFF00000000) >> 32; - pcard->build_version = (read_val & 0x00000000FFFFFFFF) >> 0; + pcard->card_id = (read_val & 0xFFFFFFFF00000000UL) >> 32; + pcard->build_version = (read_val & 0x00000000FFFFFFFFUL) >> 0; read_val = readq(pcard->sysinfo_regs_base + REG_DATE_AND_TIME_STAMPS); - pcard->build_datestamp = (read_val & 0xFFFFFFFF00000000) >> 32; - pcard->build_timestamp = (read_val & 0x00000000FFFFFFFF) >> 0; + pcard->build_datestamp = (read_val & 0xFFFFFFFF00000000UL) >> 32; + pcard->build_timestamp = (read_val & 0x00000000FFFFFFFFUL) >> 0; read_val = readq(pcard->sysinfo_regs_base + REG_CORE_TABLE_OFFSET); - pcard->core_table_length = (read_val & 0xFFFFFFFF00000000) >> 32; - pcard->core_table_offset = (read_val & 0x00000000FFFFFFFF) >> 0; + pcard->core_table_length = (read_val & 0xFFFFFFFF00000000UL) >> 32; + pcard->core_table_offset = (read_val & 0x00000000FFFFFFFFUL) >> 0; wait_and_read_ssid(pcard); @@ -401,7 +401,7 @@ static int kp2000_pcie_probe(struct pci_dev *pdev, goto err_release_dma; // Disable all "user" interrupts because they're not used yet. - writeq(0xFFFFFFFFFFFFFFFF, + writeq(0xFFFFFFFFFFFFFFFFUL, pcard->sysinfo_regs_base + REG_INTERRUPT_MASK); // let the card master PCIe diff --git a/drivers/staging/kpc2000/kpc2000_i2c.c b/drivers/staging/kpc2000/kpc2000_i2c.c index b108da4ac633..bc02534d8dc3 100644 --- a/drivers/staging/kpc2000/kpc2000_i2c.c +++ b/drivers/staging/kpc2000/kpc2000_i2c.c @@ -123,9 +123,9 @@ struct i2c_device { // FIXME! #undef inb_p -#define inb_p(a) readq((void *)a) +#define inb_p(a) readq((void __iomem *)a) #undef outb_p -#define outb_p(d, a) writeq(d, (void *)a) +#define outb_p(d, a) writeq(d, (void __iomem *)a) /* Make sure the SMBus host is ready to start transmitting. * Return 0 if it is, -EBUSY if it is not. diff --git a/drivers/staging/kpc2000/kpc2000_spi.c b/drivers/staging/kpc2000/kpc2000_spi.c index 35ac1d7070b3..3be33c450cab 100644 --- a/drivers/staging/kpc2000/kpc2000_spi.c +++ b/drivers/staging/kpc2000/kpc2000_spi.c @@ -412,8 +412,7 @@ kp_spi_cleanup(struct spi_device *spidev) { struct kp_spi_controller_state *cs = spidev->controller_state; - if (cs) - kfree(cs); + kfree(cs); } /****************** diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c index 48ca88bc6b0b..cb52bd9a6d2f 100644 --- a/drivers/staging/kpc2000/kpc_dma/fileops.c +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c @@ -146,15 +146,15 @@ static int kpc_dma_transfer(struct dev_private_data *priv, card_addr += desc->DescByteCount; dma_addr = sg_dma_address(sg) + (p * 0x80000); - desc->DescSystemAddrLS = (dma_addr & 0x00000000FFFFFFFF) >> 0; - desc->DescSystemAddrMS = (dma_addr & 0xFFFFFFFF00000000) >> 32; + desc->DescSystemAddrLS = (dma_addr & 0x00000000FFFFFFFFUL) >> 0; + desc->DescSystemAddrMS = (dma_addr & 0xFFFFFFFF00000000UL) >> 32; user_ctl = acd->priv->user_ctl; if (i == acd->mapped_entry_count-1 && p == pcnt-1) { user_ctl = acd->priv->user_ctl_last; } - desc->DescUserControlLS = (user_ctl & 0x00000000FFFFFFFF) >> 0; - desc->DescUserControlMS = (user_ctl & 0xFFFFFFFF00000000) >> 32; + desc->DescUserControlLS = (user_ctl & 0x00000000FFFFFFFFUL) >> 0; + desc->DescUserControlMS = (user_ctl & 0xFFFFFFFF00000000UL) >> 32; if (i == acd->mapped_entry_count-1 && p == pcnt-1) desc->acd = acd; diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c index f050c7347fd5..6f0cd0784786 100644 --- a/drivers/staging/media/allegro-dvt/allegro-core.c +++ b/drivers/staging/media/allegro-dvt/allegro-core.c @@ -2947,10 +2947,8 @@ static int allegro_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get irq resource\n"); + if (irq < 0) return irq; - } ret = devm_request_threaded_irq(&pdev->dev, irq, allegro_hardirq, allegro_irq_thread, diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index d8b6816b643b..6d9d41170832 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -797,10 +797,8 @@ static int hantro_probe(struct platform_device *pdev) continue; irq = platform_get_irq_byname(vpu->pdev, irq_name); - if (irq <= 0) { - dev_err(vpu->dev, "Could not get %s IRQ.\n", irq_name); + if (irq <= 0) return -ENXIO; - } ret = devm_request_irq(vpu->dev, irq, vpu->variant->irqs[i].handler, 0, diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index 4ca79ff4c9b3..bfd6b5fbf484 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -1205,10 +1205,8 @@ static int imx7_csi_probe(struct platform_device *pdev) } csi->irq = platform_get_irq(pdev, 0); - if (csi->irq < 0) { - dev_err(dev, "Missing platform resources data\n"); + if (csi->irq < 0) return csi->irq; - } csi->regbase = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(csi->regbase)) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index d1cdf011c8f1..73d8354e618c 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -975,10 +975,8 @@ static int mipi_csis_probe(struct platform_device *pdev) return PTR_ERR(state->regs); state->irq = platform_get_irq(pdev, 0); - if (state->irq < 0) { - dev_err(dev, "Failed to get irq\n"); + if (state->irq < 0) return state->irq; - } ret = mipi_csis_clk_get(state); if (ret < 0) diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c index 3a21a8cec799..95102a4bdc62 100644 --- a/drivers/staging/media/meson/vdec/esparser.c +++ b/drivers/staging/media/meson/vdec/esparser.c @@ -301,10 +301,8 @@ int esparser_init(struct platform_device *pdev, struct amvdec_core *core) int irq; irq = platform_get_irq_byname(pdev, "esparser"); - if (irq < 0) { - dev_err(dev, "Failed getting ESPARSER IRQ from dtb\n"); + if (irq < 0) return irq; - } ret = devm_request_irq(dev, irq, esparser_isr, IRQF_SHARED, "esparserirq", core); diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index c8be1db532ab..1a966cb2f3a6 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1276,7 +1276,6 @@ static int iss_probe(struct platform_device *pdev) /* Interrupt */ ret = platform_get_irq(pdev, 0); if (ret <= 0) { - dev_err(iss->dev, "No IRQ resource\n"); ret = -ENODEV; goto error_iss; } diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c index fc8579b90dab..a942cd9bed57 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c @@ -157,11 +157,8 @@ int cedrus_hw_probe(struct cedrus_dev *dev) dev->capabilities = variant->capabilities; irq_dec = platform_get_irq(dev->pdev, 0); - if (irq_dec <= 0) { - dev_err(dev->dev, "Failed to get IRQ\n"); - + if (irq_dec <= 0) return irq_dec; - } ret = devm_request_irq(dev->dev, irq_dec, cedrus_irq, 0, dev_name(dev->dev), dev); if (ret) { diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c index d0cc0b746107..724d098aeef0 100644 --- a/drivers/staging/most/cdev/cdev.c +++ b/drivers/staging/most/cdev/cdev.c @@ -463,10 +463,8 @@ static int comp_probe(struct most_interface *iface, int channel_id, spin_lock_init(&c->unlink); INIT_KFIFO(c->fifo); retval = kfifo_alloc(&c->fifo, cfg->num_buffers, GFP_KERNEL); - if (retval) { - pr_info("failed to alloc channel kfifo"); + if (retval) goto err_del_cdev_and_free_channel; - } init_waitqueue_head(&c->wq); mutex_init(&c->io_mutex); spin_lock_irqsave(&ch_list_lock, cl_flags); diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c index b9841adb7181..8e9a0b67c6ed 100644 --- a/drivers/staging/most/core.c +++ b/drivers/staging/most/core.c @@ -303,7 +303,8 @@ static ssize_t set_datatype_show(struct device *dev, for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { if (c->cfg.data_type & ch_data_type[i].most_ch_data_type) - return snprintf(buf, PAGE_SIZE, "%s", ch_data_type[i].name); + return snprintf(buf, PAGE_SIZE, "%s", + ch_data_type[i].name); } return snprintf(buf, PAGE_SIZE, "unconfigured\n"); } @@ -721,6 +722,7 @@ int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name, return link_channel_to_component(c, comp, link_name, comp_param); } + /** * remove_link_store - store function for remove_link attribute * @drv: device driver diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 31fbc1a75b06..64c979155a49 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -129,25 +129,6 @@ bool dim2_sysfs_get_state_cb(void) } /** - * dimcb_io_read - callback from HAL to read an I/O register - * @ptr32: register address - */ -u32 dimcb_io_read(u32 __iomem *ptr32) -{ - return readl(ptr32); -} - -/** - * dimcb_io_write - callback from HAL to write value to an I/O register - * @ptr32: register address - * @value: value to write - */ -void dimcb_io_write(u32 __iomem *ptr32, u32 value) -{ - writel(value, ptr32); -} - -/** * dimcb_on_error - callback from HAL to report miscommunication between * HDM and HAL * @error_id: Error ID @@ -797,7 +778,6 @@ static int dim2_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, AHB0_INT_IDX); if (irq < 0) { - dev_err(&pdev->dev, "failed to get ahb0_int irq: %d\n", irq); ret = irq; goto err_shutdown_dim; } @@ -811,7 +791,6 @@ static int dim2_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, MLB_INT_IDX); if (irq < 0) { - dev_err(&pdev->dev, "failed to get mlb_int irq: %d\n", irq); ret = irq; goto err_shutdown_dim; } diff --git a/drivers/staging/most/dim2/hal.c b/drivers/staging/most/dim2/hal.c index 699e02f83bd4..39e17a7d2f24 100644 --- a/drivers/staging/most/dim2/hal.c +++ b/drivers/staging/most/dim2/hal.c @@ -13,6 +13,7 @@ #include "reg.h" #include <linux/stddef.h> #include <linux/kernel.h> +#include <linux/io.h> /* * Size factor for isochronous DBR buffer. @@ -143,13 +144,13 @@ static void free_dbr(int offs, int size) static void dim2_transfer_madr(u32 val) { - dimcb_io_write(&g.dim2->MADR, val); + writel(val, &g.dim2->MADR); /* wait for transfer completion */ - while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1) + while ((readl(&g.dim2->MCTL) & 1) != 1) continue; - dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ + writel(0, &g.dim2->MCTL); /* clear transfer complete */ } static void dim2_clear_dbr(u16 addr, u16 size) @@ -159,8 +160,8 @@ static void dim2_clear_dbr(u16 addr, u16 size) u16 const end_addr = addr + size; u32 const cmd = bit_mask(MADR_WNR_BIT) | bit_mask(MADR_TB_BIT); - dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ - dimcb_io_write(&g.dim2->MDAT0, 0); + writel(0, &g.dim2->MCTL); /* clear transfer complete */ + writel(0, &g.dim2->MDAT0); for (; addr < end_addr; addr++) dim2_transfer_madr(cmd | addr); @@ -170,28 +171,28 @@ static u32 dim2_read_ctr(u32 ctr_addr, u16 mdat_idx) { dim2_transfer_madr(ctr_addr); - return dimcb_io_read((&g.dim2->MDAT0) + mdat_idx); + return readl((&g.dim2->MDAT0) + mdat_idx); } static void dim2_write_ctr_mask(u32 ctr_addr, const u32 *mask, const u32 *value) { enum { MADR_WNR_BIT = 31 }; - dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */ + writel(0, &g.dim2->MCTL); /* clear transfer complete */ if (mask[0] != 0) - dimcb_io_write(&g.dim2->MDAT0, value[0]); + writel(value[0], &g.dim2->MDAT0); if (mask[1] != 0) - dimcb_io_write(&g.dim2->MDAT1, value[1]); + writel(value[1], &g.dim2->MDAT1); if (mask[2] != 0) - dimcb_io_write(&g.dim2->MDAT2, value[2]); + writel(value[2], &g.dim2->MDAT2); if (mask[3] != 0) - dimcb_io_write(&g.dim2->MDAT3, value[3]); + writel(value[3], &g.dim2->MDAT3); - dimcb_io_write(&g.dim2->MDWE0, mask[0]); - dimcb_io_write(&g.dim2->MDWE1, mask[1]); - dimcb_io_write(&g.dim2->MDWE2, mask[2]); - dimcb_io_write(&g.dim2->MDWE3, mask[3]); + writel(mask[0], &g.dim2->MDWE0); + writel(mask[1], &g.dim2->MDWE1); + writel(mask[2], &g.dim2->MDWE2); + writel(mask[3], &g.dim2->MDWE3); dim2_transfer_madr(bit_mask(MADR_WNR_BIT) | ctr_addr); } @@ -356,15 +357,13 @@ static void dim2_configure_channel( dim2_configure_cat(AHB_CAT, ch_addr, type, is_tx ? 0 : 1); /* unmask interrupt for used channel, enable mlb_sys_int[0] interrupt */ - dimcb_io_write(&g.dim2->ACMR0, - dimcb_io_read(&g.dim2->ACMR0) | bit_mask(ch_addr)); + writel(readl(&g.dim2->ACMR0) | bit_mask(ch_addr), &g.dim2->ACMR0); } static void dim2_clear_channel(u8 ch_addr) { /* mask interrupt for used channel, disable mlb_sys_int[0] interrupt */ - dimcb_io_write(&g.dim2->ACMR0, - dimcb_io_read(&g.dim2->ACMR0) & ~bit_mask(ch_addr)); + writel(readl(&g.dim2->ACMR0) & ~bit_mask(ch_addr), &g.dim2->ACMR0); dim2_clear_cat(AHB_CAT, ch_addr); dim2_clear_adt(ch_addr); @@ -373,7 +372,7 @@ static void dim2_clear_channel(u8 ch_addr) dim2_clear_cdt(ch_addr); /* clear channel status bit */ - dimcb_io_write(&g.dim2->ACSR0, bit_mask(ch_addr)); + writel(bit_mask(ch_addr), &g.dim2->ACSR0); } /* -------------------------------------------------------------------------- */ @@ -471,7 +470,7 @@ static inline bool check_bytes_per_frame(u32 bytes_per_frame) return true; } -static inline u16 norm_ctrl_async_buffer_size(u16 buf_size) +u16 dim_norm_ctrl_async_buffer_size(u16 buf_size) { u16 const max_size = (u16)ADT1_CTRL_ASYNC_BD_MASK + 1u; @@ -517,20 +516,20 @@ static inline u16 norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame) static void dim2_cleanup(void) { /* disable MediaLB */ - dimcb_io_write(&g.dim2->MLBC0, false << MLBC0_MLBEN_BIT); + writel(false << MLBC0_MLBEN_BIT, &g.dim2->MLBC0); dim2_clear_ctram(); /* disable mlb_int interrupt */ - dimcb_io_write(&g.dim2->MIEN, 0); + writel(0, &g.dim2->MIEN); /* clear status for all dma channels */ - dimcb_io_write(&g.dim2->ACSR0, 0xFFFFFFFF); - dimcb_io_write(&g.dim2->ACSR1, 0xFFFFFFFF); + writel(0xFFFFFFFF, &g.dim2->ACSR0); + writel(0xFFFFFFFF, &g.dim2->ACSR1); /* mask interrupts for all channels */ - dimcb_io_write(&g.dim2->ACMR0, 0); - dimcb_io_write(&g.dim2->ACMR1, 0); + writel(0, &g.dim2->ACMR0); + writel(0, &g.dim2->ACMR1); } static void dim2_initialize(bool enable_6pin, u8 mlb_clock) @@ -538,23 +537,22 @@ static void dim2_initialize(bool enable_6pin, u8 mlb_clock) dim2_cleanup(); /* configure and enable MediaLB */ - dimcb_io_write(&g.dim2->MLBC0, - enable_6pin << MLBC0_MLBPEN_BIT | - mlb_clock << MLBC0_MLBCLK_SHIFT | - g.fcnt << MLBC0_FCNT_SHIFT | - true << MLBC0_MLBEN_BIT); + writel(enable_6pin << MLBC0_MLBPEN_BIT | + mlb_clock << MLBC0_MLBCLK_SHIFT | + g.fcnt << MLBC0_FCNT_SHIFT | + true << MLBC0_MLBEN_BIT, + &g.dim2->MLBC0); /* activate all HBI channels */ - dimcb_io_write(&g.dim2->HCMR0, 0xFFFFFFFF); - dimcb_io_write(&g.dim2->HCMR1, 0xFFFFFFFF); + writel(0xFFFFFFFF, &g.dim2->HCMR0); + writel(0xFFFFFFFF, &g.dim2->HCMR1); /* enable HBI */ - dimcb_io_write(&g.dim2->HCTL, bit_mask(HCTL_EN_BIT)); + writel(bit_mask(HCTL_EN_BIT), &g.dim2->HCTL); /* configure DMA */ - dimcb_io_write(&g.dim2->ACTL, - ACTL_DMA_MODE_VAL_DMA_MODE_1 << ACTL_DMA_MODE_BIT | - true << ACTL_SCE_BIT); + writel(ACTL_DMA_MODE_VAL_DMA_MODE_1 << ACTL_DMA_MODE_BIT | + true << ACTL_SCE_BIT, &g.dim2->ACTL); } static bool dim2_is_mlb_locked(void) @@ -562,12 +560,12 @@ static bool dim2_is_mlb_locked(void) u32 const mask0 = bit_mask(MLBC0_MLBLK_BIT); u32 const mask1 = bit_mask(MLBC1_CLKMERR_BIT) | bit_mask(MLBC1_LOCKERR_BIT); - u32 const c1 = dimcb_io_read(&g.dim2->MLBC1); + u32 const c1 = readl(&g.dim2->MLBC1); u32 const nda_mask = (u32)MLBC1_NDA_MASK << MLBC1_NDA_SHIFT; - dimcb_io_write(&g.dim2->MLBC1, c1 & nda_mask); - return (dimcb_io_read(&g.dim2->MLBC1) & mask1) == 0 && - (dimcb_io_read(&g.dim2->MLBC0) & mask0) != 0; + writel(c1 & nda_mask, &g.dim2->MLBC1); + return (readl(&g.dim2->MLBC1) & mask1) == 0 && + (readl(&g.dim2->MLBC0) & mask0) != 0; } /* -------------------------------------------------------------------------- */ @@ -590,7 +588,7 @@ static inline bool service_channel(u8 ch_addr, u8 idx) dim2_write_ctr_mask(ADT + ch_addr, mask, adt_w); /* clear channel status bit */ - dimcb_io_write(&g.dim2->ACSR0, bit_mask(ch_addr)); + writel(bit_mask(ch_addr), &g.dim2->ACSR0); return true; } @@ -652,7 +650,7 @@ static bool channel_start(struct dim_channel *ch, u32 buf_addr, u16 buf_size) return dim_on_error(DIM_ERR_BAD_BUFFER_SIZE, "Bad buffer size"); if (ch->packet_length == 0 && ch->bytes_per_frame == 0 && - buf_size != norm_ctrl_async_buffer_size(buf_size)) + buf_size != dim_norm_ctrl_async_buffer_size(buf_size)) return dim_on_error(DIM_ERR_BAD_BUFFER_SIZE, "Bad control/async buffer size"); @@ -776,13 +774,8 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx, void dim_service_mlb_int_irq(void) { - dimcb_io_write(&g.dim2->MS0, 0); - dimcb_io_write(&g.dim2->MS1, 0); -} - -u16 dim_norm_ctrl_async_buffer_size(u16 buf_size) -{ - return norm_ctrl_async_buffer_size(buf_size); + writel(0, &g.dim2->MS0); + writel(0, &g.dim2->MS1); } /** @@ -829,7 +822,7 @@ u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address, if (is_tx && !g.atx_dbr.ch_addr) { g.atx_dbr.ch_addr = ch->addr; dbrcnt_init(ch->addr, ch->dbr_size); - dimcb_io_write(&g.dim2->MIEN, bit_mask(20)); + writel(bit_mask(20), &g.dim2->MIEN); } return ret; @@ -896,7 +889,7 @@ u8 dim_destroy_channel(struct dim_channel *ch) return DIM_ERR_DRIVER_NOT_INITIALIZED; if (ch->addr == g.atx_dbr.ch_addr) { - dimcb_io_write(&g.dim2->MIEN, 0); + writel(0, &g.dim2->MIEN); g.atx_dbr.ch_addr = 0; } diff --git a/drivers/staging/most/dim2/hal.h b/drivers/staging/most/dim2/hal.h index fca6c22de8a6..20531449acab 100644 --- a/drivers/staging/most/dim2/hal.h +++ b/drivers/staging/most/dim2/hal.h @@ -97,10 +97,6 @@ bool dim_enqueue_buffer(struct dim_channel *ch, u32 buffer_addr, bool dim_detach_buffers(struct dim_channel *ch, u16 buffers_number); -u32 dimcb_io_read(u32 __iomem *ptr32); - -void dimcb_io_write(u32 __iomem *ptr32, u32 value); - void dimcb_on_error(u8 error_id, const char *error_message); #endif /* _DIM2_HAL_H */ diff --git a/drivers/staging/most/net/net.c b/drivers/staging/most/net/net.c index aababdf2be12..26a31854c636 100644 --- a/drivers/staging/most/net/net.c +++ b/drivers/staging/most/net/net.c @@ -69,7 +69,7 @@ struct net_dev_context { static struct list_head net_devices = LIST_HEAD_INIT(net_devices); static struct mutex probe_disc_mt; /* ch->linked = true, most_nd_open */ -static struct spinlock list_lock; /* list_head, ch->linked = false, dev_hold */ +static DEFINE_SPINLOCK(list_lock); /* list_head, ch->linked = false, dev_hold */ static struct core_component comp; static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo) @@ -509,7 +509,6 @@ static int __init most_net_init(void) { int err; - spin_lock_init(&list_lock); mutex_init(&probe_disc_mt); err = most_register_component(&comp); if (err) diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c index 342f390d68b3..79817061fcfa 100644 --- a/drivers/staging/most/sound/sound.c +++ b/drivers/staging/most/sound/sound.c @@ -802,8 +802,11 @@ static int __init audio_init(void) if (ret) pr_err("Failed to register %s\n", comp.name); ret = most_register_configfs_subsys(&comp); - if (ret) + if (ret) { pr_err("Failed to register %s configfs subsys\n", comp.name); + most_deregister_component(&comp); + } + return ret; } diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c index 6f6e98ab0550..250af9fb704d 100644 --- a/drivers/staging/most/video/video.c +++ b/drivers/staging/most/video/video.c @@ -54,7 +54,7 @@ struct comp_fh { }; static struct list_head video_devices = LIST_HEAD_INIT(video_devices); -static struct spinlock list_lock; +static DEFINE_SPINLOCK(list_lock); static inline bool data_ready(struct most_video_dev *mdev) { @@ -538,7 +538,6 @@ static int __init comp_init(void) { int err; - spin_lock_init(&list_lock); err = most_register_component(&comp); if (err) return err; diff --git a/drivers/staging/mt7621-dma/mtk-hsdma.c b/drivers/staging/mt7621-dma/mtk-hsdma.c index 60db06768c8a..d964642d95a3 100644 --- a/drivers/staging/mt7621-dma/mtk-hsdma.c +++ b/drivers/staging/mt7621-dma/mtk-hsdma.c @@ -675,10 +675,8 @@ static int mtk_hsdma_probe(struct platform_device *pdev) tasklet_init(&hsdma->task, mtk_hsdma_tasklet, (unsigned long)hsdma); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get irq\n"); + if (irq < 0) return -EINVAL; - } ret = devm_request_irq(&pdev->dev, irq, mtk_hsdma_irq, 0, dev_name(&pdev->dev), hsdma); if (ret) { diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c index 89fa813142ab..6b98827da57f 100644 --- a/drivers/staging/mt7621-pci/pci-mt7621.c +++ b/drivers/staging/mt7621-pci/pci-mt7621.c @@ -400,6 +400,7 @@ static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) err = of_pci_get_devfn(child); if (err < 0) { + of_node_put(child); dev_err(dev, "failed to parse devfn: %d\n", err); return err; } @@ -407,8 +408,10 @@ static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) slot = PCI_SLOT(err); err = mt7621_pcie_parse_port(pcie, child, slot); - if (err) + if (err) { + of_node_put(child); return err; + } } return 0; @@ -614,17 +617,12 @@ static int mt7621_pcie_request_resources(struct mt7621_pcie *pcie, struct list_head *res) { struct device *dev = pcie->dev; - int err; pci_add_resource_offset(res, &pcie->io, pcie->offset.io); pci_add_resource_offset(res, &pcie->mem, pcie->offset.mem); pci_add_resource(res, &pcie->busn); - err = devm_request_pci_bus_resources(dev, res); - if (err < 0) - return err; - - return 0; + return devm_request_pci_bus_resources(dev, res); } static int mt7621_pcie_register_host(struct pci_host_bridge *host, diff --git a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c index 9b52d44abef1..d0f06790d38f 100644 --- a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c +++ b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c @@ -358,12 +358,15 @@ static int rt2880_pinmux_probe(struct platform_device *pdev) gpiobase = of_get_property(np, "ralink,gpio-base", NULL); if (!ngpio || !gpiobase) { dev_err(&pdev->dev, "failed to load chip info\n"); + of_node_put(np); return -EINVAL; } range = devm_kzalloc(p->dev, sizeof(*range), GFP_KERNEL); - if (!range) + if (!range) { + of_node_put(np); return -ENOMEM; + } range->name = "pio"; range->npins = __be32_to_cpu(*ngpio); range->base = __be32_to_cpu(*gpiobase); diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 08027a36e0bc..360ec0407740 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -767,7 +767,6 @@ static int tegra_nvec_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct nvec_chip *nvec; struct nvec_msg *msg; - struct resource *res; void __iomem *base; char get_firmware_version[] = { NVEC_CNTL, GET_FIRMWARE_VERSION }, unmute_speakers[] = { NVEC_OEM0, 0x10, 0x59, 0x95 }, @@ -790,16 +789,13 @@ static int tegra_nvec_probe(struct platform_device *pdev) return -ENODEV; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); nvec->irq = platform_get_irq(pdev, 0); - if (nvec->irq < 0) { - dev_err(dev, "no irq resource?\n"); + if (nvec->irq < 0) return -ENODEV; - } i2c_clk = devm_clk_get(dev, "div-clk"); if (IS_ERR(i2c_clk)) { diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 8847a11c212f..33762f2e9a44 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -794,7 +794,7 @@ static int cvm_oct_probe(struct platform_device *pdev) priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED; priv->port = CVMX_PIP_NUM_INPUT_PORTS; priv->queue = -1; - strcpy(dev->name, "pow%d"); + strscpy(dev->name, "pow%d", sizeof(dev->name)); for (qos = 0; qos < 16; qos++) skb_queue_head_init(&priv->tx_free_list[qos]); dev->min_mtu = VLAN_ETH_ZLEN - mtu_overhead; @@ -866,39 +866,39 @@ static int cvm_oct_probe(struct platform_device *pdev) case CVMX_HELPER_INTERFACE_MODE_NPI: dev->netdev_ops = &cvm_oct_npi_netdev_ops; - strcpy(dev->name, "npi%d"); + strscpy(dev->name, "npi%d", sizeof(dev->name)); break; case CVMX_HELPER_INTERFACE_MODE_XAUI: dev->netdev_ops = &cvm_oct_xaui_netdev_ops; - strcpy(dev->name, "xaui%d"); + strscpy(dev->name, "xaui%d", sizeof(dev->name)); break; case CVMX_HELPER_INTERFACE_MODE_LOOP: dev->netdev_ops = &cvm_oct_npi_netdev_ops; - strcpy(dev->name, "loop%d"); + strscpy(dev->name, "loop%d", sizeof(dev->name)); break; case CVMX_HELPER_INTERFACE_MODE_SGMII: priv->phy_mode = PHY_INTERFACE_MODE_SGMII; dev->netdev_ops = &cvm_oct_sgmii_netdev_ops; - strcpy(dev->name, "eth%d"); + strscpy(dev->name, "eth%d", sizeof(dev->name)); break; case CVMX_HELPER_INTERFACE_MODE_SPI: dev->netdev_ops = &cvm_oct_spi_netdev_ops; - strcpy(dev->name, "spi%d"); + strscpy(dev->name, "spi%d", sizeof(dev->name)); break; case CVMX_HELPER_INTERFACE_MODE_GMII: priv->phy_mode = PHY_INTERFACE_MODE_GMII; dev->netdev_ops = &cvm_oct_rgmii_netdev_ops; - strcpy(dev->name, "eth%d"); + strscpy(dev->name, "eth%d", sizeof(dev->name)); break; case CVMX_HELPER_INTERFACE_MODE_RGMII: dev->netdev_ops = &cvm_oct_rgmii_netdev_ops; - strcpy(dev->name, "eth%d"); + strscpy(dev->name, "eth%d", sizeof(dev->name)); cvm_set_rgmii_delay(priv, interface, port_index); break; diff --git a/drivers/staging/olpc_dcon/TODO b/drivers/staging/olpc_dcon/TODO index fe09efbc7f77..d8296f2ae872 100644 --- a/drivers/staging/olpc_dcon/TODO +++ b/drivers/staging/olpc_dcon/TODO @@ -8,10 +8,6 @@ TODO: internals, but isn't properly integrated, is not the correct solution. - see if vx855 gpio API can be made similar enough to cs5535 so we can share more code - - convert all uses of the old GPIO API from <linux/gpio.h> to the - GPIO descriptor API in <linux/gpio/consumer.h> and look up GPIO - lines from device tree, ACPI or board files, board files should - use <linux/gpio/machine.h> - allow simultaneous XO-1 and XO-1.5 support Please send patches to Greg Kroah-Hartman <greg@kroah.com> and diff --git a/drivers/staging/pi433/Documentation/pi433.txt b/drivers/staging/pi433/Documentation/pi433.txt index 21cffdb86ecf..4a0d34b4ad37 100644 --- a/drivers/staging/pi433/Documentation/pi433.txt +++ b/drivers/staging/pi433/Documentation/pi433.txt @@ -14,7 +14,7 @@ until something gets received terminates the read request. The driver supports on the fly reloading of the hardware fifo of the rf chip, thus enabling for much longer telegrams than the hardware fifo size. -Discription of driver operation +Description of driver operation =============================== a) transmission diff --git a/drivers/staging/ralink-gdma/ralink-gdma.c b/drivers/staging/ralink-gdma/ralink-gdma.c index 5854551d0a52..900424db9b97 100644 --- a/drivers/staging/ralink-gdma/ralink-gdma.c +++ b/drivers/staging/ralink-gdma/ralink-gdma.c @@ -826,10 +826,8 @@ static int gdma_dma_probe(struct platform_device *pdev) tasklet_init(&dma_dev->task, gdma_dma_tasklet, (unsigned long)dma_dev); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get irq\n"); + if (irq < 0) return -EINVAL; - } ret = devm_request_irq(&pdev->dev, irq, gdma_dma_irq, 0, dev_name(&pdev->dev), dma_dev); if (ret) { diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index a24b40761af2..815dfee11968 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -1200,7 +1200,7 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) rtw_indicate_connect(padapter); } else { - pwlan = _rtw_alloc_network(pmlmepriv); + pwlan = rtw_alloc_network(pmlmepriv); spin_lock_bh(&pmlmepriv->scanned_queue.lock); if (!pwlan) { pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 51c3dd6d7ffb..02c476f45b33 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -108,7 +108,7 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) /* 1. Read the first byte to check if efuse is empty!!! */ /* */ /* */ - rtemp8 = *(phymap+eFuse_Addr); + rtemp8 = *(phymap + eFuse_Addr); if (rtemp8 != 0xFF) { efuse_utilized++; eFuse_Addr++; @@ -124,10 +124,10 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) /* Check PG header for section num. */ if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */ u1temp = (rtemp8 & 0xE0) >> 5; - rtemp8 = *(phymap+eFuse_Addr); + rtemp8 = *(phymap + eFuse_Addr); if ((rtemp8 & 0x0F) == 0x0F) { eFuse_Addr++; - rtemp8 = *(phymap+eFuse_Addr); + rtemp8 = *(phymap + eFuse_Addr); if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) eFuse_Addr++; @@ -147,13 +147,13 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { /* Check word enable condition in the section */ if (!(wren & 0x01)) { - rtemp8 = *(phymap+eFuse_Addr); + rtemp8 = *(phymap + eFuse_Addr); eFuse_Addr++; efuse_utilized++; eFuseWord[offset][i] = (rtemp8 & 0xff); if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) break; - rtemp8 = *(phymap+eFuse_Addr); + rtemp8 = *(phymap + eFuse_Addr); eFuse_Addr++; efuse_utilized++; eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00); @@ -165,7 +165,7 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) } } /* Read next PG header */ - rtemp8 = *(phymap+eFuse_Addr); + rtemp8 = *(phymap + eFuse_Addr); if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { efuse_utilized++; @@ -178,8 +178,8 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) /* */ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) { for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { - efuseTbl[(i*8)+(j*2)] = (eFuseWord[i][j] & 0xff); - efuseTbl[(i*8)+((j*2)+1)] = ((eFuseWord[i][j] >> 8) & 0xff); + efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff); + efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff); } } @@ -187,7 +187,7 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) /* 4. Copy from Efuse map to output pointer memory!!! */ /* */ for (i = 0; i < _size_byte; i++) - pbuf[i] = efuseTbl[_offset+i]; + pbuf[i] = efuseTbl[_offset + i]; /* */ /* 5. Calculate Efuse utilization. */ @@ -218,16 +218,16 @@ static void efuse_read_phymap_from_txpktbuf( u8 *pos = content; if (bcnhead < 0) /* if not valid */ - bcnhead = usb_read8(adapter, REG_TDECTRL+1); + bcnhead = usb_read8(adapter, REG_TDECTRL + 1); DBG_88E("%s bcnhead:%d\n", __func__, bcnhead); usb_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); - dbg_addr = bcnhead*128/8; /* 8-bytes addressing */ + dbg_addr = bcnhead * 128 / 8; /* 8-bytes addressing */ while (1) { - usb_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr+i); + usb_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i); usb_write8(adapter, REG_TXPKTBUF_DBG, 0); start = jiffies; @@ -246,34 +246,34 @@ static void efuse_read_phymap_from_txpktbuf( u16 aaa; lenc[0] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L); - lenc[1] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L+1); + lenc[1] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L + 1); aaabak = le16_to_cpup((__le16 *)lenc); lenbak = le16_to_cpu(*((__le16 *)lenc)); aaa = le16_to_cpup((__le16 *)&lo32); len = le16_to_cpu(*((__le16 *)&lo32)); - limit = min_t(u16, len-2, limit); + limit = min_t(u16, len - 2, limit); DBG_88E("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __func__, len, lenbak, aaa, aaabak); - memcpy(pos, ((u8 *)&lo32)+2, (limit >= count+2) ? 2 : limit-count); - count += (limit >= count+2) ? 2 : limit-count; - pos = content+count; + memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count); + count += (limit >= count + 2) ? 2 : limit - count; + pos = content + count; } else { - memcpy(pos, ((u8 *)&lo32), (limit >= count+4) ? 4 : limit-count); - count += (limit >= count+4) ? 4 : limit-count; - pos = content+count; + memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count); + count += (limit >= count + 4) ? 4 : limit - count; + pos = content + count; } - if (limit > count && len-2 > count) { - memcpy(pos, (u8 *)&hi32, (limit >= count+4) ? 4 : limit-count); - count += (limit >= count+4) ? 4 : limit-count; - pos = content+count; + if (limit > count && len - 2 > count) { + memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count); + count += (limit >= count + 4) ? 4 : limit - count; + pos = content + count; } - if (limit <= count || len-2 <= count) + if (limit <= count || len - 2 <= count) break; i++; } @@ -288,7 +288,7 @@ static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset u8 physical_map[512]; u16 size = 512; - usb_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy); + usb_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy); memset(physical_map, 0xFF, 512); usb_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); status = iol_execute(padapter, CMD_READ_EFUSE_MAP); @@ -323,7 +323,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_e efuse_OneByteWrite(pAdapter, start_addr++, data[1]); efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0]); - efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[1]); + efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[1]); if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) badworden &= (~BIT(0)); } @@ -333,7 +333,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_e efuse_OneByteWrite(pAdapter, start_addr++, data[3]); efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[2]); - efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[3]); + efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[3]); if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) badworden &= (~BIT(1)); } @@ -343,7 +343,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_e efuse_OneByteWrite(pAdapter, start_addr++, data[5]); efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4]); - efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[5]); + efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[5]); if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) badworden &= (~BIT(2)); } @@ -353,7 +353,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_e efuse_OneByteWrite(pAdapter, start_addr++, data[7]); efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6]); - efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[7]); + efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[7]); if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) badworden &= (~BIT(3)); } @@ -371,7 +371,7 @@ static u16 Efuse_GetCurrentSize(struct adapter *pAdapter) while (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) && AVAILABLE_EFUSE_ADDR(efuse_addr)) { if (efuse_data != 0xFF) { - if ((efuse_data&0x1F) == 0x0F) { /* extended header */ + if ((efuse_data & 0x1F) == 0x0F) { /* extended header */ hoffset = efuse_data; efuse_addr++; efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data); @@ -383,12 +383,12 @@ static u16 Efuse_GetCurrentSize(struct adapter *pAdapter) hworden = efuse_data & 0x0F; } } else { - hoffset = (efuse_data>>4) & 0x0F; + hoffset = (efuse_data >> 4) & 0x0F; hworden = efuse_data & 0x0F; } word_cnts = Efuse_CalculateWordCnts(hworden); /* read next header */ - efuse_addr = efuse_addr + (word_cnts*2)+1; + efuse_addr = efuse_addr + (word_cnts * 2) + 1; } else { break; } @@ -439,15 +439,15 @@ int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data) continue; } } else { - hoffset = (efuse_data>>4) & 0x0F; + hoffset = (efuse_data >> 4) & 0x0F; hworden = efuse_data & 0x0F; } word_cnts = Efuse_CalculateWordCnts(hworden); bDataEmpty = true; if (hoffset == offset) { - for (tmpidx = 0; tmpidx < word_cnts*2; tmpidx++) { - if (efuse_OneByteRead(pAdapter, efuse_addr+1+tmpidx, &efuse_data)) { + for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { + if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx, &efuse_data)) { tmpdata[tmpidx] = efuse_data; if (efuse_data != 0xff) bDataEmpty = false; @@ -456,11 +456,11 @@ int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data) if (!bDataEmpty) { ReadState = PG_STATE_DATA; } else {/* read next header */ - efuse_addr = efuse_addr + (word_cnts*2)+1; + efuse_addr = efuse_addr + (word_cnts * 2) + 1; ReadState = PG_STATE_HEADER; } } else {/* read next header */ - efuse_addr = efuse_addr + (word_cnts*2)+1; + efuse_addr = efuse_addr + (word_cnts * 2) + 1; ReadState = PG_STATE_HEADER; } } else { @@ -469,7 +469,7 @@ int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data) } else if (ReadState & PG_STATE_DATA) { /* Data section Read ------------- */ efuse_WordEnableDataRead(hworden, tmpdata, data); - efuse_addr = efuse_addr + (word_cnts*2)+1; + efuse_addr = efuse_addr + (word_cnts * 2) + 1; ReadState = PG_STATE_HEADER; } } @@ -491,7 +491,7 @@ static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, st if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata)) { /* check if data exist */ - badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata); + badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata); if (badworden != 0xf) { /* write fail */ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata); @@ -501,10 +501,10 @@ static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, st else efuse_addr = Efuse_GetCurrentSize(pAdapter); } else { - efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1; + efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1; } } else { - efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1; + efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1; } *pAddr = efuse_addr; return true; @@ -601,7 +601,7 @@ static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuse } else { struct pgpkt fixPkt; - fixPkt.offset = (tmp_header>>4) & 0x0F; + fixPkt.offset = (tmp_header >> 4) & 0x0F; fixPkt.word_en = tmp_header & 0x0F; fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr)) @@ -619,7 +619,7 @@ static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u u32 PgWriteSuccess = 0; badworden = 0x0f; - badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data); + badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data); if (badworden == 0x0F) { /* write ok */ return true; @@ -681,8 +681,8 @@ static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, bool ret = false; u8 i, efuse_data; - for (i = 0; i < (word_cnts*2); i++) { - if (efuse_OneByteRead(pAdapter, (startAddr+i), &efuse_data) && (efuse_data != 0xFF)) + for (i = 0; i < (word_cnts * 2); i++) { + if (efuse_OneByteRead(pAdapter, (startAddr + i), &efuse_data) && (efuse_data != 0xFF)) ret = true; } return ret; @@ -721,7 +721,7 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u } } else { cur_header = efuse_data; - curPkt.offset = (cur_header>>4) & 0x0F; + curPkt.offset = (cur_header >> 4) & 0x0F; curPkt.word_en = cur_header & 0x0F; } @@ -729,10 +729,10 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u /* if same header is found but no data followed */ /* write some part of data followed by the header. */ if ((curPkt.offset == pTargetPkt->offset) && - (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr+1)) && + (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1)) && wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) { /* Here to write partial data */ - badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr+1, matched_wden, pTargetPkt->data); + badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data); if (badworden != 0x0F) { u32 PgWriteSuccess = 0; /* if write fail on some words, write these bad words again */ @@ -746,13 +746,13 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u } /* partial write ok, update the target packet for later use */ for (i = 0; i < 4; i++) { - if ((matched_wden & (0x1<<i)) == 0) /* this word has been written */ - pTargetPkt->word_en |= (0x1<<i); /* disable the word */ + if ((matched_wden & (0x1 << i)) == 0) /* this word has been written */ + pTargetPkt->word_en |= (0x1 << i); /* disable the word */ } pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); } /* read from next header */ - startAddr = startAddr + (curPkt.word_cnts*2) + 1; + startAddr = startAddr + (curPkt.word_cnts * 2) + 1; } else { /* not used header, 0xff */ *pAddr = startAddr; @@ -763,20 +763,9 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u return ret; } -static bool -hal_EfusePgCheckAvailableAddr( - struct adapter *pAdapter, - u8 efuseType - ) -{ - if (Efuse_GetCurrentSize(pAdapter) >= EFUSE_MAP_LEN_88E) - return false; - return true; -} - static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt) { - memset((void *)pTargetPkt->data, 0xFF, sizeof(u8)*8); + memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8); pTargetPkt->offset = offset; pTargetPkt->word_en = word_en; efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data); @@ -789,7 +778,7 @@ bool Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pD u16 startAddr = 0; u8 efuseType = EFUSE_WIFI; - if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType)) + if (Efuse_GetCurrentSize(pAdapter) >= EFUSE_MAP_LEN_88E) return false; hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); @@ -826,13 +815,13 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data) u8 tmpidx = 0; u8 result; - usb_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr & 0xff)); - usb_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) | - (usb_read8(pAdapter, EFUSE_CTRL+2) & 0xFC)); + usb_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); + usb_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | + (usb_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC)); - usb_write8(pAdapter, EFUSE_CTRL+3, 0x72);/* read cmd */ + usb_write8(pAdapter, EFUSE_CTRL + 3, 0x72);/* read cmd */ - while (!(0x80 & usb_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100)) + while (!(0x80 & usb_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) tmpidx++; if (tmpidx < 100) { *data = usb_read8(pAdapter, EFUSE_CTRL); @@ -849,15 +838,15 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data) u8 tmpidx = 0; u8 result; - usb_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff)); - usb_write8(pAdapter, EFUSE_CTRL+2, - (usb_read8(pAdapter, EFUSE_CTRL+2) & 0xFC) | - (u8)((addr>>8) & 0x03)); + usb_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); + usb_write8(pAdapter, EFUSE_CTRL + 2, + (usb_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) | + (u8)((addr >> 8) & 0x03)); usb_write8(pAdapter, EFUSE_CTRL, data);/* data */ - usb_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */ + usb_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */ - while ((0x80 & usb_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100)) + while ((0x80 & usb_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) tmpidx++; if (tmpidx < 100) diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index 28b3cdd10397..cc1b5438c04c 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -59,7 +59,7 @@ static u8 WIFI_OFDMRATES[] = { int rtw_get_bit_value_from_ieee_value(u8 val) { - unsigned char dot11_rate_table[] = { + static const unsigned char dot11_rate_table[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 0}; /* last element must be zero!! */ int i = 0; @@ -275,7 +275,7 @@ unsigned char *rtw_get_wpa_ie(unsigned char *pie, uint *wpa_ie_len, int limit) uint len; u16 val16; __le16 le_tmp; - unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; + static const unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; u8 *pbuf = pie; int limit_new = limit; diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index d2f7a88e992e..1ec3b237212e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -104,7 +104,7 @@ void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) } } -struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv) +struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) /* _queue *free_queue) */ { struct wlan_network *pnetwork; @@ -119,7 +119,7 @@ struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv) list_del_init(&pnetwork->list); RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, - ("_rtw_alloc_network: ptr=%p\n", &pnetwork->list)); + ("rtw_alloc_network: ptr=%p\n", &pnetwork->list)); pnetwork->network_type = 0; pnetwork->fixed = false; pnetwork->last_scanned = jiffies; @@ -272,11 +272,6 @@ u8 *rtw_get_beacon_interval_from_ie(u8 *ie) return ie + 8; } -static struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) -{ - return _rtw_alloc_network(pmlmepriv); -} - int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork) { int ret = true; @@ -827,7 +822,7 @@ void rtw_indicate_disconnect(struct adapter *padapter) inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) { - rtw_os_indicate_scan_done(padapter, aborted); + indicate_wx_scan_complete_event(padapter); } static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 6f3c03201f64..18dc9fc1c04a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -4854,7 +4854,7 @@ u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) } rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); - /* Set_NETYPE0_MSR(padapter, type); */ + /* Set_MSR(padapter, type); */ return H2C_SUCCESS; } diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 9caf7041ad60..d4278361e002 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -145,8 +145,8 @@ int rtw_free_recvframe(struct recv_frame *precvframe, int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue) { - list_del_init(&(precvframe->list)); - list_add_tail(&(precvframe->list), get_list_head(queue)); + list_del_init(&precvframe->list); + list_add_tail(&precvframe->list, get_list_head(queue)); return _SUCCESS; } @@ -219,7 +219,7 @@ static int recvframe_chkmic(struct adapter *adapter, struct security_priv *psecuritypriv = &adapter->securitypriv; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); @@ -1373,11 +1373,7 @@ static struct recv_frame *recvframe_defrag(struct adapter *adapter, /* append to first fragment frame's tail (if privacy frame, pull the ICV) */ skb_trim(prframe->pkt, prframe->pkt->len - prframe->attrib.icv_len); - /* memcpy */ - memcpy(skb_tail_pointer(prframe->pkt), pnfhdr->pkt->data, - pnfhdr->pkt->len); - - skb_put(prframe->pkt, pnfhdr->pkt->len); + skb_put_data(prframe->pkt, pnfhdr->pkt->data, pnfhdr->pkt->len); prframe->attrib.icv_len = pnfhdr->attrib.icv_len; plist = plist->next; @@ -1500,7 +1496,7 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) struct rx_pkt_attrib *pattrib; struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; struct recv_priv *precvpriv = &padapter->recvpriv; - struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue); + struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; nr_subframes = 0; pattrib = &prframe->attrib; diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index 2f90f60f1681..435c0fbec54a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -87,29 +87,28 @@ static u8 crc32_reverseBit(u8 data) static void crc32_init(void) { - if (bcrc32initialized == 1) { + int i, j; + u32 c; + u8 *p = (u8 *)&c, *p1; + u8 k; + + if (bcrc32initialized == 1) return; - } else { - int i, j; - u32 c; - u8 *p = (u8 *)&c, *p1; - u8 k; - - c = 0x12340000; - - for (i = 0; i < 256; ++i) { - k = crc32_reverseBit((u8)i); - for (c = ((u32)k) << 24, j = 8; j > 0; --j) - c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); - p1 = (u8 *)&crc32_table[i]; - - p1[0] = crc32_reverseBit(p[3]); - p1[1] = crc32_reverseBit(p[2]); - p1[2] = crc32_reverseBit(p[1]); - p1[3] = crc32_reverseBit(p[0]); - } - bcrc32initialized = 1; + + c = 0x12340000; + + for (i = 0; i < 256; ++i) { + k = crc32_reverseBit((u8)i); + for (c = ((u32)k) << 24, j = 8; j > 0; --j) + c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); + p1 = (u8 *)&crc32_table[i]; + + p1[0] = crc32_reverseBit(p[3]); + p1[1] = crc32_reverseBit(p[2]); + p1[2] = crc32_reverseBit(p[1]); + p1[3] = crc32_reverseBit(p[0]); } + bcrc32initialized = 1; } static __le32 getcrc32(u8 *buf, int len) diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 7bfc5b7c2757..c985b1468d41 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -270,14 +270,9 @@ void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable) rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode)); } -static void Set_NETYPE0_MSR(struct adapter *padapter, u8 type) -{ - rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type)); -} - void Set_MSR(struct adapter *padapter, u8 type) { - Set_NETYPE0_MSR(padapter, type); + rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type)); } inline u8 rtw_get_oper_ch(struct adapter *adapter) @@ -1179,15 +1174,10 @@ void Update_RA_Entry(struct adapter *padapter, u32 mac_id) rtw_hal_update_ra_mask(padapter, mac_id, 0); } -static void enable_rate_adaptive(struct adapter *padapter, u32 mac_id) -{ - Update_RA_Entry(padapter, mac_id); -} - void set_sta_rate(struct adapter *padapter, struct sta_info *psta) { /* rate adaptive */ - enable_rate_adaptive(padapter, psta->mac_id); + Update_RA_Entry(padapter, psta->mac_id); } /* Update RRSR and Rate for USERATE */ @@ -1476,8 +1466,3 @@ void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext) { rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, NULL); } - -void beacon_timing_control(struct adapter *padapter) -{ - rtw_hal_bcn_related_reg_setting(padapter); -} diff --git a/drivers/staging/rtl8188eu/hal/bb_cfg.c b/drivers/staging/rtl8188eu/hal/bb_cfg.c index 11e0bb9c67d7..51882858fcf0 100644 --- a/drivers/staging/rtl8188eu/hal/bb_cfg.c +++ b/drivers/staging/rtl8188eu/hal/bb_cfg.c @@ -653,7 +653,7 @@ static bool config_parafile(struct adapter *adapt) bool rtl88eu_phy_bb_config(struct adapter *adapt) { - int rtstatus = true; + bool rtstatus; u32 regval; u8 crystal_cap; diff --git a/drivers/staging/rtl8188eu/hal/rf_cfg.c b/drivers/staging/rtl8188eu/hal/rf_cfg.c index 02aeb12c9870..47b1bf5a6143 100644 --- a/drivers/staging/rtl8188eu/hal/rf_cfg.c +++ b/drivers/staging/rtl8188eu/hal/rf_cfg.c @@ -218,11 +218,11 @@ static bool rtl88e_phy_config_rf_with_headerfile(struct adapter *adapt) return true; } -static bool rf6052_conf_para(struct adapter *adapt) +bool rtl88eu_phy_rf_config(struct adapter *adapt) { struct hal_data_8188e *hal_data = adapt->HalData; u32 u4val = 0; - bool rtstatus = true; + bool rtstatus; struct bb_reg_def *pphyreg; pphyreg = &hal_data->PHYRegDef[RF90_PATH_A]; @@ -246,13 +246,3 @@ static bool rf6052_conf_para(struct adapter *adapt) return rtstatus; } - -static bool rtl88e_phy_rf6052_config(struct adapter *adapt) -{ - return rf6052_conf_para(adapt); -} - -bool rtl88eu_phy_rf_config(struct adapter *adapt) -{ - return rtl88e_phy_rf6052_config(adapt); -} diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index ac5552050752..16a57b31a439 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -183,14 +183,14 @@ static void _InitTxBufferBoundary(struct adapter *Adapter, u8 txpktbuf_bndy) usb_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); usb_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); usb_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy); - usb_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy); + usb_write8(Adapter, REG_TDECTRL + 1, txpktbuf_bndy); } static void _InitPageBoundary(struct adapter *Adapter) { /* RX Page Boundary */ /* */ - u16 rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E-1; + u16 rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E - 1; usb_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy); } @@ -504,7 +504,7 @@ static void usb_AggSettingRxUpdate(struct adapter *Adapter) switch (haldata->UsbRxAggMode) { case USB_RX_AGG_DMA: usb_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount); - usb_write8(Adapter, REG_RXDMA_AGG_PG_TH+1, haldata->UsbRxAggPageTimeout); + usb_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, haldata->UsbRxAggPageTimeout); break; case USB_RX_AGG_USB: usb_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount); @@ -512,7 +512,7 @@ static void usb_AggSettingRxUpdate(struct adapter *Adapter) break; case USB_RX_AGG_MIX: usb_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount); - usb_write8(Adapter, REG_RXDMA_AGG_PG_TH+1, (haldata->UsbRxAggPageTimeout & 0x1F));/* 0x280[12:8] */ + usb_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, (haldata->UsbRxAggPageTimeout & 0x1F));/* 0x280[12:8] */ usb_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount); usb_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout); break; @@ -569,9 +569,9 @@ static void _InitBeaconParameters(struct adapter *Adapter) haldata->RegBcnCtrlVal = usb_read8(Adapter, REG_BCN_CTRL); haldata->RegTxPause = usb_read8(Adapter, REG_TXPAUSE); - haldata->RegFwHwTxQCtrl = usb_read8(Adapter, REG_FWHW_TXQ_CTRL+2); - haldata->RegReg542 = usb_read8(Adapter, REG_TBTT_PROHIBIT+2); - haldata->RegCR_1 = usb_read8(Adapter, REG_CR+1); + haldata->RegFwHwTxQCtrl = usb_read8(Adapter, REG_FWHW_TXQ_CTRL + 2); + haldata->RegReg542 = usb_read8(Adapter, REG_TBTT_PROHIBIT + 2); + haldata->RegCR_1 = usb_read8(Adapter, REG_CR + 1); } static void _BeaconFunctionEnable(struct adapter *Adapter, @@ -579,7 +579,7 @@ static void _BeaconFunctionEnable(struct adapter *Adapter, { usb_write8(Adapter, REG_BCN_CTRL, (BIT(4) | BIT(3) | BIT(1))); - usb_write8(Adapter, REG_RD_CTRL+1, 0x6F); + usb_write8(Adapter, REG_RD_CTRL + 1, 0x6F); } /* Set CCK and OFDM Block "ON" */ @@ -633,7 +633,7 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt) DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8); rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on; } else { /* rf on/off */ - usb_write8(adapt, REG_MAC_PINMUX_CFG, usb_read8(adapt, REG_MAC_PINMUX_CFG)&~(BIT(3))); + usb_write8(adapt, REG_MAC_PINMUX_CFG, usb_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3))); val8 = usb_read8(adapt, REG_GPIO_IO_SEL); DBG_88E("GPIO_IN=%02x\n", val8); rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off; @@ -770,7 +770,7 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter) value8 = usb_read8(Adapter, REG_TX_RPT_CTRL); usb_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0))); /* Set MAX RPT MACID */ - usb_write8(Adapter, REG_TX_RPT_CTRL+1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */ + usb_write8(Adapter, REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */ /* Tx RPT Timer. Unit: 32us */ usb_write16(Adapter, REG_TX_RPT_TIME, 0xCdf0); @@ -827,10 +827,10 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter) pwrctrlpriv->rf_pwrstate = rf_on; /* enable Tx report. */ - usb_write8(Adapter, REG_FWHW_TXQ_CTRL+1, 0x0F); + usb_write8(Adapter, REG_FWHW_TXQ_CTRL + 1, 0x0F); /* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */ - usb_write8(Adapter, REG_EARLY_MODE_CONTROL+3, 0x01);/* Pretx_en, for WEP/TKIP SEC */ + usb_write8(Adapter, REG_EARLY_MODE_CONTROL + 3, 0x01);/* Pretx_en, for WEP/TKIP SEC */ /* tynli_test_tx_report. */ usb_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0); @@ -880,7 +880,7 @@ static void CardDisableRTL8188EU(struct adapter *Adapter) /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */ val8 = usb_read8(Adapter, REG_TX_RPT_CTRL); - usb_write8(Adapter, REG_TX_RPT_CTRL, val8&(~BIT(1))); + usb_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1))); /* stop rx */ usb_write8(Adapter, REG_CR, 0x0); @@ -894,9 +894,9 @@ static void CardDisableRTL8188EU(struct adapter *Adapter) val8 = usb_read8(Adapter, REG_MCUFWDL); if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */ /* Reset MCU 0x2[10]=0. */ - val8 = usb_read8(Adapter, REG_SYS_FUNC_EN+1); + val8 = usb_read8(Adapter, REG_SYS_FUNC_EN + 1); val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */ - usb_write8(Adapter, REG_SYS_FUNC_EN+1, val8); + usb_write8(Adapter, REG_SYS_FUNC_EN + 1, val8); } /* reset MCU ready status */ @@ -905,17 +905,17 @@ static void CardDisableRTL8188EU(struct adapter *Adapter) /* YJ,add,111212 */ /* Disable 32k */ val8 = usb_read8(Adapter, REG_32K_CTRL); - usb_write8(Adapter, REG_32K_CTRL, val8&(~BIT(0))); + usb_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0))); /* Card disable power action flow */ rtl88eu_pwrseqcmdparsing(Adapter, PWR_CUT_ALL_MSK, Rtl8188E_NIC_DISABLE_FLOW); /* Reset MCU IO Wrapper */ - val8 = usb_read8(Adapter, REG_RSV_CTRL+1); - usb_write8(Adapter, REG_RSV_CTRL+1, (val8&(~BIT(3)))); - val8 = usb_read8(Adapter, REG_RSV_CTRL+1); - usb_write8(Adapter, REG_RSV_CTRL+1, val8 | BIT(3)); + val8 = usb_read8(Adapter, REG_RSV_CTRL + 1); + usb_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3)))); + val8 = usb_read8(Adapter, REG_RSV_CTRL + 1); + usb_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3)); /* YJ,test add, 111207. For Power Consumption. */ val8 = usb_read8(Adapter, GPIO_IN); @@ -923,9 +923,9 @@ static void CardDisableRTL8188EU(struct adapter *Adapter) usb_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */ val8 = usb_read8(Adapter, REG_GPIO_IO_SEL); - usb_write8(Adapter, REG_GPIO_IO_SEL, (val8<<4)); - val8 = usb_read8(Adapter, REG_GPIO_IO_SEL+1); - usb_write8(Adapter, REG_GPIO_IO_SEL+1, val8|0x0F);/* Reg0x43 */ + usb_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4)); + val8 = usb_read8(Adapter, REG_GPIO_IO_SEL + 1); + usb_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */ usb_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */ Adapter->HalData->bMacPwrCtrlOn = false; Adapter->bFWReady = false; @@ -1103,11 +1103,11 @@ static void ResumeTxBeacon(struct adapter *adapt) /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ /* which should be read from register to a global variable. */ - usb_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl) | BIT(6)); + usb_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) | BIT(6)); haldata->RegFwHwTxQCtrl |= BIT(6); - usb_write8(adapt, REG_TBTT_PROHIBIT+1, 0xff); + usb_write8(adapt, REG_TBTT_PROHIBIT + 1, 0xff); haldata->RegReg542 |= BIT(0); - usb_write8(adapt, REG_TBTT_PROHIBIT+2, haldata->RegReg542); + usb_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542); } static void StopTxBeacon(struct adapter *adapt) @@ -1117,11 +1117,11 @@ static void StopTxBeacon(struct adapter *adapt) /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ /* which should be read from register to a global variable. */ - usb_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl) & (~BIT(6))); + usb_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) & (~BIT(6))); haldata->RegFwHwTxQCtrl &= (~BIT(6)); - usb_write8(adapt, REG_TBTT_PROHIBIT+1, 0x64); + usb_write8(adapt, REG_TBTT_PROHIBIT + 1, 0x64); haldata->RegReg542 &= ~(BIT(0)); - usb_write8(adapt, REG_TBTT_PROHIBIT+2, haldata->RegReg542); + usb_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542); /* todo: CheckFwRsvdPageContent(Adapter); 2010.06.23. Added by tynli. */ } @@ -1135,7 +1135,7 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val) usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL) | BIT(4)); /* set net_type */ - val8 = usb_read8(Adapter, MSR)&0x0c; + val8 = usb_read8(Adapter, MSR) & 0x0c; val8 |= mode; usb_write8(Adapter, MSR, val8); @@ -1176,7 +1176,7 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val) /* enable BCN0 Function for if1 */ /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */ - usb_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | BIT(1))); + usb_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1))); /* dis BCN1 ATIM WND if if2 is station */ usb_write8(Adapter, REG_BCN_CTRL_1, usb_read8(Adapter, REG_BCN_CTRL_1) | BIT(0)); @@ -1191,7 +1191,7 @@ static void hw_var_set_macaddr(struct adapter *Adapter, u8 variable, u8 *val) reg_macid = REG_MACID; for (idx = 0; idx < 6; idx++) - usb_write8(Adapter, (reg_macid+idx), val[idx]); + usb_write8(Adapter, (reg_macid + idx), val[idx]); } static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val) @@ -1202,7 +1202,7 @@ static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val) reg_bssid = REG_BSSID; for (idx = 0; idx < 6; idx++) - usb_write8(Adapter, (reg_bssid+idx), val[idx]); + usb_write8(Adapter, (reg_bssid + idx), val[idx]); } static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val) @@ -1214,7 +1214,7 @@ static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val) if (*((u8 *)val)) usb_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT)); else - usb_write8(Adapter, bcn_ctrl_reg, usb_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT))); + usb_write8(Adapter, bcn_ctrl_reg, usb_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT))); } void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) @@ -1228,7 +1228,7 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) { u8 val8; - val8 = usb_read8(Adapter, MSR)&0x0c; + val8 = usb_read8(Adapter, MSR) & 0x0c; val8 |= *((u8 *)val); usb_write8(Adapter, MSR, val8); } @@ -1274,8 +1274,8 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) BrateCfg |= 0x01; /* default enable 1M ACK rate */ /* Set RRSR rate table. */ usb_write8(Adapter, REG_RRSR, BrateCfg & 0xff); - usb_write8(Adapter, REG_RRSR+1, (BrateCfg >> 8) & 0xff); - usb_write8(Adapter, REG_RRSR+2, usb_read8(Adapter, REG_RRSR+2)&0xf0); + usb_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff); + usb_write8(Adapter, REG_RRSR + 2, usb_read8(Adapter, REG_RRSR + 2) & 0xf0); /* Set RTS initial rate */ while (BrateCfg > 0x1) { @@ -1298,27 +1298,27 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) - 1024; /* us */ + tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval * 1024)) - 1024; /* us */ - if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) StopTxBeacon(Adapter); /* disable related TSF function */ - usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(3))); + usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL) & (~BIT(3))); usb_write32(Adapter, REG_TSFTR, tsf); - usb_write32(Adapter, REG_TSFTR+4, tsf>>32); + usb_write32(Adapter, REG_TSFTR + 4, tsf >> 32); /* enable related TSF function */ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL) | BIT(3)); - if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) ResumeTxBeacon(Adapter); } break; case HW_VAR_CHECK_BSSID: if (*((u8 *)val)) { - usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN); + usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); } else { u32 val32; @@ -1357,19 +1357,19 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; if ((is_client_associated_to_ap(Adapter)) || - ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)) { + ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) { /* enable to rx data frame */ usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); /* enable update TSF */ - usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(4))); - } else if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { + usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); + } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); /* enable update TSF */ - usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(4))); + usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); } - usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN); + usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN); } break; case HW_VAR_MLME_JOIN: @@ -1382,7 +1382,7 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) /* enable to rx data frame.Accept all data frame */ usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); - usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN); + usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) RetryLimit = (haldata->CustomerID == RT_CID_CCX) ? 7 : 48; @@ -1394,9 +1394,9 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) } else if (type == 2) { /* sta add event call back */ /* enable update TSF */ - usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(4))); + usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) RetryLimit = 0x7; } usb_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT); @@ -1432,21 +1432,21 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) case HW_VAR_RESP_SIFS: /* RESP_SIFS for CCK */ usb_write8(Adapter, REG_R2T_SIFS, val[0]); /* SIFS_T2T_CCK (0x08) */ - usb_write8(Adapter, REG_R2T_SIFS+1, val[1]); /* SIFS_R2T_CCK(0x08) */ + usb_write8(Adapter, REG_R2T_SIFS + 1, val[1]); /* SIFS_R2T_CCK(0x08) */ /* RESP_SIFS for OFDM */ usb_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */ - usb_write8(Adapter, REG_T2T_SIFS+1, val[3]); /* SIFS_R2T_OFDM(0x0a) */ + usb_write8(Adapter, REG_T2T_SIFS + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */ break; case HW_VAR_ACK_PREAMBLE: { u8 regTmp; u8 bShortPreamble = *((bool *)val); /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */ - regTmp = (haldata->nCur40MhzPrimeSC)<<5; + regTmp = (haldata->nCur40MhzPrimeSC) << 5; if (bShortPreamble) regTmp |= 0x80; - usb_write8(Adapter, REG_RRSR+2, regTmp); + usb_write8(Adapter, REG_RRSR + 2, regTmp); } break; case HW_VAR_SEC_CFG: @@ -1480,12 +1480,13 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) for (i = 0; i < CAM_CONTENT_COUNT; i++) { /* filled id in CAM config 2 byte */ if (i == 0) - ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2); + ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2); else ulContent = 0; /* polling bit, and No Write enable, and address */ - ulCommand = CAM_CONTENT_COUNT*ucIndex+i; - ulCommand = ulCommand | CAM_POLLINIG|CAM_WRITE; + ulCommand = CAM_CONTENT_COUNT * ucIndex + i; + ulCommand = ulCommand | CAM_POLLINIG | + CAM_WRITE; /* write content 0 is equall to mark invalid */ usb_write32(Adapter, WCAMI, ulContent); /* delay_ms(40); */ usb_write32(Adapter, RWCAM, ulCommand); /* delay_ms(40); */ @@ -1589,13 +1590,13 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) FactorToSet = 0xf; for (index = 0; index < 4; index++) { - if ((pRegToSet[index] & 0xf0) > (FactorToSet<<4)) - pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet<<4); + if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4)) + pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4); if ((pRegToSet[index] & 0x0f) > FactorToSet) pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet); - usb_write8(Adapter, (REG_AGGLEN_LMT+index), pRegToSet[index]); + usb_write8(Adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]); } } } @@ -1681,9 +1682,9 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) if (!pwrpriv->bkeepfwalive) { /* RX DMA stop */ - usb_write32(Adapter, REG_RXPKT_NUM, (usb_read32(Adapter, REG_RXPKT_NUM)|RW_RELEASE_EN)); + usb_write32(Adapter, REG_RXPKT_NUM, (usb_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN)); do { - if (!(usb_read32(Adapter, REG_RXPKT_NUM)&RXDMA_IDLE)) + if (!(usb_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) break; } while (trycnt--); if (trycnt == 0) @@ -1706,8 +1707,8 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) { u8 maxMacid = *val; - DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid+1); - usb_write8(Adapter, REG_TX_RPT_CTRL+1, maxMacid+1); + DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1); + usb_write8(Adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1); } break; case HW_VAR_H2C_MEDIA_STATUS_RPT: @@ -1715,7 +1716,7 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val) break; case HW_VAR_BCN_VALID: /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */ - usb_write8(Adapter, REG_TDECTRL+2, usb_read8(Adapter, REG_TDECTRL+2) | BIT(0)); + usb_write8(Adapter, REG_TDECTRL + 2, usb_read8(Adapter, REG_TDECTRL + 2) | BIT(0)); break; default: break; @@ -1733,7 +1734,7 @@ void rtw_hal_get_hwreg(struct adapter *Adapter, u8 variable, u8 *val) break; case HW_VAR_BCN_VALID: /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */ - val[0] = (BIT(0) & usb_read8(Adapter, REG_TDECTRL+2)) ? true : false; + val[0] = (BIT(0) & usb_read8(Adapter, REG_TDECTRL + 2)) ? true : false; break; case HW_VAR_FWLPS_RF_ON: { @@ -1764,7 +1765,7 @@ void rtw_hal_get_hwreg(struct adapter *Adapter, u8 variable, u8 *val) *val = Adapter->HalData->bMacPwrCtrlOn; break; case HW_VAR_CHK_HI_QUEUE_EMPTY: - *val = ((usb_read32(Adapter, REG_HGQ_INFORMATION)&0x0000ff00) == 0) ? true : false; + *val = ((usb_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false; break; default: break; @@ -1888,7 +1889,7 @@ void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level) if (mac_id >= NUM_STA) /* CAM_SIZE */ return; psta = pmlmeinfo->FW_sta_info[mac_id].psta; - if (psta == NULL) + if (!psta) return; switch (mac_id) { case 0:/* for infra mode */ @@ -1925,7 +1926,7 @@ void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level) mask &= rate_bitmap; - init_rate = get_highest_rate_idx(mask)&0x3f; + init_rate = get_highest_rate_idx(mask) & 0x3f; ODM_RA_UpdateRateInfo_8188E(odmpriv, mac_id, raid, mask, shortGIrate); @@ -1934,7 +1935,7 @@ void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level) psta->init_rate = init_rate; } -void rtw_hal_bcn_related_reg_setting(struct adapter *adapt) +void beacon_timing_control(struct adapter *adapt) { u32 value32; struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; diff --git a/drivers/staging/rtl8188eu/include/hal8188e_phy_reg.h b/drivers/staging/rtl8188eu/include/hal8188e_phy_reg.h index 53afcea21c96..bd915a1f2511 100644 --- a/drivers/staging/rtl8188eu/include/hal8188e_phy_reg.h +++ b/drivers/staging/rtl8188eu/include/hal8188e_phy_reg.h @@ -16,55 +16,10 @@ /* 5. Other definition for BB/RF R/W */ /* */ - -/* */ -/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ -/* 1. Page1(0x100) */ -/* */ -#define rPMAC_Reset 0x100 -#define rPMAC_TxStart 0x104 -#define rPMAC_TxLegacySIG 0x108 -#define rPMAC_TxHTSIG1 0x10c -#define rPMAC_TxHTSIG2 0x110 -#define rPMAC_PHYDebug 0x114 -#define rPMAC_TxPacketNum 0x118 -#define rPMAC_TxIdle 0x11c -#define rPMAC_TxMACHeader0 0x120 -#define rPMAC_TxMACHeader1 0x124 -#define rPMAC_TxMACHeader2 0x128 -#define rPMAC_TxMACHeader3 0x12c -#define rPMAC_TxMACHeader4 0x130 -#define rPMAC_TxMACHeader5 0x134 -#define rPMAC_TxDataType 0x138 -#define rPMAC_TxRandomSeed 0x13c -#define rPMAC_CCKPLCPPreamble 0x140 -#define rPMAC_CCKPLCPHeader 0x144 -#define rPMAC_CCKCRC16 0x148 -#define rPMAC_OFDMRxCRC32OK 0x170 -#define rPMAC_OFDMRxCRC32Er 0x174 -#define rPMAC_OFDMRxParityEr 0x178 -#define rPMAC_OFDMRxCRC8Er 0x17c -#define rPMAC_CCKCRxRC16Er 0x180 -#define rPMAC_CCKCRxRC32Er 0x184 -#define rPMAC_CCKCRxRC32OK 0x188 -#define rPMAC_TxStatus 0x18c - -/* 2. Page2(0x200) */ -/* The following two definition are only used for USB interface. */ -#define RF_BB_CMD_ADDR 0x02c0 /* RF/BB r/w cmd address. */ -#define RF_BB_CMD_DATA 0x02c4 /* RF/BB r/w cmd data. */ - /* 3. Page8(0x800) */ #define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC RF BW Setting */ - -#define rFPGA0_TxInfo 0x804 /* Status report?? */ -#define rFPGA0_PSDFunction 0x808 - #define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */ -#define rFPGA0_RFTiming1 0x810 /* Useless now */ -#define rFPGA0_RFTiming2 0x814 - #define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */ #define rFPGA0_XA_HSSIParameter2 0x824 #define rFPGA0_XB_HSSIParameter1 0x828 @@ -73,9 +28,6 @@ #define rFPGA0_XA_LSSIParameter 0x840 #define rFPGA0_XB_LSSIParameter 0x844 -#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */ -#define rFPGA0_RFSleepUpParameter 0x854 - #define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */ #define rFPGA0_XCD_SwitchControl 0x85c @@ -86,181 +38,63 @@ #define rFPGA0_XCD_RFInterfaceSW 0x874 #define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */ -#define rFPGA0_XCD_RFParameter 0x87c - -/* Crystal cap setting RF-R/W protection for parameter4?? */ -#define rFPGA0_AnalogParameter1 0x880 -#define rFPGA0_AnalogParameter2 0x884 -#define rFPGA0_AnalogParameter3 0x888 -/* enable ad/da clock1 for dual-phy */ -#define rFPGA0_AdDaClockEn 0x888 -#define rFPGA0_AnalogParameter4 0x88c #define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */ #define rFPGA0_XB_LSSIReadBack 0x8a4 -#define rFPGA0_XC_LSSIReadBack 0x8a8 -#define rFPGA0_XD_LSSIReadBack 0x8ac -#define rFPGA0_PSDReport 0x8b4 /* Useless now */ -/* Transceiver A HSPI Readback */ #define TransceiverA_HSPI_Readback 0x8b8 -/* Transceiver B HSPI Readback */ #define TransceiverB_HSPI_Readback 0x8bc -/* Useless now RF Interface Readback Value */ #define rFPGA0_XAB_RFInterfaceRB 0x8e0 -#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */ /* 4. Page9(0x900) */ /* RF mode & OFDM TxSC RF BW Setting?? */ #define rFPGA1_RFMOD 0x900 -#define rFPGA1_TxBlock 0x904 /* Useless now */ -#define rFPGA1_DebugSelect 0x908 /* Useless now */ -#define rFPGA1_TxInfo 0x90c /* Useless now Status report */ - /* 5. PageA(0xA00) */ /* Set Control channel to upper or lower - required only for 40MHz */ #define rCCK0_System 0xa00 -/* Disable init gain now Select RX path by RSSI */ -#define rCCK0_AFESetting 0xa04 -/* Disable init gain now Init gain */ -#define rCCK0_CCA 0xa08 - -/* AGC default value, saturation level Antenna Diversity, RX AGC, LNA Threshold, - * RX LNA Threshold useless now. Not the same as 90 series - */ -#define rCCK0_RxAGC1 0xa0c -#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ - -#define rCCK0_RxHP 0xa14 - -/* Timing recovery & Channel estimation threshold */ -#define rCCK0_DSPParameter1 0xa18 -#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ - -#define rCCK0_TxFilter1 0xa20 -#define rCCK0_TxFilter2 0xa24 -#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ -#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now */ -#define rCCK0_TRSSIReport 0xa50 -#define rCCK0_RxReport 0xa54 /* 0xa57 */ -#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ -#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ - /* */ /* PageB(0xB00) */ /* */ -#define rPdp_AntA 0xb00 -#define rPdp_AntA_4 0xb04 -#define rConfig_Pmpd_AntA 0xb28 #define rConfig_AntA 0xb68 #define rConfig_AntB 0xb6c -#define rPdp_AntB 0xb70 -#define rPdp_AntB_4 0xb74 -#define rConfig_Pmpd_AntB 0xb98 -#define rAPK 0xbd8 /* */ /* 6. PageC(0xC00) */ /* */ -#define rOFDM0_LSTF 0xc00 - #define rOFDM0_TRxPathEnable 0xc04 #define rOFDM0_TRMuxPar 0xc08 -#define rOFDM0_TRSWIsolation 0xc0c /* RxIQ DC offset, Rx digital filter, DC notch filter */ #define rOFDM0_XARxAFE 0xc10 #define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imbalance matrix */ #define rOFDM0_XBRxAFE 0xc18 #define rOFDM0_XBRxIQImbalance 0xc1c -#define rOFDM0_XCRxAFE 0xc20 -#define rOFDM0_XCRxIQImbalance 0xc24 -#define rOFDM0_XDRxAFE 0xc28 -#define rOFDM0_XDRxIQImbalance 0xc2c - -#define rOFDM0_RxDetector1 0xc30 /*PD,BW & SBD DM tune init gain*/ -#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */ -#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */ -#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & Short-GI */ #define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ -#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ -#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ #define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ #define rOFDM0_XAAGCCore1 0xc50 /* DIG */ #define rOFDM0_XAAGCCore2 0xc54 #define rOFDM0_XBAGCCore1 0xc58 #define rOFDM0_XBAGCCore2 0xc5c -#define rOFDM0_XCAGCCore1 0xc60 -#define rOFDM0_XCAGCCore2 0xc64 -#define rOFDM0_XDAGCCore1 0xc68 -#define rOFDM0_XDAGCCore2 0xc6c -#define rOFDM0_AGCParameter1 0xc70 -#define rOFDM0_AGCParameter2 0xc74 #define rOFDM0_AGCRSSITable 0xc78 -#define rOFDM0_HTSTFAGC 0xc7c #define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */ #define rOFDM0_XATxAFE 0xc84 #define rOFDM0_XBTxIQImbalance 0xc88 #define rOFDM0_XBTxAFE 0xc8c -#define rOFDM0_XCTxIQImbalance 0xc90 #define rOFDM0_XCTxAFE 0xc94 -#define rOFDM0_XDTxIQImbalance 0xc98 #define rOFDM0_XDTxAFE 0xc9c #define rOFDM0_RxIQExtAnta 0xca0 -#define rOFDM0_TxCoeff1 0xca4 -#define rOFDM0_TxCoeff2 0xca8 -#define rOFDM0_TxCoeff3 0xcac -#define rOFDM0_TxCoeff4 0xcb0 -#define rOFDM0_TxCoeff5 0xcb4 -#define rOFDM0_TxCoeff6 0xcb8 -#define rOFDM0_RxHPParameter 0xce0 -#define rOFDM0_TxPseudoNoiseWgt 0xce4 -#define rOFDM0_FrameSync 0xcf0 -#define rOFDM0_DFSReport 0xcf4 - /* */ /* 7. PageD(0xD00) */ /* */ #define rOFDM1_LSTF 0xd00 -#define rOFDM1_TRxPathEnable 0xd04 - -#define rOFDM1_CFO 0xd08 /* No setting now */ -#define rOFDM1_CSI1 0xd10 -#define rOFDM1_SBD 0xd14 -#define rOFDM1_CSI2 0xd18 -#define rOFDM1_CFOTracking 0xd2c -#define rOFDM1_TRxMesaure1 0xd34 -#define rOFDM1_IntfDet 0xd3c -#define rOFDM1_PseudoNoiseStateAB 0xd50 -#define rOFDM1_PseudoNoiseStateCD 0xd54 -#define rOFDM1_RxPseudoNoiseWgt 0xd58 - -#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ -#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ -#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ - -#define rOFDM_ShortCFOAB 0xdac /* No setting now */ -#define rOFDM_ShortCFOCD 0xdb0 -#define rOFDM_LongCFOAB 0xdb4 -#define rOFDM_LongCFOCD 0xdb8 -#define rOFDM_TailCFOAB 0xdbc -#define rOFDM_TailCFOCD 0xdc0 -#define rOFDM_PWMeasure1 0xdc4 -#define rOFDM_PWMeasure2 0xdc8 -#define rOFDM_BWReport 0xdcc -#define rOFDM_AGCReport 0xdd0 -#define rOFDM_RxSNR 0xdd4 -#define rOFDM_RxEVMCSI 0xdd8 -#define rOFDM_SIGReport 0xddc - /* */ /* 8. PageE(0xE00) */ @@ -292,10 +126,6 @@ #define rRx_IQK 0xe44 #define rIQK_AGC_Pts 0xe48 #define rIQK_AGC_Rsp 0xe4c -#define rTx_IQK_Tone_B 0xe50 -#define rRx_IQK_Tone_B 0xe54 -#define rTx_IQK_PI_B 0xe58 -#define rRx_IQK_PI_B 0xe5c #define rIQK_AGC_Cont 0xe60 #define rBlue_Tooth 0xe6c @@ -311,17 +141,13 @@ #define rTx_Power_Before_IQK_A 0xe94 #define rTx_Power_After_IQK_A 0xe9c -#define rRx_Power_Before_IQK_A 0xea0 #define rRx_Power_Before_IQK_A_2 0xea4 -#define rRx_Power_After_IQK_A 0xea8 #define rRx_Power_After_IQK_A_2 0xeac #define rTx_Power_Before_IQK_B 0xeb4 #define rTx_Power_After_IQK_B 0xebc -#define rRx_Power_Before_IQK_B 0xec0 #define rRx_Power_Before_IQK_B_2 0xec4 -#define rRx_Power_After_IQK_B 0xec8 #define rRx_Power_After_IQK_B_2 0xecc #define rRx_OFDM 0xed0 @@ -332,751 +158,44 @@ #define rPMPD_ANAEN 0xeec /* */ -/* 7. RF Register 0x00-0x2E (RF 8256) */ -/* RF-0222D 0x00-3F */ -/* */ -/* Zebra1 */ -#define rZebra1_HSSIEnable 0x0 /* Useless now */ -#define rZebra1_TRxEnable1 0x1 -#define rZebra1_TRxEnable2 0x2 -#define rZebra1_AGC 0x4 -#define rZebra1_ChargePump 0x5 -#define rZebra1_Channel 0x7 /* RF channel switch */ - -/* endif */ -#define rZebra1_TxGain 0x8 /* Useless now */ -#define rZebra1_TxLPF 0x9 -#define rZebra1_RxLPF 0xb -#define rZebra1_RxHPFCorner 0xc - -/* Zebra4 */ -#define rGlobalCtrl 0 /* Useless now */ -#define rRTL8256_TxLPF 19 -#define rRTL8256_RxLPF 11 - -/* RTL8258 */ -#define rRTL8258_TxLPF 0x11 /* Useless now */ -#define rRTL8258_RxLPF 0x13 -#define rRTL8258_RSSILPF 0xa - -/* */ /* RL6052 Register definition */ /* */ #define RF_AC 0x00 /* */ - -#define RF_IQADJ_G1 0x01 /* */ -#define RF_IQADJ_G2 0x02 /* */ - -#define RF_POW_TRSW 0x05 /* */ - -#define RF_GAIN_RX 0x06 /* */ -#define RF_GAIN_TX 0x07 /* */ - -#define RF_TXM_IDAC 0x08 /* */ -#define RF_IPA_G 0x09 /* */ -#define RF_TXBIAS_G 0x0A -#define RF_TXPA_AG 0x0B -#define RF_IPA_A 0x0C /* */ -#define RF_TXBIAS_A 0x0D -#define RF_BS_PA_APSET_G9_G11 0x0E -#define RF_BS_IQGEN 0x0F /* */ - -#define RF_MODE1 0x10 /* */ -#define RF_MODE2 0x11 /* */ - -#define RF_RX_AGC_HP 0x12 /* */ -#define RF_TX_AGC 0x13 /* */ -#define RF_BIAS 0x14 /* */ -#define RF_IPA 0x15 /* */ -#define RF_TXBIAS 0x16 -#define RF_POW_ABILITY 0x17 /* */ #define RF_CHNLBW 0x18 /* RF channel and BW switch */ -#define RF_TOP 0x19 /* */ - -#define RF_RX_G1 0x1A /* */ -#define RF_RX_G2 0x1B /* */ - -#define RF_RX_BB2 0x1C /* */ -#define RF_RX_BB1 0x1D /* */ - -#define RF_RCK1 0x1E /* */ -#define RF_RCK2 0x1F /* */ - -#define RF_TX_G1 0x20 /* */ -#define RF_TX_G2 0x21 /* */ -#define RF_TX_G3 0x22 /* */ - -#define RF_TX_BB1 0x23 /* */ - -#define RF_T_METER_92D 0x42 /* */ #define RF_T_METER_88E 0x42 /* */ -#define RF_T_METER 0x24 /* */ - -#define RF_SYN_G1 0x25 /* RF TX Power control */ -#define RF_SYN_G2 0x26 /* RF TX Power control */ -#define RF_SYN_G3 0x27 /* RF TX Power control */ -#define RF_SYN_G4 0x28 /* RF TX Power control */ -#define RF_SYN_G5 0x29 /* RF TX Power control */ -#define RF_SYN_G6 0x2A /* RF TX Power control */ -#define RF_SYN_G7 0x2B /* RF TX Power control */ -#define RF_SYN_G8 0x2C /* RF TX Power control */ - #define RF_RCK_OS 0x30 /* RF TX PA control */ #define RF_TXPA_G1 0x31 /* RF TX PA control */ #define RF_TXPA_G2 0x32 /* RF TX PA control */ -#define RF_TXPA_G3 0x33 /* RF TX PA control */ -#define RF_TX_BIAS_A 0x35 -#define RF_TX_BIAS_D 0x36 -#define RF_LOBF_9 0x38 -#define RF_RXRF_A3 0x3C /* */ -#define RF_TRSW 0x3F - -#define RF_TXRF_A2 0x41 -#define RF_TXPA_G4 0x46 -#define RF_TXPA_A4 0x4B -#define RF_0x52 0x52 #define RF_WE_LUT 0xEF - /* */ /* Bit Mask */ /* */ -/* 1. Page1(0x100) */ -#define bBBResetB 0x100 /* Useless now? */ -#define bGlobalResetB 0x200 -#define bOFDMTxStart 0x4 -#define bCCKTxStart 0x8 -#define bCRC32Debug 0x100 -#define bPMACLoopback 0x10 -#define bTxLSIG 0xffffff -#define bOFDMTxRate 0xf -#define bOFDMTxReserved 0x10 -#define bOFDMTxLength 0x1ffe0 -#define bOFDMTxParity 0x20000 -#define bTxHTSIG1 0xffffff -#define bTxHTMCSRate 0x7f -#define bTxHTBW 0x80 -#define bTxHTLength 0xffff00 -#define bTxHTSIG2 0xffffff -#define bTxHTSmoothing 0x1 -#define bTxHTSounding 0x2 -#define bTxHTReserved 0x4 -#define bTxHTAggreation 0x8 -#define bTxHTSTBC 0x30 -#define bTxHTAdvanceCoding 0x40 -#define bTxHTShortGI 0x80 -#define bTxHTNumberHT_LTF 0x300 -#define bTxHTCRC8 0x3fc00 -#define bCounterReset 0x10000 -#define bNumOfOFDMTx 0xffff -#define bNumOfCCKTx 0xffff0000 -#define bTxIdleInterval 0xffff -#define bOFDMService 0xffff0000 -#define bTxMACHeader 0xffffffff -#define bTxDataInit 0xff -#define bTxHTMode 0x100 -#define bTxDataType 0x30000 -#define bTxRandomSeed 0xffffffff -#define bCCKTxPreamble 0x1 -#define bCCKTxSFD 0xffff0000 -#define bCCKTxSIG 0xff -#define bCCKTxService 0xff00 -#define bCCKLengthExt 0x8000 -#define bCCKTxLength 0xffff0000 -#define bCCKTxCRC16 0xffff -#define bCCKTxStatus 0x1 -#define bOFDMTxStatus 0x2 - -#define IS_BB_REG_OFFSET_92S(_Offset) \ - ((_Offset >= 0x800) && (_Offset <= 0xfff)) /* 2. Page8(0x800) */ #define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */ -#define bJapanMode 0x2 -#define bCCKTxSC 0x30 #define bCCKEn 0x1000000 #define bOFDMEn 0x2000000 -#define bOFDMRxADCPhase 0x10000 /* Useless now */ -#define bOFDMTxDACPhase 0x40000 -#define bXATxAGC 0x3f - -#define bAntennaSelect 0x0300 - -#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */ -#define bXCTxAGC 0xf000 -#define bXDTxAGC 0xf0000 - -#define bPAStart 0xf0000000 /* Useless now */ -#define bTRStart 0x00f00000 -#define bRFStart 0x0000f000 -#define bBBStart 0x000000f0 -#define bBBCCKStart 0x0000000f -#define bPAEnd 0xf /* Reg0x814 */ -#define bTREnd 0x0f000000 -#define bRFEnd 0x000f0000 -#define bCCAMask 0x000000f0 /* T2R */ -#define bR2RCCAMask 0x00000f00 -#define bHSSI_R2TDelay 0xf8000000 -#define bHSSI_T2RDelay 0xf80000 -#define bContTxHSSI 0x400 /* change gain at continue Tx */ -#define bIGFromCCK 0x200 -#define bAGCAddress 0x3f -#define bRxHPTx 0x7000 -#define bRxHPT2R 0x38000 -#define bRxHPCCKIni 0xc0000 -#define bAGCTxCode 0xc00000 -#define bAGCRxCode 0x300000 - -/* Reg 0x820~84f rFPGA0_XA_HSSIParameter1 */ -#define b3WireDataLength 0x800 -#define b3WireAddressLength 0x400 - -#define b3WireRFPowerDown 0x1 /* Useless now */ -#define b5GPAPEPolarity 0x40000000 -#define b2GPAPEPolarity 0x80000000 -#define bRFSW_TxDefaultAnt 0x3 -#define bRFSW_TxOptionAnt 0x30 -#define bRFSW_RxDefaultAnt 0x300 -#define bRFSW_RxOptionAnt 0x3000 -#define bRFSI_3WireData 0x1 -#define bRFSI_3WireClock 0x2 -#define bRFSI_3WireLoad 0x4 -#define bRFSI_3WireRW 0x8 -#define bRFSI_3Wire 0xf - -#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */ - -#define bRFSI_TRSW 0x20 /* Useless now */ -#define bRFSI_TRSWB 0x40 -#define bRFSI_ANTSW 0x100 -#define bRFSI_ANTSWB 0x200 -#define bRFSI_PAPE 0x400 -#define bRFSI_PAPE5G 0x800 -#define bBandSelect 0x1 -#define bHTSIG2_GI 0x80 -#define bHTSIG2_Smoothing 0x01 -#define bHTSIG2_Sounding 0x02 -#define bHTSIG2_Aggreaton 0x08 -#define bHTSIG2_STBC 0x30 -#define bHTSIG2_AdvCoding 0x40 -#define bHTSIG2_NumOfHTLTF 0x300 -#define bHTSIG2_CRC8 0x3fc -#define bHTSIG1_MCS 0x7f -#define bHTSIG1_BandWidth 0x80 -#define bHTSIG1_HTLength 0xffff -#define bLSIG_Rate 0xf -#define bLSIG_Reserved 0x10 -#define bLSIG_Length 0x1fffe -#define bLSIG_Parity 0x20 -#define bCCKRxPhase 0x4 - #define bLSSIReadAddress 0x7f800000 /* T65 RF */ - #define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ - #define bLSSIReadBackData 0xfffff /* T65 RF */ -#define bLSSIReadOKFlag 0x1000 /* Useless now */ -#define bCCKSampleRate 0x8 /* 0: 44MHz, 1:88MHz */ -#define bRegulator0Standby 0x1 -#define bRegulatorPLLStandby 0x2 -#define bRegulator1Standby 0x4 -#define bPLLPowerUp 0x8 -#define bDPLLPowerUp 0x10 -#define bDA10PowerUp 0x20 -#define bAD7PowerUp 0x200 -#define bDA6PowerUp 0x2000 -#define bXtalPowerUp 0x4000 -#define b40MDClkPowerUP 0x8000 -#define bDA6DebugMode 0x20000 -#define bDA6Swing 0x380000 - -/* Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */ -#define bADClkPhase 0x4000000 - -#define b80MClkDelay 0x18000000 /* Useless */ -#define bAFEWatchDogEnable 0x20000000 - -/* Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */ -#define bXtalCap01 0xc0000000 -#define bXtalCap23 0x3 -#define bXtalCap92x 0x0f000000 -#define bXtalCap 0x0f000000 - -#define bIntDifClkEnable 0x400 /* Useless */ -#define bExtSigClkEnable 0x800 -#define bBandgapMbiasPowerUp 0x10000 -#define bAD11SHGain 0xc0000 -#define bAD11InputRange 0x700000 -#define bAD11OPCurrent 0x3800000 -#define bIPathLoopback 0x4000000 -#define bQPathLoopback 0x8000000 -#define bAFELoopback 0x10000000 -#define bDA10Swing 0x7e0 -#define bDA10Reverse 0x800 -#define bDAClkSource 0x1000 -#define bAD7InputRange 0x6000 -#define bAD7Gain 0x38000 -#define bAD7OutputCMMode 0x40000 -#define bAD7InputCMMode 0x380000 -#define bAD7Current 0xc00000 -#define bRegulatorAdjust 0x7000000 -#define bAD11PowerUpAtTx 0x1 -#define bDA10PSAtTx 0x10 -#define bAD11PowerUpAtRx 0x100 -#define bDA10PSAtRx 0x1000 -#define bCCKRxAGCFormat 0x200 -#define bPSDFFTSamplepPoint 0xc000 -#define bPSDAverageNum 0x3000 -#define bIQPathControl 0xc00 -#define bPSDFreq 0x3ff -#define bPSDAntennaPath 0x30 -#define bPSDIQSwitch 0x40 -#define bPSDRxTrigger 0x400000 -#define bPSDTxTrigger 0x80000000 -#define bPSDSineToneScale 0x7f000000 -#define bPSDReport 0xffff - -/* 3. Page9(0x900) */ -#define bOFDMTxSC 0x30000000 /* Useless */ -#define bCCKTxOn 0x1 -#define bOFDMTxOn 0x2 -#define bDebugPage 0xfff /* reset debug page and HWord, LWord */ -#define bDebugItem 0xff /* reset debug page and LWord */ -#define bAntL 0x10 -#define bAntNonHT 0x100 -#define bAntHT1 0x1000 -#define bAntHT2 0x10000 -#define bAntHT1S1 0x100000 -#define bAntNonHTS1 0x1000000 - -/* 4. PageA(0xA00) */ -#define bCCKBBMode 0x3 /* Useless */ -#define bCCKTxPowerSaving 0x80 -#define bCCKRxPowerSaving 0x40 - #define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0_System 20/40 */ -#define bCCKScramble 0x8 /* Useless */ -#define bCCKAntDiversity 0x8000 -#define bCCKCarrierRecovery 0x4000 -#define bCCKTxRate 0x3000 -#define bCCKDCCancel 0x0800 -#define bCCKISICancel 0x0400 -#define bCCKMatchFilter 0x0200 -#define bCCKEqualizer 0x0100 -#define bCCKPreambleDetect 0x800000 -#define bCCKFastFalseCCA 0x400000 -#define bCCKChEstStart 0x300000 -#define bCCKCCACount 0x080000 -#define bCCKcs_lim 0x070000 -#define bCCKBistMode 0x80000000 -#define bCCKCCAMask 0x40000000 -#define bCCKTxDACPhase 0x4 -#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ -#define bCCKr_cp_mode0 0x0100 -#define bCCKTxDCOffset 0xf0 -#define bCCKRxDCOffset 0xf -#define bCCKCCAMode 0xc000 -#define bCCKFalseCS_lim 0x3f00 -#define bCCKCS_ratio 0xc00000 -#define bCCKCorgBit_sel 0x300000 -#define bCCKPD_lim 0x0f0000 -#define bCCKNewCCA 0x80000000 -#define bCCKRxHPofIG 0x8000 -#define bCCKRxIG 0x7f00 -#define bCCKLNAPolarity 0x800000 -#define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 /* CCK Rx Iinital gain polarity */ -#define bCCKRxAGCSatLevel 0x1f000000 -#define bCCKRxAGCSatCount 0xe0 -#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ -#define bCCKFixedRxAGC 0x8000 -#define bCCKAntennaPolarity 0x2000 -#define bCCKTxFilterType 0x0c00 -#define bCCKRxAGCReportType 0x0300 -#define bCCKRxDAGCEn 0x80000000 -#define bCCKRxDAGCPeriod 0x20000000 -#define bCCKRxDAGCSatLevel 0x1f000000 -#define bCCKTimingRecovery 0x800000 -#define bCCKTxC0 0x3f0000 -#define bCCKTxC1 0x3f000000 -#define bCCKTxC2 0x3f -#define bCCKTxC3 0x3f00 -#define bCCKTxC4 0x3f0000 -#define bCCKTxC5 0x3f000000 -#define bCCKTxC6 0x3f -#define bCCKTxC7 0x3f00 -#define bCCKDebugPort 0xff0000 -#define bCCKDACDebug 0x0f000000 -#define bCCKFalseAlarmEnable 0x8000 -#define bCCKFalseAlarmRead 0x4000 -#define bCCKTRSSI 0x7f -#define bCCKRxAGCReport 0xfe -#define bCCKRxReport_AntSel 0x80000000 -#define bCCKRxReport_MFOff 0x40000000 -#define bCCKRxRxReport_SQLoss 0x20000000 -#define bCCKRxReport_Pktloss 0x10000000 -#define bCCKRxReport_Lockedbit 0x08000000 -#define bCCKRxReport_RateError 0x04000000 -#define bCCKRxReport_RxRate 0x03000000 -#define bCCKRxFACounterLower 0xff -#define bCCKRxFACounterUpper 0xff000000 -#define bCCKRxHPAGCStart 0xe000 -#define bCCKRxHPAGCFinal 0x1c00 -#define bCCKRxFalseAlarmEnable 0x8000 -#define bCCKFACounterFreeze 0x4000 -#define bCCKTxPathSel 0x10000000 -#define bCCKDefaultRxPath 0xc000000 -#define bCCKOptionRxPath 0x3000000 - -/* 5. PageC(0xC00) */ -#define bNumOfSTF 0x3 /* Useless */ -#define bShift_L 0xc0 -#define bGI_TH 0xc -#define bRxPathA 0x1 -#define bRxPathB 0x2 -#define bRxPathC 0x4 -#define bRxPathD 0x8 -#define bTxPathA 0x1 -#define bTxPathB 0x2 -#define bTxPathC 0x4 -#define bTxPathD 0x8 -#define bTRSSIFreq 0x200 -#define bADCBackoff 0x3000 -#define bDFIRBackoff 0xc000 -#define bTRSSILatchPhase 0x10000 -#define bRxIDCOffset 0xff -#define bRxQDCOffset 0xff00 -#define bRxDFIRMode 0x1800000 -#define bRxDCNFType 0xe000000 -#define bRXIQImb_A 0x3ff -#define bRXIQImb_B 0xfc00 -#define bRXIQImb_C 0x3f0000 -#define bRXIQImb_D 0xffc00000 -#define bDC_dc_Notch 0x60000 -#define bRxNBINotch 0x1f000000 -#define bPD_TH 0xf -#define bPD_TH_Opt2 0xc000 -#define bPWED_TH 0x700 -#define bIfMF_Win_L 0x800 -#define bPD_Option 0x1000 -#define bMF_Win_L 0xe000 -#define bBW_Search_L 0x30000 -#define bwin_enh_L 0xc0000 -#define bBW_TH 0x700000 -#define bED_TH2 0x3800000 -#define bBW_option 0x4000000 -#define bRatio_TH 0x18000000 -#define bWindow_L 0xe0000000 -#define bSBD_Option 0x1 -#define bFrame_TH 0x1c -#define bFS_Option 0x60 -#define bDC_Slope_check 0x80 -#define bFGuard_Counter_DC_L 0xe00 -#define bFrame_Weight_Short 0x7000 -#define bSub_Tune 0xe00000 -#define bFrame_DC_Length 0xe000000 -#define bSBD_start_offset 0x30000000 -#define bFrame_TH_2 0x7 -#define bFrame_GI2_TH 0x38 -#define bGI2_Sync_en 0x40 -#define bSarch_Short_Early 0x300 -#define bSarch_Short_Late 0xc00 -#define bSarch_GI2_Late 0x70000 -#define bCFOAntSum 0x1 -#define bCFOAcc 0x2 -#define bCFOStartOffset 0xc -#define bCFOLookBack 0x70 -#define bCFOSumWeight 0x80 -#define bDAGCEnable 0x10000 -#define bTXIQImb_A 0x3ff -#define bTXIQImb_B 0xfc00 -#define bTXIQImb_C 0x3f0000 -#define bTXIQImb_D 0xffc00000 -#define bTxIDCOffset 0xff -#define bTxQDCOffset 0xff00 -#define bTxDFIRMode 0x10000 -#define bTxPesudoNoiseOn 0x4000000 -#define bTxPesudoNoise_A 0xff -#define bTxPesudoNoise_B 0xff00 -#define bTxPesudoNoise_C 0xff0000 -#define bTxPesudoNoise_D 0xff000000 -#define bCCADropOption 0x20000 -#define bCCADropThres 0xfff00000 -#define bEDCCA_H 0xf -#define bEDCCA_L 0xf0 -#define bLambda_ED 0x300 -#define bRxInitialGain 0x7f -#define bRxAntDivEn 0x80 -#define bRxAGCAddressForLNA 0x7f00 -#define bRxHighPowerFlow 0x8000 -#define bRxAGCFreezeThres 0xc0000 -#define bRxFreezeStep_AGC1 0x300000 -#define bRxFreezeStep_AGC2 0xc00000 -#define bRxFreezeStep_AGC3 0x3000000 -#define bRxFreezeStep_AGC0 0xc000000 -#define bRxRssi_Cmp_En 0x10000000 -#define bRxQuickAGCEn 0x20000000 -#define bRxAGCFreezeThresMode 0x40000000 -#define bRxOverFlowCheckType 0x80000000 -#define bRxAGCShift 0x7f -#define bTRSW_Tri_Only 0x80 -#define bPowerThres 0x300 -#define bRxAGCEn 0x1 -#define bRxAGCTogetherEn 0x2 -#define bRxAGCMin 0x4 -#define bRxHP_Ini 0x7 -#define bRxHP_TRLNA 0x70 -#define bRxHP_RSSI 0x700 -#define bRxHP_BBP1 0x7000 -#define bRxHP_BBP2 0x70000 -#define bRxHP_BBP3 0x700000 -#define bRSSI_H 0x7f0000 /* threshold for high power */ -#define bRSSI_Gen 0x7f000000 /* threshold for ant diversity */ -#define bRxSettle_TRSW 0x7 -#define bRxSettle_LNA 0x38 -#define bRxSettle_RSSI 0x1c0 -#define bRxSettle_BBP 0xe00 -#define bRxSettle_RxHP 0x7000 -#define bRxSettle_AntSW_RSSI 0x38000 -#define bRxSettle_AntSW 0xc0000 -#define bRxProcessTime_DAGC 0x300000 -#define bRxSettle_HSSI 0x400000 -#define bRxProcessTime_BBPPW 0x800000 -#define bRxAntennaPowerShift 0x3000000 -#define bRSSITableSelect 0xc000000 -#define bRxHP_Final 0x7000000 -#define bRxHTSettle_BBP 0x7 -#define bRxHTSettle_HSSI 0x8 -#define bRxHTSettle_RxHP 0x70 -#define bRxHTSettle_BBPPW 0x80 -#define bRxHTSettle_Idle 0x300 -#define bRxHTSettle_Reserved 0x1c00 -#define bRxHTRxHPEn 0x8000 -#define bRxHTAGCFreezeThres 0x30000 -#define bRxHTAGCTogetherEn 0x40000 -#define bRxHTAGCMin 0x80000 -#define bRxHTAGCEn 0x100000 -#define bRxHTDAGCEn 0x200000 -#define bRxHTRxHP_BBP 0x1c00000 -#define bRxHTRxHP_Final 0xe0000000 -#define bRxPWRatioTH 0x3 -#define bRxPWRatioEn 0x4 -#define bRxMFHold 0x3800 -#define bRxPD_Delay_TH1 0x38 -#define bRxPD_Delay_TH2 0x1c0 -#define bRxPD_DC_COUNT_MAX 0x600 -#define bRxPD_Delay_TH 0x8000 -#define bRxProcess_Delay 0xf0000 -#define bRxSearchrange_GI2_Early 0x700000 -#define bRxFrame_Guard_Counter_L 0x3800000 -#define bRxSGI_Guard_L 0xc000000 -#define bRxSGI_Search_L 0x30000000 -#define bRxSGI_TH 0xc0000000 -#define bDFSCnt0 0xff -#define bDFSCnt1 0xff00 -#define bDFSFlag 0xf0000 -#define bMFWeightSum 0x300000 -#define bMinIdxTH 0x7f000000 -#define bDAFormat 0x40000 -#define bTxChEmuEnable 0x01000000 -#define bTRSWIsolation_A 0x7f -#define bTRSWIsolation_B 0x7f00 -#define bTRSWIsolation_C 0x7f0000 -#define bTRSWIsolation_D 0x7f000000 -#define bExtLNAGain 0x7c00 - -/* 6. PageE(0xE00) */ -#define bSTBCEn 0x4 /* Useless */ -#define bAntennaMapping 0x10 -#define bNss 0x20 -#define bCFOAntSumD 0x200 -#define bPHYCounterReset 0x8000000 -#define bCFOReportGet 0x4000000 -#define bOFDMContinueTx 0x10000000 -#define bOFDMSingleCarrier 0x20000000 -#define bOFDMSingleTone 0x40000000 -#define bHTDetect 0x100 -#define bCFOEn 0x10000 -#define bCFOValue 0xfff00000 -#define bSigTone_Re 0x3f -#define bSigTone_Im 0x7f00 -#define bCounter_CCA 0xffff -#define bCounter_ParityFail 0xffff0000 -#define bCounter_RateIllegal 0xffff -#define bCounter_CRC8Fail 0xffff0000 -#define bCounter_MCSNoSupport 0xffff -#define bCounter_FastSync 0xffff -#define bShortCFO 0xfff -#define bShortCFOTLength 12 /* total */ -#define bShortCFOFLength 11 /* fraction */ -#define bLongCFO 0x7ff -#define bLongCFOTLength 11 -#define bLongCFOFLength 11 -#define bTailCFO 0x1fff -#define bTailCFOTLength 13 -#define bTailCFOFLength 12 -#define bmax_en_pwdB 0xffff -#define bCC_power_dB 0xffff0000 -#define bnoise_pwdB 0xffff -#define bPowerMeasTLength 10 -#define bPowerMeasFLength 3 -#define bRx_HT_BW 0x1 -#define bRxSC 0x6 -#define bRx_HT 0x8 -#define bNB_intf_det_on 0x1 -#define bIntf_win_len_cfg 0x30 -#define bNB_Intf_TH_cfg 0x1c0 -#define bRFGain 0x3f -#define bTableSel 0x40 -#define bTRSW 0x80 -#define bRxSNR_A 0xff -#define bRxSNR_B 0xff00 -#define bRxSNR_C 0xff0000 -#define bRxSNR_D 0xff000000 -#define bSNREVMTLength 8 -#define bSNREVMFLength 1 -#define bCSI1st 0xff -#define bCSI2nd 0xff00 -#define bRxEVM1st 0xff0000 -#define bRxEVM2nd 0xff000000 -#define bSIGEVM 0xff -#define bPWDB 0xff00 -#define bSGIEN 0x10000 - -#define bSFactorQAM1 0xf /* Useless */ -#define bSFactorQAM2 0xf0 -#define bSFactorQAM3 0xf00 -#define bSFactorQAM4 0xf000 -#define bSFactorQAM5 0xf0000 -#define bSFactorQAM6 0xf0000 -#define bSFactorQAM7 0xf00000 -#define bSFactorQAM8 0xf000000 -#define bSFactorQAM9 0xf0000000 -#define bCSIScheme 0x100000 - -#define bNoiseLvlTopSet 0x3 /* Useless */ -#define bChSmooth 0x4 -#define bChSmoothCfg1 0x38 -#define bChSmoothCfg2 0x1c0 -#define bChSmoothCfg3 0xe00 -#define bChSmoothCfg4 0x7000 -#define bMRCMode 0x800000 -#define bTHEVMCfg 0x7000000 - -#define bLoopFitType 0x1 /* Useless */ -#define bUpdCFO 0x40 -#define bUpdCFOOffData 0x80 -#define bAdvUpdCFO 0x100 -#define bAdvTimeCtrl 0x800 -#define bUpdClko 0x1000 -#define bFC 0x6000 -#define bTrackingMode 0x8000 -#define bPhCmpEnable 0x10000 -#define bUpdClkoLTF 0x20000 -#define bComChCFO 0x40000 -#define bCSIEstiMode 0x80000 -#define bAdvUpdEqz 0x100000 -#define bUChCfg 0x7000000 -#define bUpdEqz 0x8000000 - -/* Rx Pseduo noise */ -#define bRxPesudoNoiseOn 0x20000000 /* Useless */ -#define bRxPesudoNoise_A 0xff -#define bRxPesudoNoise_B 0xff00 -#define bRxPesudoNoise_C 0xff0000 -#define bRxPesudoNoise_D 0xff000000 -#define bPesudoNoiseState_A 0xffff -#define bPesudoNoiseState_B 0xffff0000 -#define bPesudoNoiseState_C 0xffff -#define bPesudoNoiseState_D 0xffff0000 - -/* 7. RF Register */ -/* Zebra1 */ -#define bZebra1_HSSIEnable 0x8 /* Useless */ -#define bZebra1_TRxControl 0xc00 -#define bZebra1_TRxGainSetting 0x07f -#define bZebra1_RxCorner 0xc00 -#define bZebra1_TxChargePump 0x38 -#define bZebra1_RxChargePump 0x7 -#define bZebra1_ChannelNum 0xf80 -#define bZebra1_TxLPFBW 0x400 -#define bZebra1_RxLPFBW 0x600 - -/* Zebra4 */ -#define bRTL8256RegModeCtrl1 0x100 /* Useless */ -#define bRTL8256RegModeCtrl0 0x40 -#define bRTL8256_TxLPFBW 0x18 -#define bRTL8256_RxLPFBW 0x600 - -/* RTL8258 */ -#define bRTL8258_TxLPFBW 0xc /* Useless */ -#define bRTL8258_RxLPFBW 0xc00 -#define bRTL8258_RSSILPFBW 0xc0 - - /* */ /* Other Definition */ /* */ -/* byte endable for sb_write */ -#define bByte0 0x1 /* Useless */ -#define bByte1 0x2 -#define bByte2 0x4 -#define bByte3 0x8 -#define bWord0 0x3 -#define bWord1 0xc -#define bDWord 0xf - /* for PutRegsetting & GetRegSetting BitMask */ #define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */ #define bMaskByte1 0xff00 -#define bMaskByte2 0xff0000 #define bMaskByte3 0xff000000 -#define bMaskHWord 0xffff0000 -#define bMaskLWord 0x0000ffff #define bMaskDWord 0xffffffff #define bMask12Bits 0xfff -#define bMaskH4Bits 0xf0000000 #define bMaskOFDM_D 0xffc00000 -#define bMaskCCK 0x3f3f3f3f /* for PutRFRegsetting & GetRFRegSetting BitMask */ #define bRFRegOffsetMask 0xfffff -#define bEnable 0x1 /* Useless */ -#define bDisable 0x0 - -#define LeftAntenna 0x0 /* Useless */ -#define RightAntenna 0x1 - -#define tCheckTxStatus 500 /* 500ms Useless */ -#define tUpdateRxCounter 100 /* 100ms */ - -#define rateCCK 0 /* Useless */ -#define rateOFDM 1 -#define rateHT 2 - -/* define Register-End */ -#define bPMAC_End 0x1ff /* Useless */ -#define bFPGAPHY0_End 0x8ff -#define bFPGAPHY1_End 0x9ff -#define bCCKPHY0_End 0xaff -#define bOFDMPHY0_End 0xcff -#define bOFDMPHY1_End 0xdff - -#define bPMACControl 0x0 /* Useless */ -#define bWMACControl 0x1 -#define bWNICControl 0x2 - -#define PathA 0x0 /* Useless */ -#define PathB 0x1 -#define PathC 0x2 -#define PathD 0x3 - -/*--------------------------Define Parameters-------------------------------*/ - - #endif diff --git a/drivers/staging/rtl8188eu/include/hal_intf.h b/drivers/staging/rtl8188eu/include/hal_intf.h index 8b65fcba1967..516a89647003 100644 --- a/drivers/staging/rtl8188eu/include/hal_intf.h +++ b/drivers/staging/rtl8188eu/include/hal_intf.h @@ -199,7 +199,7 @@ void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg, u8 level); void rtw_hal_clone_data(struct adapter *dst_adapt, struct adapter *src_adapt); -void rtw_hal_bcn_related_reg_setting(struct adapter *padapter); +void beacon_timing_control(struct adapter *padapter); u32 rtw_hal_read_rfreg(struct adapter *padapter, enum rf_radio_path eRFPath, u32 RegAddr, u32 BitMask); diff --git a/drivers/staging/rtl8188eu/include/mlme_osdep.h b/drivers/staging/rtl8188eu/include/mlme_osdep.h index eda16c06336a..8e919441c2aa 100644 --- a/drivers/staging/rtl8188eu/include/mlme_osdep.h +++ b/drivers/staging/rtl8188eu/include/mlme_osdep.h @@ -13,7 +13,6 @@ void rtw_init_mlme_timer(struct adapter *padapter); void rtw_os_indicate_disconnect(struct adapter *adapter); void rtw_os_indicate_connect(struct adapter *adapter); -void rtw_os_indicate_scan_done(struct adapter *padapter, bool aborted); void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie); void rtw_reset_securitypriv(struct adapter *adapter); diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index cfe5698fbbb1..c0114ad79788 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -80,8 +80,6 @@ void rtw_free_netdev(struct net_device *netdev); #define FUNC_ADPT_FMT "%s(%s)" #define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name -u64 rtw_modular64(u64 x, u64 y); - /* Macros for handling unaligned memory accesses */ #define RTW_GET_BE24(a) ((((u32)(a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme.h b/drivers/staging/rtl8188eu/include/rtw_mlme.h index 9abb7c320192..010f0c42368a 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme.h @@ -333,7 +333,7 @@ void rtw_dynamic_check_timer_handlder(struct timer_list *t); void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv); -struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv); +struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv); int rtw_if_up(struct adapter *padapter); diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h index 327f7d1bc20c..d70780c8fd62 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h @@ -535,7 +535,6 @@ void report_del_sta_event(struct adapter *padapter, void report_add_sta_event(struct adapter *padapter, unsigned char *addr, int cam_idx); -void beacon_timing_control(struct adapter *padapter); u8 set_tx_beacon_cmd(struct adapter *padapter); unsigned int setup_beacon_frame(struct adapter *padapter, unsigned char *beacon_frame); diff --git a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c index e660bd4d91ef..321b2c46479c 100644 --- a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c @@ -27,11 +27,6 @@ void rtw_os_indicate_connect(struct adapter *adapter) netif_carrier_on(adapter->pnetdev); } -void rtw_os_indicate_scan_done(struct adapter *padapter, bool aborted) -{ - indicate_wx_scan_complete_event(padapter); -} - static struct rt_pmkid_list backup_pmkid[NUM_PMKID_CACHE]; void rtw_reset_securitypriv(struct adapter *adapter) diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c index 105f3f21bdea..69d4b1d66b6f 100644 --- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c +++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c @@ -59,11 +59,6 @@ RETURN: return; } -u64 rtw_modular64(u64 x, u64 y) -{ - return do_div(x, y); -} - void rtw_buf_free(u8 **buf, u32 *buf_len) { *buf_len = 0; diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c index eedf2cd831d1..aaab0d577453 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c @@ -122,8 +122,7 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) precvframe->pkt = pkt_copy; skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */ skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */ - memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); - skb_put(precvframe->pkt, skb_len); + skb_put_data(pkt_copy, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); } else { DBG_88E("%s: alloc_skb fail , drop frag frame\n", __func__); diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig index 11528d17bb3c..1007eea6c8fc 100644 --- a/drivers/staging/rtl8192e/Kconfig +++ b/drivers/staging/rtl8192e/Kconfig @@ -15,6 +15,7 @@ config RTLLIB_CRYPTO_CCMP tristate "Support for rtllib CCMP crypto" depends on RTLLIB select CRYPTO_AES + select CRYPTO_CCM default y help CCMP crypto driver for rtllib. diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 1b7e3fda7905..20e494186c9e 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -618,7 +618,7 @@ static void _rtl92e_dm_tx_update_tssi_strong_signal(struct net_device *dev, static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - bool bHighpowerstate, viviflag = false; + bool viviflag = false; struct dcmd_txcmd tx_cmd; u8 powerlevelOFDM24G; int i = 0, j = 0, k = 0; @@ -632,7 +632,6 @@ static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev) rtl92e_writeb(dev, Pw_Track_Flag, 0); rtl92e_writeb(dev, FW_Busy_Flag, 0); priv->rtllib->bdynamic_txpower_enable = false; - bHighpowerstate = priv->bDynamicTxHighPower; powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24); RF_Type = priv->rf_type; @@ -1901,7 +1900,7 @@ static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev) u8 cck_default_Rx = 0x2; u8 cck_optional_Rx = 0x3; long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0; - u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0; + u8 cck_rx_ver2_max_index = 0; u8 cck_rx_ver2_sec_index = 0; u8 cur_rf_rssi; long cur_cck_pwdb; @@ -1984,7 +1983,6 @@ static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev) if (rf_num == 1) { cck_rx_ver2_max_index = i; - cck_rx_ver2_min_index = i; cck_rx_ver2_sec_index = i; tmp_cck_max_pwdb = cur_cck_pwdb; tmp_cck_min_pwdb = cur_cck_pwdb; @@ -1997,7 +1995,6 @@ static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev) tmp_cck_sec_pwdb = cur_cck_pwdb; tmp_cck_min_pwdb = cur_cck_pwdb; cck_rx_ver2_sec_index = i; - cck_rx_ver2_min_index = i; } } else { if (cur_cck_pwdb > tmp_cck_max_pwdb) { @@ -2027,13 +2024,10 @@ static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev) (cur_cck_pwdb > tmp_cck_min_pwdb)) { ; } else if (cur_cck_pwdb == tmp_cck_min_pwdb) { - if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) { + if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_min_index = i; - } } else if (cur_cck_pwdb < tmp_cck_min_pwdb) { tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_min_index = i; } } diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 2dd57e88276e..328f410daa03 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -479,7 +479,6 @@ enum wireless_mode { #define P80211_OUI_LEN 3 struct rtllib_snap_hdr { - u8 dsap; /* always 0xAA */ u8 ssap; /* always 0xAA */ u8 ctrl; /* always 0x03 */ @@ -1940,7 +1939,7 @@ int rtllib_encrypt_fragment( int hdr_len); int rtllib_xmit(struct sk_buff *skb, struct net_device *dev); -void rtllib_txb_free(struct rtllib_txb *); +void rtllib_txb_free(struct rtllib_txb *txb); /* rtllib_rx.c */ int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb, @@ -2132,7 +2131,7 @@ static inline const char *escape_essid(const char *essid, u8 essid_len) return escaped; } - snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); + snprintf(escaped, sizeof(escaped), "%*pE", essid_len, essid); return escaped; } diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c index 2581ed6d14fa..0cbf4a1a326b 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c @@ -17,6 +17,7 @@ #include "rtllib.h" #include <linux/crypto.h> +#include <crypto/aead.h> #include <linux/scatterlist.h> @@ -39,20 +40,13 @@ struct rtllib_ccmp_data { int key_idx; - struct crypto_tfm *tfm; + struct crypto_aead *tfm; /* scratch buffers for virt_to_page() (crypto API) */ - u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], - tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; - u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; + u8 tx_aad[2 * AES_BLOCK_LEN]; + u8 rx_aad[2 * AES_BLOCK_LEN]; }; -static void rtllib_ccmp_aes_encrypt(struct crypto_tfm *tfm, - const u8 pt[16], u8 ct[16]) -{ - crypto_cipher_encrypt_one((void *)tfm, ct, pt); -} - static void *rtllib_ccmp_init(int key_idx) { struct rtllib_ccmp_data *priv; @@ -62,7 +56,7 @@ static void *rtllib_ccmp_init(int key_idx) goto fail; priv->key_idx = key_idx; - priv->tfm = (void *)crypto_alloc_cipher("aes", 0, 0); + priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tfm)) { pr_debug("Could not allocate crypto API aes\n"); priv->tfm = NULL; @@ -73,7 +67,7 @@ static void *rtllib_ccmp_init(int key_idx) fail: if (priv) { if (priv->tfm) - crypto_free_cipher((void *)priv->tfm); + crypto_free_aead(priv->tfm); kfree(priv); } @@ -86,31 +80,18 @@ static void rtllib_ccmp_deinit(void *priv) struct rtllib_ccmp_data *_priv = priv; if (_priv && _priv->tfm) - crypto_free_cipher((void *)_priv->tfm); + crypto_free_aead(_priv->tfm); kfree(priv); } -static inline void xor_block(u8 *b, u8 *a, size_t len) -{ - int i; - - for (i = 0; i < len; i++) - b[i] ^= a[i]; -} - - - -static void ccmp_init_blocks(struct crypto_tfm *tfm, - struct rtllib_hdr_4addr *hdr, - u8 *pn, size_t dlen, u8 *b0, u8 *auth, - u8 *s0) +static int ccmp_init_iv_and_aad(struct rtllib_hdr_4addr *hdr, + u8 *pn, u8 *iv, u8 *aad) { u8 *pos, qc = 0; size_t aad_len; u16 fc; int a4_included, qc_included; - u8 aad[2 * AES_BLOCK_LEN]; fc = le16_to_cpu(hdr->frame_ctl); a4_included = ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == @@ -128,18 +109,19 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, qc = *pos & 0x0f; aad_len += 2; } - /* CCM Initial Block: - * Flag (Include authentication header, M=3 (8-octet MIC), - * L=1 (2-octet Dlen)) - * Nonce: 0x00 | A2 | PN - * Dlen + /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC + * mode authentication are not allowed to collide, yet both are derived + * from the same vector. We only set L := 1 here to indicate that the + * data size can be represented in (L+1) bytes. The CCM layer will take + * care of storing the data length in the top (L+1) bytes and setting + * and clearing the other bits as is required to derive the two IVs. */ - b0[0] = 0x59; - b0[1] = qc; - memcpy(b0 + 2, hdr->addr2, ETH_ALEN); - memcpy(b0 + 8, pn, CCMP_PN_LEN); - b0[14] = (dlen >> 8) & 0xff; - b0[15] = dlen & 0xff; + iv[0] = 0x1; + + /* Nonce: QC | A2 | PN */ + iv[1] = qc; + memcpy(iv + 2, hdr->addr2, ETH_ALEN); + memcpy(iv + 8, pn, CCMP_PN_LEN); /* AAD: * FC with bits 4..6 and 11..13 masked to zero; 14 is always one @@ -149,31 +131,21 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, * QC (if present) */ pos = (u8 *) hdr; - aad[0] = 0; /* aad_len >> 8 */ - aad[1] = aad_len & 0xff; - aad[2] = pos[0] & 0x8f; - aad[3] = pos[1] & 0xc7; - memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); + aad[0] = pos[0] & 0x8f; + aad[1] = pos[1] & 0xc7; + memcpy(aad + 2, hdr->addr1, 3 * ETH_ALEN); pos = (u8 *) &hdr->seq_ctl; - aad[22] = pos[0] & 0x0f; - aad[23] = 0; /* all bits masked */ - memset(aad + 24, 0, 8); + aad[20] = pos[0] & 0x0f; + aad[21] = 0; /* all bits masked */ + memset(aad + 22, 0, 8); if (a4_included) - memcpy(aad + 24, hdr->addr4, ETH_ALEN); + memcpy(aad + 22, hdr->addr4, ETH_ALEN); if (qc_included) { - aad[a4_included ? 30 : 24] = qc; + aad[a4_included ? 28 : 22] = qc; /* rest of QC masked */ } - /* Start with the first block and AAD */ - rtllib_ccmp_aes_encrypt(tfm, b0, auth); - xor_block(auth, aad, AES_BLOCK_LEN); - rtllib_ccmp_aes_encrypt(tfm, auth, auth); - xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - rtllib_ccmp_aes_encrypt(tfm, auth, auth); - b0[0] &= 0x07; - b0[14] = b0[15] = 0; - rtllib_ccmp_aes_encrypt(tfm, b0, s0); + return aad_len; } @@ -181,7 +153,7 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct rtllib_ccmp_data *key = priv; - int data_len, i; + int i; u8 *pos; struct rtllib_hdr_4addr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + @@ -191,7 +163,6 @@ static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) skb->len < hdr_len) return -1; - data_len = skb->len - hdr_len; pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdr_len); pos += hdr_len; @@ -213,40 +184,37 @@ static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = key->tx_pn[1]; *pos++ = key->tx_pn[0]; - hdr = (struct rtllib_hdr_4addr *) skb->data; if (!tcb_desc->bHwSec) { - int blocks, last, len; - u8 *mic; - u8 *b0 = key->tx_b0; - u8 *b = key->tx_b; - u8 *e = key->tx_e; - u8 *s0 = key->tx_s0; - - mic = skb_put(skb, CCMP_MIC_LEN); - - ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, - b0, b, s0); - - blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Authentication */ - xor_block(b, pos, len); - rtllib_ccmp_aes_encrypt(key->tfm, b, b); - /* Encryption, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - rtllib_ccmp_aes_encrypt(key->tfm, b0, e); - xor_block(pos, e, len); - pos += len; - } + struct aead_request *req; + struct scatterlist sg[2]; + u8 *aad = key->tx_aad; + u8 iv[AES_BLOCK_LEN]; + int aad_len, ret; + int data_len = skb->len - hdr_len - CCMP_HDR_LEN; + + req = aead_request_alloc(key->tfm, GFP_ATOMIC); + if (!req) + return -ENOMEM; + + aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad); + + skb_put(skb, CCMP_MIC_LEN); + sg_init_table(sg, 2); + sg_set_buf(&sg[0], aad, aad_len); + sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN, + data_len + CCMP_MIC_LEN); - for (i = 0; i < CCMP_MIC_LEN; i++) - mic[i] = b[i] ^ s0[i]; + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, aad_len); + aead_request_set_crypt(req, sg, sg, data_len, iv); + + ret = crypto_aead_encrypt(req); + aead_request_free(req); + + return ret; } + return 0; } @@ -302,35 +270,31 @@ static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return -4; } if (!tcb_desc->bHwSec) { - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - - CCMP_MIC_LEN; - u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; - u8 *b0 = key->rx_b0; - u8 *b = key->rx_b; - u8 *a = key->rx_a; - int i, blocks, last, len; - - - ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); - xor_block(mic, b, CCMP_MIC_LEN); - - blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Decrypt, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - rtllib_ccmp_aes_encrypt(key->tfm, b0, b); - xor_block(pos, b, len); - /* Authentication */ - xor_block(a, pos, len); - rtllib_ccmp_aes_encrypt(key->tfm, a, a); - pos += len; - } + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; + struct aead_request *req; + struct scatterlist sg[2]; + u8 *aad = key->rx_aad; + u8 iv[AES_BLOCK_LEN]; + int aad_len, ret; + + req = aead_request_alloc(key->tfm, GFP_ATOMIC); + if(!req) + return -ENOMEM; + + aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad); + + sg_init_table(sg, 2); + sg_set_buf(&sg[0], aad, aad_len); + sg_set_buf(&sg[1], pos, data_len); + + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, aad_len); + aead_request_set_crypt(req, sg, sg, data_len, iv); + + ret = crypto_aead_decrypt(req); + aead_request_free(req); - if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { + if (ret) { if (net_ratelimit()) { pr_debug("CCMP: decrypt failed: STA= %pM\n", hdr->addr2); @@ -354,7 +318,7 @@ static int rtllib_ccmp_set_key(void *key, int len, u8 *seq, void *priv) { struct rtllib_ccmp_data *data = priv; int keyidx; - struct crypto_tfm *tfm = data->tfm; + struct crypto_aead *tfm = data->tfm; keyidx = data->key_idx; memset(data, 0, sizeof(*data)); @@ -371,7 +335,9 @@ static int rtllib_ccmp_set_key(void *key, int len, u8 *seq, void *priv) data->rx_pn[4] = seq[1]; data->rx_pn[5] = seq[0]; } - crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN); + if (crypto_aead_setauthsize(data->tfm, CCMP_MIC_LEN) || + crypto_aead_setkey(data->tfm, data->key, CCMP_TK_LEN)) + return -1; } else if (len == 0) { data->key_set = 0; } else { diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 0c19ac2bc3bf..0bae0a0a4cbe 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1300,7 +1300,6 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, struct rx_ts_record *pTS = NULL; u16 fc, sc, SeqNum = 0; u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0; - u8 *payload; u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; u8 bssid[ETH_ALEN] = {0}; @@ -1412,7 +1411,6 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Parse rx data frame (For AMSDU) */ /* skb: hdr + (possible reassembled) full plaintext payload */ - payload = skb->data + hdrlen; rxb = kmalloc(sizeof(struct rtllib_rxb), GFP_ATOMIC); if (!rxb) goto rx_dropped; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index e29e8d6f4611..f2f7529e7c80 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1382,15 +1382,10 @@ rtllib_association_req(struct rtllib_network *beacon, ieee->assocreq_ies = NULL; ies = &(hdr->info_element[0].id); ieee->assocreq_ies_len = (skb->data + skb->len) - ies; - ieee->assocreq_ies = kmalloc(ieee->assocreq_ies_len, GFP_ATOMIC); - if (ieee->assocreq_ies) - memcpy(ieee->assocreq_ies, ies, ieee->assocreq_ies_len); - else { - netdev_info(ieee->dev, - "%s()Warning: can't alloc memory for assocreq_ies\n", - __func__); + ieee->assocreq_ies = kmemdup(ies, ieee->assocreq_ies_len, GFP_ATOMIC); + if (!ieee->assocreq_ies) ieee->assocreq_ies_len = 0; - } + return skb; } @@ -2259,17 +2254,12 @@ rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, ieee->assocresp_ies = NULL; ies = &(assoc_resp->info_element[0].id); ieee->assocresp_ies_len = (skb->data + skb->len) - ies; - ieee->assocresp_ies = kmalloc(ieee->assocresp_ies_len, + ieee->assocresp_ies = kmemdup(ies, + ieee->assocresp_ies_len, GFP_ATOMIC); - if (ieee->assocresp_ies) - memcpy(ieee->assocresp_ies, ies, - ieee->assocresp_ies_len); - else { - netdev_info(ieee->dev, - "%s()Warning: can't alloc memory for assocresp_ies\n", - __func__); + if (!ieee->assocresp_ies) ieee->assocresp_ies_len = 0; - } + rtllib_associate_complete(ieee); } else { /* aid could not been allocated */ diff --git a/drivers/staging/rtl8192u/Kconfig b/drivers/staging/rtl8192u/Kconfig index 22c2165e8b1c..1edca5c304fb 100644 --- a/drivers/staging/rtl8192u/Kconfig +++ b/drivers/staging/rtl8192u/Kconfig @@ -6,3 +6,5 @@ config RTL8192U select WIRELESS_EXT select WEXT_PRIV select CRYPTO + select CRYPTO_AES + select CRYPTO_CCM diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.c b/drivers/staging/rtl8192u/ieee80211/dot11d.c index 130ddfe9868f..bc642076b96f 100644 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.c +++ b/drivers/staging/rtl8192u/ieee80211/dot11d.c @@ -12,7 +12,7 @@ void rtl8192u_dot11d_init(struct ieee80211_device *ieee) dot11d_info->state = DOT11D_STATE_NONE; dot11d_info->country_ie_len = 0; memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1); + memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1); RESET_CIE_WATCHDOG(ieee); netdev_info(ieee->dev, "rtl8192u_dot11d_init()\n"); @@ -25,8 +25,8 @@ void dot11d_reset(struct ieee80211_device *ieee) u32 i; struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); /* Clear old channel map */ - memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1); + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1); /* Set new channel map */ for (i = 1; i <= 11; i++) (dot11d_info->channel_map)[i] = 1; @@ -56,8 +56,8 @@ void dot11d_update_country_ie(struct ieee80211_device *dev, u8 *pTaddr, u8 i, j, NumTriples, MaxChnlNum; struct chnl_txpower_triple *pTriple; - memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1); + memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); + memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1); MaxChnlNum = 0; NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */ pTriple = (struct chnl_txpower_triple *)(pCoutryIe + 3); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index d36963469015..9576b647f6b1 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -169,9 +169,9 @@ struct cb_desc { #define MGN_MCS14 0x8e #define MGN_MCS15 0x8f -#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A || \ +#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A || \ priv->ieee80211->current_network.mode == IEEE_N_24G || \ - priv->ieee80211->current_network.mode == IEEE_N_5G) ? \ + priv->ieee80211->current_network.mode == IEEE_N_5G) ? \ 16 : 10) #define MGMT_QUEUE_NUM 5 @@ -387,7 +387,7 @@ struct ieee_param { #define IEEE80211_STYPE_ACK 0x00D0 #define IEEE80211_STYPE_CFEND 0x00E0 #define IEEE80211_STYPE_CFENDACK 0x00F0 -#define IEEE80211_STYPE_BLOCKACK 0x0094 +#define IEEE80211_STYPE_BLOCKACK 0x0094 /* data */ #define IEEE80211_STYPE_DATA 0x0000 @@ -452,23 +452,23 @@ do { if (ieee80211_debug_level & (level)) \ printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0) //wb added to debug out data buf //if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA -#define IEEE80211_DEBUG_DATA(level, data, datalen) \ - do { if ((ieee80211_debug_level & (level)) == (level)) \ - { \ - int i; \ - u8 *pdata = (u8 *) data; \ - printk(KERN_DEBUG "ieee80211: %s()\n", __func__); \ - for (i = 0; i < (int)(datalen); i++) \ - { \ - printk("%2x ", pdata[i]); \ - if ((i + 1) % 16 == 0) printk("\n"); \ - } \ - printk("\n"); \ - } \ +#define IEEE80211_DEBUG_DATA(level, data, datalen) \ + do { if ((ieee80211_debug_level & (level)) == (level)) \ + { \ + int i; \ + u8 *pdata = (u8 *)data; \ + printk(KERN_DEBUG "ieee80211: %s()\n", __func__); \ + for (i = 0; i < (int)(datalen); i++) { \ + printk("%2x ", pdata[i]); \ + if ((i + 1) % 16 == 0) \ + printk("\n"); \ + } \ + printk("\n"); \ + } \ } while (0) #else #define IEEE80211_DEBUG (level, fmt, args...) do {} while (0) -#define IEEE80211_DEBUG_DATA (level, data, datalen) do {} while(0) +#define IEEE80211_DEBUG_DATA (level, data, datalen) do {} while (0) #endif /* CONFIG_IEEE80211_DEBUG */ /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ @@ -1649,10 +1649,8 @@ struct ieee80211_device { struct list_head Rx_TS_Pending_List; struct list_head Rx_TS_Unused_List; struct rx_ts_record RxTsRecord[TOTAL_TS_NUM]; -//#ifdef TO_DO_LIST struct rx_reorder_entry RxReorderEntry[128]; struct list_head RxReorder_Unused_List; -//#endif // Qos related. Added by Annie, 2005-11-01. // PSTA_QOS pStaQos; u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) @@ -2015,8 +2013,8 @@ struct ieee80211_device { #define IEEE_A (1<<0) #define IEEE_B (1<<1) #define IEEE_G (1<<2) -#define IEEE_N_24G (1<<4) -#define IEEE_N_5G (1<<5) +#define IEEE_N_24G (1<<4) +#define IEEE_N_5G (1<<5) #define IEEE_MODE_MASK (IEEE_A | IEEE_B | IEEE_G) /* Generate a 802.11 header */ @@ -2426,7 +2424,7 @@ static inline const char *escape_essid(const char *essid, u8 essid_len) return escaped; } - snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); + snprintf(escaped, sizeof(escaped), "%*pE", essid_len, essid); return escaped; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c index 36987fccac5d..01012dddcd73 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c @@ -176,7 +176,7 @@ struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) } -static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } +static void *ieee80211_crypt_null_init(int keyidx) { return (void *)1; } static void ieee80211_crypt_null_deinit(void *priv) {} static struct ieee80211_crypto_ops ieee80211_crypt_null = { diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c index d7188b3f3190..c241cf484023 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c @@ -19,6 +19,7 @@ #include "ieee80211.h" #include <linux/crypto.h> +#include <crypto/aead.h> #include <linux/scatterlist.h> MODULE_AUTHOR("Jouni Malinen"); @@ -44,20 +45,13 @@ struct ieee80211_ccmp_data { int key_idx; - struct crypto_tfm *tfm; + struct crypto_aead *tfm; /* scratch buffers for virt_to_page() (crypto API) */ - u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], - tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; - u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; + u8 tx_aad[2 * AES_BLOCK_LEN]; + u8 rx_aad[2 * AES_BLOCK_LEN]; }; -static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, - const u8 pt[16], u8 ct[16]) -{ - crypto_cipher_encrypt_one((void *)tfm, ct, pt); -} - static void *ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; @@ -67,7 +61,7 @@ static void *ieee80211_ccmp_init(int key_idx) goto fail; priv->key_idx = key_idx; - priv->tfm = (void *)crypto_alloc_cipher("aes", 0, 0); + priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tfm)) { pr_debug("ieee80211_crypt_ccmp: could not allocate crypto API aes\n"); priv->tfm = NULL; @@ -79,7 +73,7 @@ static void *ieee80211_ccmp_init(int key_idx) fail: if (priv) { if (priv->tfm) - crypto_free_cipher((void *)priv->tfm); + crypto_free_aead(priv->tfm); kfree(priv); } @@ -91,28 +85,17 @@ static void ieee80211_ccmp_deinit(void *priv) struct ieee80211_ccmp_data *_priv = priv; if (_priv && _priv->tfm) - crypto_free_cipher((void *)_priv->tfm); + crypto_free_aead(_priv->tfm); kfree(priv); } -static inline void xor_block(u8 *b, u8 *a, size_t len) -{ - int i; - - for (i = 0; i < len; i++) - b[i] ^= a[i]; -} - -static void ccmp_init_blocks(struct crypto_tfm *tfm, - struct rtl_80211_hdr_4addr *hdr, - u8 *pn, size_t dlen, u8 *b0, u8 *auth, - u8 *s0) +static int ccmp_init_iv_and_aad(struct rtl_80211_hdr_4addr *hdr, + u8 *pn, u8 *iv, u8 *aad) { u8 *pos, qc = 0; size_t aad_len; u16 fc; int a4_included, qc_included; - u8 aad[2 * AES_BLOCK_LEN]; fc = le16_to_cpu(hdr->frame_ctl); a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == @@ -133,18 +116,20 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, qc = *pos & 0x0f; aad_len += 2; } - /* CCM Initial Block: - * Flag (Include authentication header, M=3 (8-octet MIC), - * L=1 (2-octet Dlen)) - * Nonce: 0x00 | A2 | PN - * Dlen + + /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC + * mode authentication are not allowed to collide, yet both are derived + * from the same vector. We only set L := 1 here to indicate that the + * data size can be represented in (L+1) bytes. The CCM layer will take + * care of storing the data length in the top (L+1) bytes and setting + * and clearing the other bits as is required to derive the two IVs. */ - b0[0] = 0x59; - b0[1] = qc; - memcpy(b0 + 2, hdr->addr2, ETH_ALEN); - memcpy(b0 + 8, pn, CCMP_PN_LEN); - b0[14] = (dlen >> 8) & 0xff; - b0[15] = dlen & 0xff; + iv[0] = 0x1; + + /* Nonce: QC | A2 | PN */ + iv[1] = qc; + memcpy(iv + 2, hdr->addr2, ETH_ALEN); + memcpy(iv + 8, pn, CCMP_PN_LEN); /* AAD: * FC with bits 4..6 and 11..13 masked to zero; 14 is always one @@ -154,38 +139,27 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, * QC (if present) */ pos = (u8 *)hdr; - aad[0] = 0; /* aad_len >> 8 */ - aad[1] = aad_len & 0xff; - aad[2] = pos[0] & 0x8f; - aad[3] = pos[1] & 0xc7; - memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); + aad[0] = pos[0] & 0x8f; + aad[1] = pos[1] & 0xc7; + memcpy(aad + 2, hdr->addr1, 3 * ETH_ALEN); pos = (u8 *)&hdr->seq_ctl; - aad[22] = pos[0] & 0x0f; - aad[23] = 0; /* all bits masked */ - memset(aad + 24, 0, 8); + aad[20] = pos[0] & 0x0f; + aad[21] = 0; /* all bits masked */ + memset(aad + 22, 0, 8); if (a4_included) - memcpy(aad + 24, hdr->addr4, ETH_ALEN); + memcpy(aad + 22, hdr->addr4, ETH_ALEN); if (qc_included) { - aad[a4_included ? 30 : 24] = qc; + aad[a4_included ? 28 : 22] = qc; /* rest of QC masked */ } - /* Start with the first block and AAD */ - ieee80211_ccmp_aes_encrypt(tfm, b0, auth); - xor_block(auth, aad, AES_BLOCK_LEN); - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); - xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); - b0[0] &= 0x07; - b0[14] = 0; - b0[15] = 0; - ieee80211_ccmp_aes_encrypt(tfm, b0, s0); + return aad_len; } static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct ieee80211_ccmp_data *key = priv; - int data_len, i; + int i; u8 *pos; struct rtl_80211_hdr_4addr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); @@ -195,7 +169,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) skb->len < hdr_len) return -1; - data_len = skb->len - hdr_len; pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdr_len); pos += hdr_len; @@ -220,36 +193,34 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) hdr = (struct rtl_80211_hdr_4addr *)skb->data; if (!tcb_desc->bHwSec) { - int blocks, last, len; - u8 *mic; - u8 *b0 = key->tx_b0; - u8 *b = key->tx_b; - u8 *e = key->tx_e; - u8 *s0 = key->tx_s0; - - /* mic is moved to here by john */ - mic = skb_put(skb, CCMP_MIC_LEN); - - ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); - - blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Authentication */ - xor_block(b, pos, len); - ieee80211_ccmp_aes_encrypt(key->tfm, b, b); - /* Encryption, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - ieee80211_ccmp_aes_encrypt(key->tfm, b0, e); - xor_block(pos, e, len); - pos += len; - } + struct aead_request *req; + struct scatterlist sg[2]; + u8 *aad = key->tx_aad; + u8 iv[AES_BLOCK_LEN]; + int aad_len, ret; + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; - for (i = 0; i < CCMP_MIC_LEN; i++) - mic[i] = b[i] ^ s0[i]; + req = aead_request_alloc(key->tfm, GFP_ATOMIC); + if (!req) + return -ENOMEM; + + aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad); + + skb_put(skb, CCMP_MIC_LEN); + + sg_init_table(sg, 2); + sg_set_buf(&sg[0], aad, aad_len); + sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN, + data_len + CCMP_MIC_LEN); + + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, aad_len); + aead_request_set_crypt(req, sg, sg, data_len, iv); + + ret = crypto_aead_encrypt(req); + aead_request_free(req); + + return ret; } return 0; } @@ -309,33 +280,31 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return -4; } if (!tcb_desc->bHwSec) { - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; - u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; - u8 *b0 = key->rx_b0; - u8 *b = key->rx_b; - u8 *a = key->rx_a; - int i, blocks, last, len; - - ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); - xor_block(mic, b, CCMP_MIC_LEN); - - blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Decrypt, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - ieee80211_ccmp_aes_encrypt(key->tfm, b0, b); - xor_block(pos, b, len); - /* Authentication */ - xor_block(a, pos, len); - ieee80211_ccmp_aes_encrypt(key->tfm, a, a); - pos += len; - } + struct aead_request *req; + struct scatterlist sg[2]; + u8 *aad = key->rx_aad; + u8 iv[AES_BLOCK_LEN]; + int aad_len, ret; + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; + + req = aead_request_alloc(key->tfm, GFP_ATOMIC); + if (!req) + return -ENOMEM; + + aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad); + + sg_init_table(sg, 2); + sg_set_buf(&sg[0], aad, aad_len); + sg_set_buf(&sg[1], pos, data_len); + + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, aad_len); + aead_request_set_crypt(req, sg, sg, data_len, iv); + + ret = crypto_aead_decrypt(req); + aead_request_free(req); - if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { + if (ret) { if (net_ratelimit()) { netdev_dbg(skb->dev, "CCMP: decrypt failed: STA=%pM\n", hdr->addr2); @@ -358,12 +327,11 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) { struct ieee80211_ccmp_data *data = priv; int keyidx; - struct crypto_tfm *tfm = data->tfm; + struct crypto_aead *tfm = data->tfm; keyidx = data->key_idx; memset(data, 0, sizeof(*data)); data->key_idx = keyidx; - data->tfm = tfm; if (len == CCMP_TK_LEN) { memcpy(data->key, key, CCMP_TK_LEN); data->key_set = 1; @@ -375,7 +343,9 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) data->rx_pn[4] = seq[1]; data->rx_pn[5] = seq[0]; } - crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN); + if (crypto_aead_setauthsize(tfm, CCMP_MIC_LEN) || + crypto_aead_setkey(tfm, data->key, CCMP_TK_LEN)) + return -1; } else if (len == 0) { data->key_set = 0; } else { diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c index 0927b2b15151..6f4710171151 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c @@ -160,7 +160,7 @@ static inline u16 Hi16(u32 val) static inline u16 Mk16(u8 hi, u8 lo) { - return lo | (((u16) hi) << 8); + return lo | (((u16)hi) << 8); } static const u16 Sbox[256] = { @@ -238,7 +238,7 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, * Make temporary area overlap WEP seed so that the final copy can be * avoided on little endian hosts. */ - u16 *PPK = (u16 *) &WEPSeed[4]; + u16 *PPK = (u16 *)&WEPSeed[4]; /* Step 1 - make copy of TTAK and bring in TSC */ PPK[0] = TTAK[0]; @@ -299,7 +299,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) skb->len < hdr_len) return -1; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; if (!tcb_desc->bHwSec) { if (!tkey->tx_phase1_done) { @@ -343,7 +343,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) icv[2] = crc >> 16; icv[3] = crc >> 24; crypto_sync_skcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); - sg_init_one(&sg, pos, len+4); + sg_init_one(&sg, pos, len + 4); skcipher_request_set_sync_tfm(req, tkey->tx_tfm_arc4); skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_crypt(req, &sg, &sg, len + 4, NULL); @@ -383,7 +383,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (skb->len < hdr_len + 8 + 4) return -1; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & BIT(5))) { @@ -435,7 +435,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) plen = skb->len - hdr_len - 12; crypto_sync_skcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); - sg_init_one(&sg, pos, plen+4); + sg_init_one(&sg, pos, plen + 4); skcipher_request_set_sync_tfm(req, tkey->rx_tfm_arc4); skcipher_request_set_callback(req, 0, NULL, NULL); @@ -523,7 +523,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) { struct rtl_80211_hdr_4addr *hdr11; - hdr11 = (struct rtl_80211_hdr_4addr *) skb->data; + hdr11 = (struct rtl_80211_hdr_4addr *)skb->data; switch (le16_to_cpu(hdr11->frame_ctl) & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { case IEEE80211_FCTL_TODS: @@ -556,7 +556,7 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri u8 *pos; struct rtl_80211_hdr_4addr *hdr; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { printk(KERN_DEBUG "Invalid packet for Michael MIC add " @@ -599,7 +599,7 @@ static void ieee80211_michael_mic_failure(struct net_device *dev, memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN); memset(&wrqu, 0, sizeof(wrqu)); wrqu.data.length = sizeof(ev); - wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev); + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); } static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, @@ -609,7 +609,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, u8 mic[8]; struct rtl_80211_hdr_4addr *hdr; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; if (!tkey->key_set) return -1; @@ -626,7 +626,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, return -1; if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { struct rtl_80211_hdr_4addr *hdr; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " "MSDU from %pM keyidx=%d\n", diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c index 805493a0870d..26482c3dcd1c 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c @@ -135,7 +135,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) icv[3] = crc >> 24; crypto_sync_skcipher_setkey(wep->tx_tfm, key, klen); - sg_init_one(&sg, pos, len+4); + sg_init_one(&sg, pos, len + 4); skcipher_request_set_sync_tfm(req, wep->tx_tfm); skcipher_request_set_callback(req, 0, NULL, NULL); @@ -192,7 +192,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) SYNC_SKCIPHER_REQUEST_ON_STACK(req, wep->rx_tfm); crypto_sync_skcipher_setkey(wep->rx_tfm, key, klen); - sg_init_one(&sg, pos, plen+4); + sg_init_one(&sg, pos, plen + 4); skcipher_request_set_sync_tfm(req, wep->rx_tfm); skcipher_request_set_callback(req, 0, NULL, NULL); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 0a3e478fccd6..5c33bcb0db2e 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -103,17 +103,17 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee, u8 tid; if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; + hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid++; } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; + hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid++; } else { - tid = 0; + tid = 0; } if (frag == 0) { @@ -124,7 +124,7 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee, 2 /* alignment */ + 8 /* WEP */ + ETH_ALEN /* WDS */ + - (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */); + (IEEE80211_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */); if (!skb) return NULL; @@ -145,7 +145,7 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee, } else { /* received a fragment of a frame for which the head fragment * should have already been received */ - entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2, + entry = ieee80211_frag_cache_find(ieee, seq, frag, tid, hdr->addr2, hdr->addr1); if (entry) { entry->last_frag = frag; @@ -169,18 +169,18 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, struct rtl_80211_hdr_4addrqos *hdr_4addrqos; u8 tid; - if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid++; } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; + hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid++; } else { - tid = 0; + tid = 0; } entry = ieee80211_frag_cache_find(ieee, seq, -1, tid, hdr->addr2, @@ -216,10 +216,10 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, struct rtl_80211_hdr_3addr *hdr = (struct rtl_80211_hdr_3addr *)skb->data; rx_stats->len = skb->len; - ieee80211_rx_mgt(ieee,(struct rtl_80211_hdr_4addr *)skb->data,rx_stats); + ieee80211_rx_mgt(ieee, (struct rtl_80211_hdr_4addr *)skb->data, rx_stats); /* if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) */ - if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))/* use ADDR1 to perform address matching for Management frames */ - { + if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN))) { + /* use ADDR1 to perform address matching for Management frames */ dev_kfree_skb_any(skb); return 0; } @@ -281,11 +281,11 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; +static unsigned char rfc1042_header[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; +static unsigned char bridge_tunnel_header[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; /* No encapsulation header if EtherType < 0x600 (=length) */ /* Called by ieee80211_rx_frame_decrypt */ @@ -300,7 +300,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, if (skb->len < 24) return 0; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; fc = le16_to_cpu(hdr->frame_ctl); /* check that the frame is unicast frame to us */ @@ -339,12 +339,11 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, if (!crypt || !crypt->ops->decrypt_mpdu) return 0; - if (ieee->hwsec_active) - { - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); + if (ieee->hwsec_active) { + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bHwSec = 1; } - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); if (ieee->tkip_countermeasures && @@ -386,13 +385,12 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *s if (!crypt || !crypt->ops->decrypt_msdu) return 0; - if (ieee->hwsec_active) - { - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); + if (ieee->hwsec_active) { + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bHwSec = 1; } - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); atomic_inc(&crypt->refcnt); @@ -410,7 +408,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *s /* this function is stolen from ipw2200 driver*/ -#define IEEE_PACKET_RETRY_TIME (5*HZ) +#define IEEE_PACKET_RETRY_TIME (5 * HZ) static int is_duplicate_packet(struct ieee80211_device *ieee, struct rtl_80211_hdr_4addr *header) { @@ -426,18 +424,18 @@ static int is_duplicate_packet(struct ieee80211_device *ieee, //TO2DS and QoS - if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)header; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS - hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)header; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)header; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid++; + } else if (IEEE80211_QOS_HAS_SEQ(fc)) { //QoS + hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)header; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid++; } else { // no QoS - tid = 0; + tid = 0; } switch (ieee->iw_mode) { @@ -507,8 +505,7 @@ drop: static bool AddReorderEntry(struct rx_ts_record *pTS, struct rx_reorder_entry *pReorderEntry) { struct list_head *pList = &pTS->rx_pending_pkt_list; - while(pList->next != &pTS->rx_pending_pkt_list) - { + while (pList->next != &pTS->rx_pending_pkt_list) { if (SN_LESS(pReorderEntry->SeqNum, list_entry(pList->next, struct rx_reorder_entry, List)->SeqNum)) pList = pList->next; else if (SN_EQUAL(pReorderEntry->SeqNum, list_entry(pList->next, struct rx_reorder_entry, List)->SeqNum)) @@ -524,17 +521,16 @@ static bool AddReorderEntry(struct rx_ts_record *pTS, struct rx_reorder_entry *p return true; } -void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb **prxbIndicateArray,u8 index) +void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb **prxbIndicateArray, u8 index) { - u8 i = 0 , j=0; + u8 i = 0, j = 0; u16 ethertype; // if(index > 1) // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): hahahahhhh, We indicate packet from reorder list, index is %u\n",__func__,index); - for(j = 0; j<index; j++) - { + for (j = 0; j < index; j++) { //added by amy for reorder struct ieee80211_rxb *prxb = prxbIndicateArray[j]; - for(i = 0; i<prxb->nr_subframes; i++) { + for (i = 0; i < prxb->nr_subframes; i++) { struct sk_buff *sub_skb = prxb->subframes[i]; /* convert hdr + possible LLC headers into Ethernet header */ @@ -585,7 +581,7 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, u16 WinEnd = (pTS->rx_indicate_seq + WinSize - 1) % 4096; u8 index = 0; bool bMatchWinStart = false, bPktInBuf = false; - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->rx_indicate_seq is %d, WinSize is %d\n",__func__,SeqNum,pTS->rx_indicate_seq,WinSize); + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Seq is %d,pTS->rx_indicate_seq is %d, WinSize is %d\n", __func__, SeqNum, pTS->rx_indicate_seq, WinSize); prxbIndicateArray = kmalloc_array(REORDER_WIN_SIZE, sizeof(struct ieee80211_rxb *), @@ -599,12 +595,12 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, /* Drop out the packet which SeqNum is smaller than WinStart */ if (SN_LESS(SeqNum, pTS->rx_indicate_seq)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n", + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); pHTInfo->RxReorderDropCounter++; { int i; - for(i =0; i < prxb->nr_subframes; i++) { + for (i = 0; i < prxb->nr_subframes; i++) { dev_kfree_skb(prxb->subframes[i]); } kfree(prxb); @@ -620,16 +616,16 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N */ - if(SN_EQUAL(SeqNum, pTS->rx_indicate_seq)) { + if (SN_EQUAL(SeqNum, pTS->rx_indicate_seq)) { pTS->rx_indicate_seq = (pTS->rx_indicate_seq + 1) % 4096; bMatchWinStart = true; - } else if(SN_LESS(WinEnd, SeqNum)) { - if(SeqNum >= (WinSize - 1)) { - pTS->rx_indicate_seq = SeqNum + 1 -WinSize; + } else if (SN_LESS(WinEnd, SeqNum)) { + if (SeqNum >= (WinSize - 1)) { + pTS->rx_indicate_seq = SeqNum + 1 - WinSize; } else { pTS->rx_indicate_seq = 4095 - (WinSize - (SeqNum + 1)) + 1; } - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->rx_indicate_seq, SeqNum); + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); } /* @@ -641,7 +637,7 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, * 1. All packets with SeqNum smaller than WinStart => Indicate * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */ - if(bMatchWinStart) { + if (bMatchWinStart) { /* Current packet is going to be indicated.*/ IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\ pTS->rx_indicate_seq, SeqNum); @@ -651,7 +647,7 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, } else { /* Current packet is going to be inserted into pending list.*/ //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to ordered list\n",__func__); - if(!list_empty(&ieee->RxReorder_Unused_List)) { + if (!list_empty(&ieee->RxReorder_Unused_List)) { pReorderEntry = list_entry(ieee->RxReorder_Unused_List.next, struct rx_reorder_entry, List); list_del_init(&pReorderEntry->List); @@ -660,13 +656,13 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, pReorderEntry->prxb = prxb; // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__func__,pReorderEntry->SeqNum); - if(!AddReorderEntry(pTS, pReorderEntry)) { + if (!AddReorderEntry(pTS, pReorderEntry)) { IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", __func__, pTS->rx_indicate_seq, SeqNum); - list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List); + list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); { int i; - for(i =0; i < prxb->nr_subframes; i++) { + for (i = 0; i < prxb->nr_subframes; i++) { dev_kfree_skb(prxb->subframes[i]); } kfree(prxb); @@ -674,10 +670,9 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, } } else { IEEE80211_DEBUG(IEEE80211_DL_REORDER, - "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->rx_indicate_seq, SeqNum); + "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); } - } - else { + } else { /* * Packets are dropped if there is not enough reorder entries. * This part shall be modified!! We can just indicate all the @@ -686,7 +681,7 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n"); { int i; - for(i =0; i < prxb->nr_subframes; i++) { + for (i = 0; i < prxb->nr_subframes; i++) { dev_kfree_skb(prxb->subframes[i]); } kfree(prxb); @@ -696,12 +691,11 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, } /* Check if there is any packet need indicate.*/ - while(!list_empty(&pTS->rx_pending_pkt_list)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__func__); + while (!list_empty(&pTS->rx_pending_pkt_list)) { + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): start RREORDER indicate\n", __func__); pReorderEntry = list_entry(pTS->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); if (SN_LESS(pReorderEntry->SeqNum, pTS->rx_indicate_seq) || - SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) - { + SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) { /* This protect buffer from overflow. */ if (index >= REORDER_WIN_SIZE) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n"); @@ -711,15 +705,15 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, list_del_init(&pReorderEntry->List); - if(SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) + if (SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) pTS->rx_indicate_seq = (pTS->rx_indicate_seq + 1) % 4096; - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->rx_indicate_seq, SeqNum); + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); prxbIndicateArray[index] = pReorderEntry->prxb; // printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__func__,pReorderEntry->SeqNum); index++; - list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List); + list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); } else { bPktInBuf = true; break; @@ -727,13 +721,13 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, } /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/ - if (index>0) { + if (index > 0) { // Cancel previous pending timer. // del_timer_sync(&pTS->rx_pkt_pending_timer); pTS->rx_timeout_indicate_seq = 0xffff; // Indicate packets - if(index>REORDER_WIN_SIZE){ + if (index > REORDER_WIN_SIZE) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"); kfree(prxbIndicateArray); return; @@ -743,9 +737,9 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, if (bPktInBuf && pTS->rx_timeout_indicate_seq == 0xffff) { // Set new pending timer. - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __func__); + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): SET rx timeout timer\n", __func__); pTS->rx_timeout_indicate_seq = pTS->rx_indicate_seq; - if(timer_pending(&pTS->rx_pkt_pending_timer)) + if (timer_pending(&pTS->rx_pkt_pending_timer)) del_timer_sync(&pTS->rx_pkt_pending_timer); pTS->rx_pkt_pending_timer.expires = jiffies + msecs_to_jiffies(pHTInfo->RxReorderPendingTime); @@ -762,12 +756,12 @@ static u8 parse_subframe(struct sk_buff *skb, struct rtl_80211_hdr_3addr *hdr = (struct rtl_80211_hdr_3addr *)skb->data; u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 LLCOffset= sizeof(struct rtl_80211_hdr_3addr); + u16 LLCOffset = sizeof(struct rtl_80211_hdr_3addr); u16 ChkLength; bool bIsAggregateFrame = false; u16 nSubframe_Length; u8 nPadding_Length = 0; - u16 SeqNum=0; + u16 SeqNum = 0; struct sk_buff *sub_skb; /* just for debug purpose */ @@ -793,7 +787,7 @@ static u8 parse_subframe(struct sk_buff *skb, skb_pull(skb, LLCOffset); - if(!bIsAggregateFrame) { + if (!bIsAggregateFrame) { rxb->nr_subframes = 1; #ifdef JOHN_NOCPY rxb->subframes[0] = skb; @@ -801,26 +795,26 @@ static u8 parse_subframe(struct sk_buff *skb, rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC); #endif - memcpy(rxb->src,src,ETH_ALEN); - memcpy(rxb->dst,dst,ETH_ALEN); + memcpy(rxb->src, src, ETH_ALEN); + memcpy(rxb->dst, dst, ETH_ALEN); //IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len); return 1; } else { rxb->nr_subframes = 0; - memcpy(rxb->src,src,ETH_ALEN); - memcpy(rxb->dst,dst,ETH_ALEN); - while(skb->len > ETHERNET_HEADER_SIZE) { + memcpy(rxb->src, src, ETH_ALEN); + memcpy(rxb->dst, dst, ETH_ALEN); + while (skb->len > ETHERNET_HEADER_SIZE) { /* Offset 12 denote 2 mac address */ nSubframe_Length = *((u16 *)(skb->data + 12)); //==m==>change the length order - nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8); + nSubframe_Length = (nSubframe_Length >> 8) + (nSubframe_Length << 8); - if (skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) { + if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\ __func__, rxb->nr_subframes); - printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__func__, nSubframe_Length); - printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length); - printk("The Packet SeqNum is %d\n",SeqNum); + printk("%s: A-MSDU parse error!! Subframe Length: %d\n", __func__, nSubframe_Length); + printk("nRemain_Length is %d and nSubframe_Length is : %d\n", skb->len, nSubframe_Length); + printk("The Packet SeqNum is %d\n", SeqNum); return 0; } @@ -923,9 +917,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, frag = WLAN_GET_SEQ_FRAG(sc); hdrlen = ieee80211_get_hdrlen(fc); - if (HTCCheck(ieee, skb->data)) - { - if(net_ratelimit()) + if (HTCCheck(ieee, skb->data)) { + if (net_ratelimit()) printk("find HTCControl\n"); hdrlen += 4; rx_stats->bContainHTC = true; @@ -972,7 +965,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, * stations that do not support WEP key mapping). */ if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key) - (void) hostap_handle_sta_crypto(local, hdr, &crypt, + (void)hostap_handle_sta_crypto(local, hdr, &crypt, &sta); #endif @@ -998,39 +991,32 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, goto rx_dropped; // if QoS enabled, should check the sequence for each of the AC - if ((!ieee->pHTInfo->bCurRxReorderEnable) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)) { + if ((!ieee->pHTInfo->bCurRxReorderEnable) || !ieee->current_network.qos_data.active || !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)) { if (is_duplicate_packet(ieee, hdr)) - goto rx_dropped; + goto rx_dropped; - } - else - { + } else { struct rx_ts_record *pRxTS = NULL; //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__func__, tid); - if(GetTs( + if (GetTs( ieee, - (struct ts_common_info **) &pRxTS, + (struct ts_common_info **)&pRxTS, hdr->addr2, Frame_QoSTID((u8 *)(skb->data)), RX_DIR, - true)) - { + true)) { // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->rx_last_frag_num is %d,frag is %d,pRxTS->rx_last_seq_num is %d,seq is %d\n",__func__,pRxTS->rx_last_frag_num,frag,pRxTS->rx_last_seq_num,WLAN_GET_SEQ_SEQ(sc)); - if ((fc & (1<<11)) && + if ((fc & (1 << 11)) && (frag == pRxTS->rx_last_frag_num) && (WLAN_GET_SEQ_SEQ(sc) == pRxTS->rx_last_seq_num)) { goto rx_dropped; - } - else - { + } else { pRxTS->rx_last_frag_num = frag; pRxTS->rx_last_seq_num = WLAN_GET_SEQ_SEQ(sc); } - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__func__); + } else { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n", __func__); goto rx_dropped; } } @@ -1126,14 +1112,13 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) - { + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) { printk("decrypt frame error\n"); goto rx_dropped; } - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; /* skb: hdr + (possibly fragmented) plaintext payload */ // PR: FIXME: hostap has additional conditions in the "if" below: @@ -1185,15 +1170,14 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* this was the last fragment and the frame will be * delivered, so remove skb from fragment cache */ skb = frag_skb; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; ieee80211_frag_cache_invalidate(ieee, hdr); } /* skb: hdr + (possible reassembled) full MSDU payload; possibly still * encrypted/authenticated */ if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) - { + ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) { printk("==>decrypt msdu error\n"); goto rx_dropped; } @@ -1202,7 +1186,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, ieee->LinkDetectInfo.NumRecvDataInPeriod++; ieee->LinkDetectInfo.NumRxOkInPeriod++; - hdr = (struct rtl_80211_hdr_4addr *) skb->data; + hdr = (struct rtl_80211_hdr_4addr *)skb->data; if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { if (/*ieee->ieee802_1x &&*/ ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { @@ -1227,10 +1211,10 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, #ifdef CONFIG_IEEE80211_DEBUG if (crypt && !(fc & IEEE80211_FCTL_WEP) && ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - struct eapol *eap = (struct eapol *)(skb->data + - 24); - IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); + struct eapol *eap = (struct eapol *)(skb->data + + 24); + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); } #endif @@ -1250,13 +1234,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, */ //added by amy for reorder if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1)) - { + && !is_multicast_ether_addr(hdr->addr1)) { TID = Frame_QoSTID(skb->data); SeqNum = WLAN_GET_SEQ_SEQ(sc); - GetTs(ieee,(struct ts_common_info **) &pTS,hdr->addr2,TID,RX_DIR,true); - if (TID !=0 && TID !=3) - { + GetTs(ieee, (struct ts_common_info **)&pTS, hdr->addr2, TID, RX_DIR, true); + if (TID != 0 && TID != 3) { ieee->bis_any_nonbepkts = true; } } @@ -1270,7 +1252,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* qos data packets & reserved bit is 1 */ if (parse_subframe(skb, rx_stats, rxb, src, dst) == 0) { /* only to free rxb, and not submit the packets to upper layer */ - for(i =0; i < rxb->nr_subframes; i++) { + for (i = 0; i < rxb->nr_subframes; i++) { dev_kfree_skb(rxb->subframes[i]); } kfree(rxb); @@ -1281,7 +1263,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, //added by amy for reorder if (!ieee->pHTInfo->bCurRxReorderEnable || !pTS) { //added by amy for reorder - for(i = 0; i<rxb->nr_subframes; i++) { + for (i = 0; i < rxb->nr_subframes; i++) { struct sk_buff *sub_skb = rxb->subframes[i]; if (sub_skb) { @@ -1324,10 +1306,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, kfree(rxb); rxb = NULL; - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__func__); + } else { + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n", __func__); RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); } #ifndef JOHN_NOCPY @@ -1407,10 +1387,9 @@ static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info /* * Parse a QoS information element */ -static int ieee80211_read_qos_info_element(struct - ieee80211_qos_information_element - *element_info, struct ieee80211_info_element - *info_element) +static int ieee80211_read_qos_info_element( + struct ieee80211_qos_information_element *element_info, + struct ieee80211_info_element *info_element) { int ret = 0; u16 size = sizeof(struct ieee80211_qos_information_element) - 2; @@ -1438,11 +1417,9 @@ static int ieee80211_read_qos_info_element(struct /* * Write QoS parameters from the ac parameters. */ -static int ieee80211_qos_convert_ac_to_parameters(struct - ieee80211_qos_parameter_info - *param_elm, struct - ieee80211_qos_parameters - *qos_param) +static int ieee80211_qos_convert_ac_to_parameters( + struct ieee80211_qos_parameter_info *param_elm, + struct ieee80211_qos_parameters *qos_param) { int i; struct ieee80211_qos_ac_parameter *ac_params; @@ -1455,12 +1432,12 @@ static int ieee80211_qos_convert_ac_to_parameters(struct aci = (ac_params->aci_aifsn & 0x60) >> 5; - if(aci >= QOS_QUEUE_NUM) + if (aci >= QOS_QUEUE_NUM) continue; qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f; /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ - qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci]; + qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2 : qos_param->aifs[aci]; qos_param->cw_min[aci] = cpu_to_le16(ac_params->ecw_min_max & 0x0F); @@ -1561,15 +1538,12 @@ static inline void ieee80211_extract_country_ie( u8 *addr2 ) { - if (IS_DOT11D_ENABLE(ieee)) - { - if (info_element->len!= 0) - { + if (IS_DOT11D_ENABLE(ieee)) { + if (info_element->len != 0) { memcpy(network->CountryIeBuf, info_element->data, info_element->len); network->CountryIeLen = info_element->len; - if (!IS_COUNTRY_IE_VALID(ieee)) - { + if (!IS_COUNTRY_IE_VALID(ieee)) { dot11d_update_country_ie(ieee, addr2, info_element->len, info_element->data); } } @@ -1579,8 +1553,7 @@ static inline void ieee80211_extract_country_ie( // some AP (e.g. Cisco 1242) don't include country IE in their // probe response frame. // - if (IS_EQUAL_CIE_SRC(ieee, addr2) ) - { + if (IS_EQUAL_CIE_SRC(ieee, addr2)) { UPDATE_CIE_WATCHDOG(ieee); } } @@ -1595,9 +1568,9 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, { u8 i; short offset; - u16 tmp_htcap_len=0; - u16 tmp_htinfo_len=0; - u16 ht_realtek_agg_len=0; + u16 tmp_htcap_len = 0; + u16 tmp_htinfo_len = 0; + u16 ht_realtek_agg_len = 0; u8 ht_realtek_agg_buf[MAX_IE_LEN]; // u16 broadcom_len = 0; #ifdef CONFIG_IEEE80211_DEBUG @@ -1628,7 +1601,7 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, } network->ssid_len = min(info_element->len, - (u8) IW_ESSID_MAX_SIZE); + (u8)IW_ESSID_MAX_SIZE); memcpy(network->ssid, info_element->data, network->ssid_len); if (network->ssid_len < IW_ESSID_MAX_SIZE) memset(network->ssid + network->ssid_len, 0, @@ -1707,14 +1680,14 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, break; case MFIE_TYPE_TIM: - if(info_element->len < 4) + if (info_element->len < 4) break; network->tim.tim_count = info_element->data[0]; network->tim.tim_period = info_element->data[1]; network->dtim_period = info_element->data[1]; - if(ieee->state != IEEE80211_LINKED) + if (ieee->state != IEEE80211_LINKED) break; network->last_dtim_sta_time[0] = stats->mac_time[0]; @@ -1722,22 +1695,22 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, network->dtim_data = IEEE80211_DTIM_VALID; - if(info_element->data[0] != 0) + if (info_element->data[0] != 0) break; - if(info_element->data[2] & 1) + if (info_element->data[2] & 1) network->dtim_data |= IEEE80211_DTIM_MBCAST; - offset = (info_element->data[2] >> 1)*2; + offset = (info_element->data[2] >> 1) * 2; - if(ieee->assoc_id < 8*offset || - ieee->assoc_id > 8*(offset + info_element->len -3)) + if (ieee->assoc_id < 8 * offset || + ieee->assoc_id > 8 * (offset + info_element->len - 3)) break; offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ; - if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) + if (info_element->data[3 + offset] & (1 << (ieee->assoc_id % 8))) network->dtim_data |= IEEE80211_DTIM_UCAST; //IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n"); @@ -1790,66 +1763,66 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, #endif //for HTcap and HTinfo parameters - if(tmp_htcap_len == 0){ - if(info_element->len >= 4 && + if (tmp_htcap_len == 0) { + if (info_element->len >= 4 && info_element->data[0] == 0x00 && info_element->data[1] == 0x90 && info_element->data[2] == 0x4c && info_element->data[3] == 0x033){ - tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htcap_len != 0){ - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\ - sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len; - memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen); - } + tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htcap_len != 0) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? \ + sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len; + memcpy(network->bssht.bdHTCapBuf, info_element->data, network->bssht.bdHTCapLen); + } } - if(tmp_htcap_len != 0) + if (tmp_htcap_len != 0) network->bssht.bdSupportHT = true; else network->bssht.bdSupportHT = false; } - if(tmp_htinfo_len == 0){ - if(info_element->len >= 4 && + if (tmp_htinfo_len == 0) { + if (info_element->len >= 4 && info_element->data[0] == 0x00 && info_element->data[1] == 0x90 && info_element->data[2] == 0x4c && info_element->data[3] == 0x034){ - tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htinfo_len != 0){ - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - if(tmp_htinfo_len){ - network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\ - sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len; - memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen); - } - + tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htinfo_len != 0) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + if (tmp_htinfo_len) { + network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf) ? \ + sizeof(network->bssht.bdHTInfoBuf) : tmp_htinfo_len; + memcpy(network->bssht.bdHTInfoBuf, info_element->data, network->bssht.bdHTInfoLen); } + } + } } - if(ieee->aggregation){ - if(network->bssht.bdSupportHT){ - if(info_element->len >= 4 && + if (ieee->aggregation) { + if (network->bssht.bdSupportHT) { + if (info_element->len >= 4 && info_element->data[0] == 0x00 && info_element->data[1] == 0xe0 && info_element->data[2] == 0x4c && info_element->data[3] == 0x02){ - ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN); - memcpy(ht_realtek_agg_buf,info_element->data,info_element->len); + ht_realtek_agg_len = min(info_element->len, (u8)MAX_IE_LEN); + memcpy(ht_realtek_agg_buf, info_element->data, info_element->len); } - if(ht_realtek_agg_len >= 5){ + if (ht_realtek_agg_len >= 5) { network->bssht.bdRT2RTAggregation = true; - if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02)) - network->bssht.bdRT2RTLongSlotTime = true; + if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02)) + network->bssht.bdRT2RTLongSlotTime = true; } } @@ -1870,78 +1843,63 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, info_element->data[1] == 0x10 && info_element->data[2] == 0x18)){ - network->broadcom_cap_exist = true; + network->broadcom_cap_exist = true; } } - if(info_element->len >= 3 && + if (info_element->len >= 3 && info_element->data[0] == 0x00 && info_element->data[1] == 0x0c && - info_element->data[2] == 0x43) - { + info_element->data[2] == 0x43) { network->ralink_cap_exist = true; - } - else + } else network->ralink_cap_exist = false; //added by amy for atheros AP - if((info_element->len >= 3 && + if ((info_element->len >= 3 && info_element->data[0] == 0x00 && info_element->data[1] == 0x03 && info_element->data[2] == 0x7f) || (info_element->len >= 3 && info_element->data[0] == 0x00 && info_element->data[1] == 0x13 && - info_element->data[2] == 0x74)) - { - printk("========>%s(): athros AP is exist\n",__func__); + info_element->data[2] == 0x74)) { + printk("========>%s(): athros AP is exist\n", __func__); network->atheros_cap_exist = true; - } - else + } else network->atheros_cap_exist = false; - if(info_element->len >= 3 && + if (info_element->len >= 3 && info_element->data[0] == 0x00 && info_element->data[1] == 0x40 && - info_element->data[2] == 0x96) - { + info_element->data[2] == 0x96) { network->cisco_cap_exist = true; - } - else + } else network->cisco_cap_exist = false; //added by amy for LEAP of cisco if (info_element->len > 4 && info_element->data[0] == 0x00 && info_element->data[1] == 0x40 && info_element->data[2] == 0x96 && - info_element->data[3] == 0x01) - { - if(info_element->len == 6) - { + info_element->data[3] == 0x01) { + if (info_element->len == 6) { memcpy(network->CcxRmState, &info_element[4], 2); - if(network->CcxRmState[0] != 0) - { + if (network->CcxRmState[0] != 0) network->bCcxRmEnable = true; - } else network->bCcxRmEnable = false; // // CCXv4 Table 59-1 MBSSID Masks. // network->MBssidMask = network->CcxRmState[1] & 0x07; - if(network->MBssidMask != 0) - { + if (network->MBssidMask != 0) { network->bMBssidValid = true; network->MBssidMask = 0xff << (network->MBssidMask); ether_addr_copy(network->MBssid, network->bssid); network->MBssid[5] &= network->MBssidMask; - } - else - { + } else { network->bMBssidValid = false; } - } - else - { + } else { network->bCcxRmEnable = false; } } @@ -1949,15 +1907,11 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, info_element->data[0] == 0x00 && info_element->data[1] == 0x40 && info_element->data[2] == 0x96 && - info_element->data[3] == 0x03) - { - if(info_element->len == 5) - { + info_element->data[3] == 0x03) { + if (info_element->len == 5) { network->bWithCcxVerNum = true; network->BssCcxVerNumber = info_element->data[4]; - } - else - { + } else { network->bWithCcxVerNum = false; network->BssCcxVerNumber = 0; } @@ -1977,19 +1931,18 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, case MFIE_TYPE_HT_CAP: IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n", info_element->len); - tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htcap_len != 0){ + tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htcap_len != 0) { network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\ - sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len; - memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen); + network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? \ + sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len; + memcpy(network->bssht.bdHTCapBuf, info_element->data, network->bssht.bdHTCapLen); //If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() // windows driver will update WMM parameters each beacon received once connected // Linux driver is a bit different. network->bssht.bdSupportHT = true; - } - else + } else network->bssht.bdSupportHT = false; break; @@ -1997,37 +1950,31 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, case MFIE_TYPE_HT_INFO: IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n", info_element->len); - tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htinfo_len){ + tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htinfo_len) { network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE; - network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\ - sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len; - memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen); + network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf) ? \ + sizeof(network->bssht.bdHTInfoBuf) : tmp_htinfo_len; + memcpy(network->bssht.bdHTInfoBuf, info_element->data, network->bssht.bdHTInfoLen); } break; case MFIE_TYPE_AIRONET: IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n", info_element->len); - if(info_element->len >IE_CISCO_FLAG_POSITION) - { + if (info_element->len > IE_CISCO_FLAG_POSITION) { network->bWithAironetIE = true; // CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23): // "A Cisco access point advertises support for CKIP in beacon and probe response packets, // by adding an Aironet element and setting one or both of the CKIP negotiation bits." - if( (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC) || - (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK) ) - { + if ((info_element->data[IE_CISCO_FLAG_POSITION] & SUPPORT_CKIP_MIC) || + (info_element->data[IE_CISCO_FLAG_POSITION] & SUPPORT_CKIP_PK)) { network->bCkipSupported = true; - } - else - { + } else { network->bCkipSupported = false; } - } - else - { + } else { network->bWithAironetIE = false; network->bCkipSupported = false; } @@ -2057,13 +2004,10 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, data[info_element->len]; } - if(!network->atheros_cap_exist && !network->broadcom_cap_exist && - !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation) - { + if (!network->atheros_cap_exist && !network->broadcom_cap_exist && + !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation) { network->unknown_cap_exist = true; - } - else - { + } else { network->unknown_cap_exist = false; } return 0; @@ -2076,44 +2020,25 @@ static inline u8 ieee80211_SignalStrengthTranslate( u8 RetSS; // Step 1. Scale mapping. - if(CurrSS >= 71 && CurrSS <= 100) - { + if (CurrSS >= 71 && CurrSS <= 100) { RetSS = 90 + ((CurrSS - 70) / 3); - } - else if(CurrSS >= 41 && CurrSS <= 70) - { + } else if (CurrSS >= 41 && CurrSS <= 70) { RetSS = 78 + ((CurrSS - 40) / 3); - } - else if(CurrSS >= 31 && CurrSS <= 40) - { + } else if (CurrSS >= 31 && CurrSS <= 40) { RetSS = 66 + (CurrSS - 30); - } - else if(CurrSS >= 21 && CurrSS <= 30) - { + } else if (CurrSS >= 21 && CurrSS <= 30) { RetSS = 54 + (CurrSS - 20); - } - else if(CurrSS >= 5 && CurrSS <= 20) - { + } else if (CurrSS >= 5 && CurrSS <= 20) { RetSS = 42 + (((CurrSS - 5) * 2) / 3); - } - else if(CurrSS == 4) - { + } else if (CurrSS == 4) { RetSS = 36; - } - else if(CurrSS == 3) - { + } else if (CurrSS == 3) { RetSS = 27; - } - else if(CurrSS == 2) - { + } else if (CurrSS == 2) { RetSS = 18; - } - else if(CurrSS == 1) - { + } else if (CurrSS == 1) { RetSS = 9; - } - else - { + } else { RetSS = CurrSS; } //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); @@ -2193,7 +2118,7 @@ static inline int ieee80211_network_init( network->rsn_ie_len = 0; if (ieee80211_parse_info_param - (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats)) + (ieee, beacon->info_element, stats->len - sizeof(*beacon), network, stats)) return 1; network->mode = 0; @@ -2215,10 +2140,10 @@ static inline int ieee80211_network_init( return 1; } - if(network->bssht.bdSupportHT){ - if(network->mode == IEEE_A) + if (network->bssht.bdSupportHT) { + if (network->mode == IEEE_A) network->mode = IEEE_N_5G; - else if(network->mode & (IEEE_G | IEEE_B)) + else if (network->mode & (IEEE_G | IEEE_B)) network->mode = IEEE_N_24G; } if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) @@ -2226,7 +2151,7 @@ static inline int ieee80211_network_init( stats->signal = 30 + (stats->SignalStrength * 70) / 100; //stats->signal = ieee80211_SignalStrengthTranslate(stats->signal); - stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25; + stats->noise = ieee80211_translate_todbm((u8)(100 - stats->signal)) - 25; memcpy(&network->stats, stats, sizeof(network->stats)); @@ -2264,8 +2189,7 @@ static inline void update_network(struct ieee80211_network *dst, dst->rates_len = src->rates_len; memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); dst->rates_ex_len = src->rates_ex_len; - if (src->ssid_len > 0) - { + if (src->ssid_len > 0) { memset(dst->ssid, 0, dst->ssid_len); dst->ssid_len = src->ssid_len; memcpy(dst->ssid, src->ssid, src->ssid_len); @@ -2274,8 +2198,7 @@ static inline void update_network(struct ieee80211_network *dst, dst->flags = src->flags; dst->time_stamp[0] = src->time_stamp[0]; dst->time_stamp[1] = src->time_stamp[1]; - if (src->flags & NETWORK_HAS_ERP_VALUE) - { + if (src->flags & NETWORK_HAS_ERP_VALUE) { dst->erp_value = src->erp_value; dst->berp_info_valid = src->berp_info_valid = true; } @@ -2290,10 +2213,10 @@ static inline void update_network(struct ieee80211_network *dst, dst->bssht.bdSupportHT = src->bssht.bdSupportHT; dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation; - dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen; - memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen); - dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen; - memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen); + dst->bssht.bdHTCapLen = src->bssht.bdHTCapLen; + memcpy(dst->bssht.bdHTCapBuf, src->bssht.bdHTCapBuf, src->bssht.bdHTCapLen); + dst->bssht.bdHTInfoLen = src->bssht.bdHTInfoLen; + memcpy(dst->bssht.bdHTInfoBuf, src->bssht.bdHTInfoBuf, src->bssht.bdHTInfoLen); dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer; dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime; dst->broadcom_cap_exist = src->broadcom_cap_exist; @@ -2312,7 +2235,7 @@ static inline void update_network(struct ieee80211_network *dst, qos_active = dst->qos_data.active; //old_param = dst->qos_data.old_param_count; old_param = dst->qos_data.param_count; - if(dst->flags & NETWORK_HAS_QOS_MASK) + if (dst->flags & NETWORK_HAS_QOS_MASK) memcpy(&dst->qos_data, &src->qos_data, sizeof(struct ieee80211_qos_data)); else { @@ -2322,7 +2245,7 @@ static inline void update_network(struct ieee80211_network *dst, if (dst->qos_data.supported == 1) { dst->QoS_Enable = 1; - if(dst->ssid_len) + if (dst->ssid_len) IEEE80211_DEBUG_QOS ("QoS the network %s is QoS supported\n", dst->ssid); @@ -2335,11 +2258,11 @@ static inline void update_network(struct ieee80211_network *dst, /* dst->last_associate is not overwritten */ dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame. - if (src->wmm_param[0].aci_aifsn|| \ - src->wmm_param[1].aci_aifsn|| \ - src->wmm_param[2].aci_aifsn|| \ + if (src->wmm_param[0].aci_aifsn || \ + src->wmm_param[1].aci_aifsn || \ + src->wmm_param[2].aci_aifsn || \ src->wmm_param[3].aci_aifsn) { - memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); } //dst->QoS_Enable = src->QoS_Enable; #ifdef THOMAS_TURBO @@ -2429,46 +2352,34 @@ static inline void ieee80211_process_probe_response( if (!is_legal_channel(ieee, network->channel)) goto out; - if (ieee->bGlobalDomain) - { - if (fc == IEEE80211_STYPE_PROBE_RESP) - { - // Case 1: Country code - if(IS_COUNTRY_IE_VALID(ieee) ) - { + if (ieee->bGlobalDomain) { + if (fc == IEEE80211_STYPE_PROBE_RESP) { + if (IS_COUNTRY_IE_VALID(ieee)) { + // Case 1: Country code if (!is_legal_channel(ieee, network->channel)) { printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network->channel); goto out; } - } - // Case 2: No any country code. - else - { + } else { + // Case 2: No any country code. // Filter over channel ch12~14 - if (network->channel > 11) - { + if (network->channel > 11) { printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network->channel); goto out; } } - } - else - { - // Case 1: Country code - if(IS_COUNTRY_IE_VALID(ieee) ) - { + } else { + if (IS_COUNTRY_IE_VALID(ieee)) { + // Case 1: Country code if (!is_legal_channel(ieee, network->channel)) { - printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network->channel); + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network->channel); goto out; } - } - // Case 2: No any country code. - else - { + } else { + // Case 2: No any country code. // Filter over channel ch12~14 - if (network->channel > 14) - { - printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network->channel); + if (network->channel > 14) { + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network->channel); goto out; } } @@ -2490,19 +2401,17 @@ static inline void ieee80211_process_probe_response( if (is_same_network(&ieee->current_network, network, ieee)) { update_network(&ieee->current_network, network); if ((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G) - && ieee->current_network.berp_info_valid){ - if(ieee->current_network.erp_value& ERP_UseProtection) - ieee->current_network.buseprotection = true; - else - ieee->current_network.buseprotection = false; + && ieee->current_network.berp_info_valid){ + if (ieee->current_network.erp_value & ERP_UseProtection) + ieee->current_network.buseprotection = true; + else + ieee->current_network.buseprotection = false; } - if(is_beacon(beacon->header.frame_ctl)) - { - if(ieee->state == IEEE80211_LINKED) + if (is_beacon(beacon->header.frame_ctl)) { + if (ieee->state == IEEE80211_LINKED) ieee->LinkDetectInfo.NumRecvBcnInPeriod++; - } - else //hidden AP - network->flags = (~NETWORK_EMPTY_ESSID & network->flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags); + } else //hidden AP + network->flags = (~NETWORK_EMPTY_ESSID & network->flags) | (NETWORK_EMPTY_ESSID & ieee->current_network.flags); } list_for_each_entry(target, &ieee->network_list, list) { @@ -2543,8 +2452,8 @@ static inline void ieee80211_process_probe_response( #endif memcpy(target, network, sizeof(*target)); list_add_tail(&target->list, &ieee->network_list); - if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) - ieee80211_softmac_new_net(ieee,network); + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) + ieee80211_softmac_new_net(ieee, network); } else { IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", escape_essid(target->ssid, @@ -2559,26 +2468,26 @@ static inline void ieee80211_process_probe_response( */ renew = !time_after(target->last_scanned + ieee->scan_age, jiffies); //YJ,add,080819,for hidden ap - if(is_beacon(beacon->header.frame_ctl) == 0) - network->flags = (~NETWORK_EMPTY_ESSID & network->flags)|(NETWORK_EMPTY_ESSID & target->flags); + if (is_beacon(beacon->header.frame_ctl) == 0) + network->flags = (~NETWORK_EMPTY_ESSID & network->flags) | (NETWORK_EMPTY_ESSID & target->flags); //if(strncmp(network->ssid, "linksys-c",9) == 0) // printk("====>2 network->ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network->ssid, network->flags, target->ssid, target->flags); - if(((network->flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ + if (((network->flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ && (((network->ssid_len > 0) && (strncmp(target->ssid, network->ssid, network->ssid_len)))\ - ||((ieee->current_network.ssid_len == network->ssid_len) && (strncmp(ieee->current_network.ssid, network->ssid, network->ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK)))) + || ((ieee->current_network.ssid_len == network->ssid_len) && (strncmp(ieee->current_network.ssid, network->ssid, network->ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK)))) renew = 1; //YJ,add,080819,for hidden ap,end update_network(target, network); - if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) - ieee80211_softmac_new_net(ieee,network); + if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) + ieee80211_softmac_new_net(ieee, network); } spin_unlock_irqrestore(&ieee->lock, flags); if (is_beacon(beacon->header.frame_ctl) && is_same_network(&ieee->current_network, network, ieee) && \ (ieee->state == IEEE80211_LINKED)) { if (ieee->handle_beacon) - ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network); + ieee->handle_beacon(ieee->dev, beacon, &ieee->current_network); } out: diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index e0da0900a4f7..33a6af7aad22 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -743,7 +743,6 @@ static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - crypt = ieee->crypt[ieee->tx_keyidx]; if (encrypt) beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c index 4a8d16a45fc5..b1baaa18b129 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c @@ -42,8 +42,8 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info /* if setting by freq convert to channel */ if (fwrq->e == 1) { - if ((fwrq->m >= (int) 2.412e8 && - fwrq->m <= (int) 2.487e8)) { + if ((fwrq->m >= (int)2.412e8 && + fwrq->m <= (int)2.487e8)) { int f = fwrq->m / 100000; int c = 0; @@ -92,7 +92,7 @@ int ieee80211_wx_get_freq(struct ieee80211_device *ieee, if (ieee->current_network.channel == 0) return -1; /* NM 0.7.0 will not accept channel any more. */ - fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000; + fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel - 1] * 100000; fwrq->e = 1; /* fwrq->m = ieee->current_network.channel; */ /* fwrq->e = 0; */ @@ -220,7 +220,7 @@ int ieee80211_wx_set_rate(struct ieee80211_device *ieee, u32 target_rate = wrqu->bitrate.value; - ieee->rate = target_rate/100000; + ieee->rate = target_rate / 100000; /* FIXME: we might want to limit rate also in management protocols. */ return 0; } @@ -415,9 +415,9 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee, if (wrqu->essid.flags && wrqu->essid.length) { /* first flush current network.ssid */ - len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; - strncpy(ieee->current_network.ssid, extra, len+1); - ieee->current_network.ssid_len = len+1; + len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE; + strncpy(ieee->current_network.ssid, extra, len + 1); + ieee->current_network.ssid_len = len + 1; ieee->ssid_set = 1; } else { ieee->ssid_set = 0; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index fc6eb97801e1..f0b6b8372f91 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -214,7 +214,8 @@ int ieee80211_encrypt_fragment( } -void ieee80211_txb_free(struct ieee80211_txb *txb) { +void ieee80211_txb_free(struct ieee80211_txb *txb) +{ //int i; if (unlikely(!txb)) return; @@ -293,7 +294,7 @@ static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee, struct tx_ts_record *pTxTs = NULL; struct rtl_80211_hdr_1addr *hdr = (struct rtl_80211_hdr_1addr *)skb->data; - if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) return; if (!IsQoSDataFrame(skb->data)) return; @@ -301,13 +302,6 @@ static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee, if (is_multicast_ether_addr(hdr->addr1)) return; //check packet and mode later -#ifdef TO_DO_LIST - if (pTcb->PacketLength >= 4096) - return; - // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation. - if (!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter)) - return; -#endif if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) { return; } @@ -333,8 +327,7 @@ static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee, } } FORCED_AGG_SETTING: - switch (pHTInfo->ForcedAMPDUMode ) - { + switch (pHTInfo->ForcedAMPDUMode) { case HT_AGG_AUTO: break; @@ -372,7 +365,7 @@ ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, struct cb_desc *tcb_ tcb_desc->bUseShortGI = false; - if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) return; if (pHTInfo->bForcedShortGI) { @@ -380,9 +373,9 @@ ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, struct cb_desc *tcb_ return; } - if ((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz) + if ((pHTInfo->bCurBW40MHz == true) && pHTInfo->bCurShortGI40MHz) tcb_desc->bUseShortGI = true; - else if ((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz) + else if ((pHTInfo->bCurBW40MHz == false) && pHTInfo->bCurShortGI20MHz) tcb_desc->bUseShortGI = true; } @@ -393,16 +386,16 @@ static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, tcb_desc->bPacketBW = false; - if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) return; if (tcb_desc->bMulticast || tcb_desc->bBroadcast) return; - if ((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel. + if ((tcb_desc->data_rate & 0x80) == 0) // If using legacy rate, it shall use 20MHz channel. return; //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance - if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz) + if (pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz) tcb_desc->bPacketBW = true; return; } @@ -418,25 +411,21 @@ static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate. tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz - if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts + if (tcb_desc->bBroadcast || tcb_desc->bMulticast) //only unicast frame will use rts/cts return; - if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA. + if (is_broadcast_ether_addr(skb->data + 16)) //check addr3 as infrastructure add3 is DA. return; - if (ieee->mode < IEEE_N_24G) //b, g mode - { + if (ieee->mode < IEEE_N_24G) /* b, g mode */ { // (1) RTS_Threshold is compared to the MPDU, not MSDU. // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. // Other fragments are protected by previous fragment. // So we only need to check the length of first fragment. - if (skb->len > ieee->rts) - { + if (skb->len > ieee->rts) { tcb_desc->bRTSEnable = true; tcb_desc->rts_rate = MGN_24M; - } - else if (ieee->current_network.buseprotection) - { + } else if (ieee->current_network.buseprotection) { // Use CTS-to-SELF in protection mode. tcb_desc->bRTSEnable = true; tcb_desc->bCTSEnable = true; @@ -444,43 +433,35 @@ static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, } //otherwise return; return; - } - else - {// 11n High throughput case. + } else { // 11n High throughput case. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - while (true) - { + while (true) { //check ERP protection - if (ieee->current_network.buseprotection) - {// CTS-to-SELF + if (ieee->current_network.buseprotection) {// CTS-to-SELF tcb_desc->bRTSEnable = true; tcb_desc->bCTSEnable = true; tcb_desc->rts_rate = MGN_24M; break; } //check HT op mode - if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) - { + if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) { u8 HTOpMode = pHTInfo->CurrentOpMode; - if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) || - (!pHTInfo->bCurBW40MHz && HTOpMode == 3) ) - { + if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) || + (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) { tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. tcb_desc->bRTSEnable = true; break; } } //check rts - if (skb->len > ieee->rts) - { + if (skb->len > ieee->rts) { tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. tcb_desc->bRTSEnable = true; break; } //to do list: check MIMO power save condition. //check AMPDU aggregation for TXOP - if(tcb_desc->bAMPDUEnable) - { + if (tcb_desc->bAMPDUEnable) { tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily @@ -488,8 +469,7 @@ static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, break; } //check IOT action - if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) - { + if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) { tcb_desc->bCTSEnable = true; tcb_desc->rts_rate = MGN_24M; tcb_desc->bRTSEnable = true; @@ -508,7 +488,7 @@ static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) tcb_desc->bUseShortPreamble = true; if (ieee->mode == IW_MODE_MASTER) - goto NO_PROTECTION; + goto NO_PROTECTION; return; NO_PROTECTION: tcb_desc->bRTSEnable = false; @@ -522,27 +502,12 @@ NO_PROTECTION: static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, struct cb_desc *tcb_desc) { -#ifdef TO_DO_LIST - if (!IsDataFrame(pFrame)) { - pTcb->bTxDisableRateFallBack = true; - pTcb->bTxUseDriverAssingedRate = true; - pTcb->RATRIndex = 7; - return; - } - - if (pMgntInfo->ForcedDataRate!= 0) { - pTcb->bTxDisableRateFallBack = true; - pTcb->bTxUseDriverAssingedRate = true; - return; - } -#endif if (ieee->bTxDisableRateFallBack) tcb_desc->bTxDisableRateFallBack = true; if (ieee->bTxUseDriverAssingedRate) tcb_desc->bTxUseDriverAssingedRate = true; - if (!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate) - { + if (!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate) { if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) tcb_desc->RATRIndex = 0; } @@ -553,11 +518,9 @@ static void ieee80211_query_seqnum(struct ieee80211_device *ieee, { if (is_multicast_ether_addr(dst)) return; - if (IsQoSDataFrame(skb->data)) //we deal qos data only - { + if (IsQoSDataFrame(skb->data)) /* we deal qos data only */ { struct tx_ts_record *pTS = NULL; - if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, skb->priority, TX_DIR, true)) - { + if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, skb->priority, TX_DIR, true)) { return; } pTS->tx_cur_seq = (pTS->tx_cur_seq + 1) % 4096; @@ -592,7 +555,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) /* If there is no driver handler to take the TXB, dont' bother * creating it... */ - if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))|| + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) || ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name); @@ -631,7 +594,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) /* Save source and destination addresses */ memcpy(&dest, skb->data, ETH_ALEN); - memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); + memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN); /* Advance the SKB to the start of the payload */ skb_pull(skb, sizeof(struct ethhdr)); @@ -646,7 +609,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) fc = IEEE80211_FTYPE_DATA; //if(ieee->current_network.QoS_Enable) - if(qos_actived) + if (qos_actived) fc |= IEEE80211_STYPE_QOS_DATA; else fc |= IEEE80211_STYPE_DATA; @@ -740,7 +703,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i < nr_frags; i++) { skb_frag = txb->fragments[i]; tcb_desc = (struct cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE); - if(qos_actived){ + if (qos_actived) { skb_frag->priority = skb->priority;//UP2AC(skb->priority); tcb_desc->queue_index = UP2AC(skb->priority); } else { @@ -749,15 +712,13 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) } skb_reserve(skb_frag, ieee->tx_headroom); - if (encrypt){ + if (encrypt) { if (ieee->hwsec_active) tcb_desc->bHwSec = 1; else tcb_desc->bHwSec = 0; skb_reserve(skb_frag, crypt->ops->extra_prefix_len); - } - else - { + } else { tcb_desc->bHwSec = 0; } frag_hdr = skb_put_data(skb_frag, &header, hdr_len); @@ -775,12 +736,11 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) bytes = bytes_last_frag; } //if(ieee->current_network.QoS_Enable) - if(qos_actived) - { + if (qos_actived) { // add 1 only indicate to corresponding seq number control 2006/7/12 - frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i); + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority) + 1] << 4 | i); } else { - frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4 | i); } /* Put a SNAP header on the first fragment */ @@ -806,17 +766,16 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) skb_put(skb_frag, 4); } - if(qos_actived) - { - if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) - ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; - else - ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; + if (qos_actived) { + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; + else + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; } else { - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; } } else { if (unlikely(skb->len < sizeof(struct rtl_80211_hdr_3addr))) { @@ -826,7 +785,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) } txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC); - if(!txb){ + if (!txb) { printk(KERN_WARNING "%s: Could not allocate TXB\n", ieee->dev->name); goto failed; @@ -839,8 +798,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) success: //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place. - if (txb) - { + if (txb) { struct cb_desc *tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bTxEnableFwCalcDur = 1; if (is_multicast_ether_addr(header.addr1)) @@ -862,9 +820,9 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&ieee->lock, flags); dev_kfree_skb_any(skb); if (txb) { - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){ + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) { ieee80211_softmac_xmit(txb, ieee); - }else{ + } else { if ((*ieee->hard_start_xmit)(txb, dev) == 0) { stats->tx_packets++; stats->tx_bytes += __le16_to_cpu(txb->payload_size); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index be08cd1d37a7..9dd5c04181ea 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -70,10 +70,10 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, } /* Add the protocol name */ iwe.cmd = SIOCGIWNAME; - for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) { + for (i = 0; i < ARRAY_SIZE(ieee80211_modes); i++) { if (network->mode & BIT(i)) { - sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size); - pname +=ieee80211_modes[i].mode_size; + sprintf(pname, ieee80211_modes[i].mode_string, ieee80211_modes[i].mode_size); + pname += ieee80211_modes[i].mode_size; } } *pname = '\0'; @@ -130,8 +130,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, max_rate = rate; } - if (network->mode >= IEEE_N_24G)//add N rate here; - { + if (network->mode >= IEEE_N_24G) /* add N rate here */ { struct ht_capability_ele *ht_cap = NULL; bool is40M = false, isShortGI = false; u8 max_mcs = 0; @@ -139,13 +138,13 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[4]; else ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[0]; - is40M = (ht_cap->ChlWidth)?1:0; - isShortGI = (ht_cap->ChlWidth)? - ((ht_cap->ShortGI40Mhz)?1:0): - ((ht_cap->ShortGI20Mhz)?1:0); + is40M = (ht_cap->ChlWidth) ? 1 : 0; + isShortGI = (ht_cap->ChlWidth) ? + ((ht_cap->ShortGI40Mhz) ? 1 : 0) : + ((ht_cap->ShortGI20Mhz) ? 1 : 0); max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL); - rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f]; + rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f]; if (rate > max_rate) max_rate = rate; } @@ -178,7 +177,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, iwe.u.data.length = p - custom; if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); + start = iwe_stream_add_point(info, start, stop, &iwe, custom); if (ieee->wpa_enabled && network->wpa_ie_len) { char buf[MAX_WPA_IE_LEN * 2 + 30]; @@ -219,7 +218,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100)); iwe.u.data.length = p - custom; if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); + start = iwe_stream_add_point(info, start, stop, &iwe, custom); return start; } @@ -243,7 +242,7 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee, list_for_each_entry(network, &ieee->network_list, list) { i++; - if((stop-ev)<200) { + if ((stop - ev) < 200) { err = -E2BIG; break; } @@ -454,7 +453,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee, IEEE80211_DEBUG_WX("GET_ENCODE\n"); - if(ieee->iw_mode == IW_MODE_MONITOR) + if (ieee->iw_mode == IW_MODE_MONITOR) return -1; key = erq->flags & IW_ENCODE_INDEX; @@ -571,7 +570,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, ret = -EINVAL; goto done; } - printk("alg name:%s\n",alg); + printk("alg name:%s\n", alg); ops = try_then_request_module(ieee80211_get_crypto_ops(alg), module); if (!ops) { @@ -688,7 +687,7 @@ int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, ext->key_len = 0; encoding->flags |= IW_ENCODE_DISABLED; } else { - if (strcmp(crypt->ops->name, "WEP") == 0 ) + if (strcmp(crypt->ops->name, "WEP") == 0) ext->alg = IW_ENCODE_ALG_WEP; else if (strcmp(crypt->ops->name, "TKIP")) ext->alg = IW_ENCODE_ALG_TKIP; @@ -712,7 +711,7 @@ int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct iw_mlme *mlme = (struct iw_mlme *) extra; + struct iw_mlme *mlme = (struct iw_mlme *)extra; switch (mlme->cmd) { case IW_MLME_DEAUTH: case IW_MLME_DISASSOC: @@ -765,7 +764,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, break; case IW_AUTH_WPA_ENABLED: - ieee->wpa_enabled = (data->value)?1:0; + ieee->wpa_enabled = (data->value) ? 1 : 0; break; case IW_AUTH_RX_UNENCRYPTED_EAPOL: @@ -785,14 +784,14 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) { u8 *buf; - if (len>MAX_WPA_IE_LEN || (len && !ie)) { - // printk("return error out, len:%d\n", len); - return -EINVAL; + if (len > MAX_WPA_IE_LEN || (len && !ie)) { + //printk("return error out, len:%d\n", len); + return -EINVAL; } if (len) { - if (len != ie[1]+2) { + if (len != ie[1] + 2) { printk("len:%zu, ie:%d\n", len, ie[1]); return -EINVAL; } diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 53869b3c985c..379a2ccf4d9f 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -162,7 +162,7 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, s tag += 2; } - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); return skb; //return NULL; } @@ -229,7 +229,7 @@ static struct sk_buff *ieee80211_DELBA( put_unaligned_le16(ReasonCode, tag); tag += 2; - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); if (net_ratelimit()) IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __func__); @@ -331,9 +331,9 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) return -1; } - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); - req = (struct rtl_80211_hdr_3addr *) skb->data; + req = (struct rtl_80211_hdr_3addr *)skb->data; tag = (u8 *)req; dst = &req->addr2[0]; tag += sizeof(struct rtl_80211_hdr_3addr); @@ -556,7 +556,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) return -1; } - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); delba = (struct rtl_80211_hdr_3addr *)skb->data; dst = &delba->addr2[0]; pDelBaParamSet = (union delba_param_set *)&delba->payload[2]; @@ -643,7 +643,7 @@ TsInitDelBA(struct ieee80211_device *ieee, struct ts_common_info *pTsCommonInfo, ieee80211_send_DELBA( ieee, pTsCommonInfo->addr, - (pTxTs->tx_admitted_ba_record.valid)?(&pTxTs->tx_admitted_ba_record):(&pTxTs->tx_pending_ba_record), + (pTxTs->tx_admitted_ba_record.valid) ? (&pTxTs->tx_admitted_ba_record) : (&pTxTs->tx_pending_ba_record), TxRxSelect, DELBA_REASON_END_BA); } else if (TxRxSelect == RX_DIR) { diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h index b7769bca9740..79346a00af09 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h @@ -253,10 +253,10 @@ extern u8 MCS_FILTER_1SS[16]; /* 2007/07/12 MH We only define legacy and HT wireless mode now. */ #define LEGACY_WIRELESS_MODE IEEE_MODE_MASK -#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \ - ((WirelessMode & (LEGACY_WIRELESS_MODE)) != 0) ?\ - (LegacyRate) :\ - (PICK_RATE(LegacyRate, HTRate)) +#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \ + ((WirelessMode & (LEGACY_WIRELESS_MODE)) != 0) ? \ + (LegacyRate) : \ + (PICK_RATE(LegacyRate, HTRate)) // MCS Bw 40 {1~7, 12~15,32} #define RATE_ADPT_1SS_MASK 0xFF @@ -270,11 +270,10 @@ typedef enum _HT_AGGRE_SIZE { HT_AGG_SIZE_16K = 1, HT_AGG_SIZE_32K = 2, HT_AGG_SIZE_64K = 3, -}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E; +} HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E; /* Indicate different AP vendor for IOT issue */ -typedef enum _HT_IOT_PEER -{ +typedef enum _HT_IOT_PEER { HT_IOT_PEER_UNKNOWN = 0, HT_IOT_PEER_REALTEK = 1, HT_IOT_PEER_BROADCOM = 2, @@ -282,7 +281,7 @@ typedef enum _HT_IOT_PEER HT_IOT_PEER_ATHEROS = 4, HT_IOT_PEER_CISCO = 5, HT_IOT_PEER_MAX = 6 -}HT_IOT_PEER_E, *PHTIOT_PEER_E; +} HT_IOT_PEER_E, *PHTIOT_PEER_E; /* * IOT Action for different AP @@ -298,6 +297,6 @@ typedef enum _HT_IOT_ACTION { HT_IOT_ACT_CDD_FSYNC = 0x00000080, HT_IOT_ACT_PURE_N_MODE = 0x00000100, HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, -}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E; +} HT_IOT_ACTION_E, *PHT_IOT_ACTION_E; #endif //_RTL819XU_HTTYPE_H_ diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c index c73a8058cf87..dba3f2db9f48 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c @@ -93,10 +93,6 @@ void HTUpdateDefaultSetting(struct ieee80211_device *ieee) ieee->bTxDisableRateFallBack = 0; ieee->bTxUseDriverAssingedRate = 0; -#ifdef TO_DO_LIST - // 8190 only. Assign duration operation mode to firmware - pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur; -#endif /* * 8190 only, Realtek proprietary aggregation mode * Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index 59d179ae7ad2..5cee1031a27c 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -105,7 +105,7 @@ static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo) { eth_zero_addr(pTsCommonInfo->addr); memset(&pTsCommonInfo->t_spec, 0, sizeof(struct tspec_body)); - memset(&pTsCommonInfo->t_class, 0, sizeof(union qos_tclas)*TCLAS_NUM); + memset(&pTsCommonInfo->t_class, 0, sizeof(union qos_tclas) * TCLAS_NUM); pTsCommonInfo->t_clas_proc = 0; pTsCommonInfo->t_clas_num = 0; } @@ -180,14 +180,12 @@ void TSInitialize(struct ieee80211_device *ieee) } // Initialize unused Rx Reorder List. INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); -//#ifdef TO_DO_LIST for (count = 0; count < REORDER_ENTRY_NUM; count++) { list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List); - if (count == (REORDER_ENTRY_NUM-1)) + if (count == (REORDER_ENTRY_NUM - 1)) break; - pRxReorderEntry = &ieee->RxReorderEntry[count+1]; + pRxReorderEntry = &ieee->RxReorderEntry[count + 1]; } -//#endif } static void AdmitTS(struct ieee80211_device *ieee, @@ -259,7 +257,7 @@ static struct ts_common_info *SearchAdmitTRStream(struct ieee80211_device *ieee, } if (&pRet->list != psearch_list) - return pRet ; + return pRet; else return NULL; } @@ -367,8 +365,8 @@ bool GetTs( (&ieee->Rx_TS_Admit_List); enum direction_value Dir = (ieee->iw_mode == IW_MODE_MASTER) ? - ((TxRxSelect == TX_DIR)?DIR_DOWN:DIR_UP) : - ((TxRxSelect == TX_DIR)?DIR_UP:DIR_DOWN); + ((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) : + ((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN); IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n"); if (!list_empty(pUnusedList)) { (*ppTS) = list_entry(pUnusedList->next, struct ts_common_info, list); @@ -417,7 +415,6 @@ static void RemoveTsEntry(struct ieee80211_device *ieee, struct ts_common_info * TsInitDelBA(ieee, pTs, TxRxSelect); if (TxRxSelect == RX_DIR) { -//#ifdef TO_DO_LIST struct rx_reorder_entry *pRxReorderEntry; struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs; if (timer_pending(&pRxTS->rx_pkt_pending_timer)) @@ -445,7 +442,6 @@ static void RemoveTsEntry(struct ieee80211_device *ieee, struct ts_common_info * spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); } -//#endif } else { struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs; del_timer_sync(&pTxTS->ts_add_ba_timer); @@ -530,7 +526,7 @@ void TsStartAddBaProcess(struct ieee80211_device *ieee, struct tx_ts_record *pTx jiffies + msecs_to_jiffies(TS_ADDBA_DELAY)); } else { IEEE80211_DEBUG(IEEE80211_DL_BA, "%s: Immediately Start ADDBA now!!\n", __func__); - mod_timer(&pTxTS->ts_add_ba_timer, jiffies+10); //set 10 ticks + mod_timer(&pTxTS->ts_add_ba_timer, jiffies + 10); //set 10 ticks } } else { IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __func__); diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c index de83daa0c9ed..2527cea60e3e 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.c +++ b/drivers/staging/rtl8192u/r8180_93cx6.c @@ -39,7 +39,6 @@ static void eprom_cs(struct net_device *dev, short bit) udelay(EPROM_DELAY); } - static void eprom_ck_cycle(struct net_device *dev) { u8 cmdreg; @@ -58,7 +57,6 @@ static void eprom_ck_cycle(struct net_device *dev) udelay(EPROM_DELAY); } - static void eprom_w(struct net_device *dev, short bit) { u8 cmdreg; @@ -76,7 +74,6 @@ static void eprom_w(struct net_device *dev, short bit) udelay(EPROM_DELAY); } - static short eprom_r(struct net_device *dev) { u8 bit; @@ -94,7 +91,6 @@ static short eprom_r(struct net_device *dev) return 0; } - static void eprom_send_bits_string(struct net_device *dev, short b[], int len) { int i; @@ -105,7 +101,6 @@ static void eprom_send_bits_string(struct net_device *dev, short b[], int len) } } - int eprom_read(struct net_device *dev, u32 addr) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -119,7 +114,7 @@ int eprom_read(struct net_device *dev, u32 addr) ret = 0; /* enable EPROM programming */ write_nic_byte_E(dev, EPROM_CMD, - (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT)); + (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT)); force_pci_posting(dev); udelay(EPROM_DELAY); @@ -162,7 +157,7 @@ int eprom_read(struct net_device *dev, u32 addr) if (err < 0) return err; - ret |= err<<(15-i); + ret |= err << (15 - i); } eprom_cs(dev, 0); @@ -170,6 +165,6 @@ int eprom_read(struct net_device *dev, u32 addr) /* disable EPROM programming */ write_nic_byte_E(dev, EPROM_CMD, - (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT)); + (EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT)); return ret; } diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c index 92de92a3325a..b169460b9f26 100644 --- a/drivers/staging/rtl8192u/r8190_rtl8256.c +++ b/drivers/staging/rtl8192u/r8190_rtl8256.c @@ -42,9 +42,9 @@ void phy_set_rf8256_bandwidth(struct net_device *dev, enum ht_channel_width Band switch (Bandwidth) { case HT_CHANNEL_WIDTH_20: - if (priv->card_8192_version == VERSION_819XU_A - || priv->card_8192_version - == VERSION_819XU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */ + if (priv->card_8192_version == VERSION_819XU_A || + priv->card_8192_version == + VERSION_819XU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */ rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0b, bMask12Bits, 0x100); /* phy para:1ba */ @@ -79,10 +79,10 @@ void phy_set_rf8256_bandwidth(struct net_device *dev, enum ht_channel_width Band default: RT_TRACE(COMP_ERR, "phy_set_rf8256_bandwidth(): unknown Bandwidth: %#X\n", Bandwidth); break; - } } } + /*-------------------------------------------------------------------------- * Overview: Interface to config 8256 * Input: struct net_device* dev @@ -101,6 +101,7 @@ void phy_rf8256_config(struct net_device *dev) /* Config BB and RF */ phy_rf8256_config_para_file(dev); } + /*-------------------------------------------------------------------------- * Overview: Interface to config 8256 * Input: struct net_device* dev @@ -137,12 +138,12 @@ static void phy_rf8256_config_para_file(struct net_device *dev) break; case RF90_PATH_B: case RF90_PATH_D: - u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16); + u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV << 16); break; } /*----Set RF_ENV enable----*/ - rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); + rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1); /*----Set RF_ENV output high----*/ rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); @@ -151,7 +152,7 @@ static void phy_rf8256_config_para_file(struct net_device *dev) rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 */ rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? */ - rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e) eRFPath, 0x0, bMask12Bits, 0xbf); + rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0, bMask12Bits, 0xbf); /* Check RF block (for FPGA platform only)---- * TODO: this function should be removed on ASIC , Emily 2007.2.2 @@ -207,7 +208,7 @@ static void phy_rf8256_config_para_file(struct net_device *dev) break; case RF90_PATH_B: case RF90_PATH_D: - rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); + rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV << 16, u4RegValue); break; } @@ -215,7 +216,6 @@ static void phy_rf8256_config_para_file(struct net_device *dev) RT_TRACE(COMP_ERR, "phy_rf8256_config_para_file():Radio[%d] Fail!!", eRFPath); goto phy_RF8256_Config_ParaFile_Fail; } - } RT_TRACE(COMP_PHY, "PHY Initialization Success\n"); @@ -225,11 +225,11 @@ phy_RF8256_Config_ParaFile_Fail: RT_TRACE(COMP_ERR, "PHY Initialization failed\n"); } - void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel) { u32 TxAGC = 0; struct r8192_priv *priv = ieee80211_priv(dev); + TxAGC = powerlevel; if (priv->bDynamicTxLowPower) { @@ -244,7 +244,6 @@ void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel) rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); } - void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -255,16 +254,16 @@ void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel) u8 byte0, byte1, byte2, byte3; powerBase0 = powerlevel + priv->TxPowerDiff; /* OFDM rates */ - powerBase0 = (powerBase0<<24) | (powerBase0<<16) | (powerBase0<<8) | powerBase0; + powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | (powerBase0 << 8) | powerBase0; powerBase1 = powerlevel; /* MCS rates */ - powerBase1 = (powerBase1<<24) | (powerBase1<<16) | (powerBase1<<8) | powerBase1; + powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; for (index = 0; index < 6; index++) { - writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index < 2)?powerBase0:powerBase1); + writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index < 2) ? powerBase0 : powerBase1); byte0 = (u8)(writeVal & 0x7f); - byte1 = (u8)((writeVal & 0x7f00)>>8); - byte2 = (u8)((writeVal & 0x7f0000)>>16); - byte3 = (u8)((writeVal & 0x7f000000)>>24); + byte1 = (u8)((writeVal & 0x7f00) >> 8); + byte2 = (u8)((writeVal & 0x7f0000) >> 16); + byte3 = (u8)((writeVal & 0x7f000000) >> 24); if (byte0 > 0x24) /* Max power index = 0x24 */ @@ -278,7 +277,7 @@ void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel) /* for tx power track */ if (index == 3) { - writeVal_tmp = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0; + writeVal_tmp = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0; priv->Pwr_Track = writeVal_tmp; } @@ -288,10 +287,9 @@ void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel) */ writeVal = 0x03030303; } else { - writeVal = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0; - } - rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); + writeVal = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0; + } + rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); } return; - } diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index fe1f279ca368..2821411878ce 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2076,14 +2076,6 @@ static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode) wireless_mode = WIRELESS_MODE_B; } } -#ifdef TO_DO_LIST - /* TODO: this function doesn't work well at this time, - * we should wait for FPGA - */ - ActUpdateChannelAccessSetting( - pAdapter, pHalData->CurrentWirelessMode, - &pAdapter->MgntInfo.Info8185.ChannelAccessSetting); -#endif priv->ieee80211->mode = wireless_mode; if (wireless_mode == WIRELESS_MODE_N_24G || @@ -2096,7 +2088,7 @@ static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode) } /* init priv variables here. only non_zero value should be initialized here. */ -static void rtl8192_init_priv_variable(struct net_device *dev) +static int rtl8192_init_priv_variable(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); u8 i; @@ -2159,12 +2151,6 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->ieee80211->InitialGainHandler = InitialGain819xUsb; priv->card_type = USB; -#ifdef TO_DO_LIST - if (Adapter->bInHctTest) { - pHalData->ShortRetryLimit = 7; - pHalData->LongRetryLimit = 7; - } -#endif priv->ShortRetryLimit = 0x30; priv->LongRetryLimit = 0x30; priv->EarlyRxThreshold = 7; @@ -2180,34 +2166,6 @@ static void rtl8192_init_priv_variable(struct net_device *dev) * TRUE: SW provides them */ (false ? TCR_SAT : 0); -#ifdef TO_DO_LIST - if (Adapter->bInHctTest) - pHalData->ReceiveConfig = - pHalData->CSMethod | - /* accept management/data */ - RCR_AMF | RCR_ADF | - /* accept control frame for SW - * AP needs PS-poll - */ - RCR_ACF | - /* accept BC/MC/UC */ - RCR_AB | RCR_AM | RCR_APM | - /* accept ICV/CRC error - * packet - */ - RCR_AICV | RCR_ACRC32 | - /* Max DMA Burst Size per Tx - * DMA Burst, 7: unlimited. - */ - ((u32)7 << RCR_MXDMA_OFFSET) | - /* Rx FIFO Threshold, - * 7: No Rx threshold. - */ - (pHalData->EarlyRxThreshold << RCR_FIFO_OFFSET) | - (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt : 0); - else - -#endif priv->ReceiveConfig = /* accept management/data */ RCR_AMF | RCR_ADF | @@ -2223,6 +2181,8 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->AcmControl = 0; priv->pFirmware = kzalloc(sizeof(rt_firmware), GFP_KERNEL); + if (!priv->pFirmware) + return -ENOMEM; /* rx related queue */ skb_queue_head_init(&priv->rx_queue); @@ -2236,6 +2196,8 @@ static void rtl8192_init_priv_variable(struct net_device *dev) for (i = 0; i < MAX_QUEUE_SIZE; i++) skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ[i]); priv->rf_set_chan = rtl8192_phy_SwChnl; + + return 0; } /* init lock here */ @@ -2605,7 +2567,10 @@ static short rtl8192_init(struct net_device *dev) memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9); } #endif - rtl8192_init_priv_variable(dev); + err = rtl8192_init_priv_variable(dev); + if (err) + return err; + rtl8192_init_priv_lock(priv); rtl8192_init_priv_task(dev); rtl8192_get_eeprom_size(dev); @@ -2658,19 +2623,10 @@ static void rtl8192_hwconfig(struct net_device *dev) regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; break; case WIRELESS_MODE_AUTO: -#ifdef TO_DO_LIST - if (Adapter->bInHctTest) { - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - } else -#endif - { - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - } + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | + RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; break; case WIRELESS_MODE_N_24G: /* It support CCK rate by default. CCK rate will be filtered @@ -2841,48 +2797,6 @@ static bool rtl8192_adapter_start(struct net_device *dev) } RT_TRACE(COMP_INIT, "%s():after firmware download\n", __func__); -#ifdef TO_DO_LIST - if (Adapter->ResetProgress == RESET_TYPE_NORESET) { - if (pMgntInfo->RegRfOff) { /* User disable RF via registry. */ - RT_TRACE((COMP_INIT | COMP_RF), DBG_LOUD, - ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n")); - MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW); - /* Those actions will be discard in MgntActSet_RF_State - * because of the same state - */ - for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) - PHY_SetRFReg(Adapter, - (enum rf90_radio_path_e)eRFPath, - 0x4, 0xC00, 0x0); - } else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { - /* H/W or S/W RF OFF before sleep. */ - RT_TRACE((COMP_INIT | COMP_RF), DBG_LOUD, - ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", - pMgntInfo->RfOffReason)); - MgntActSet_RF_State(Adapter, - eRfOff, - pMgntInfo->RfOffReason); - } else { - pHalData->eRFPowerState = eRfOn; - pMgntInfo->RfOffReason = 0; - RT_TRACE((COMP_INIT | COMP_RF), DBG_LOUD, - ("InitializeAdapter819xUsb(): RF is on ----------\n")); - } - } else { - if (pHalData->eRFPowerState == eRfOff) { - MgntActSet_RF_State(Adapter, - eRfOff, - pMgntInfo->RfOffReason); - /* Those actions will be discard in MgntActSet_RF_State - * because of the same state - */ - for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) - PHY_SetRFReg(Adapter, - (enum rf90_radio_path_e)eRFPath, - 0x4, 0xC00, 0x0); - } - } -#endif /* config RF. */ if (priv->ResetProgress == RESET_TYPE_NORESET) { rtl8192_phy_RFConfig(dev); diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index ade14ef05730..c23e43b095d9 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -1334,7 +1334,7 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) return; } /*DbgPrint("Schedule TxPowerTrackingWorkItem\n");*/ - queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0); + queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0); TM_Trigger = 0; } diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 153d4ee0ec07..dd81d210bd49 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -231,7 +231,7 @@ bool init_firmware(struct net_device *dev) rst_opt = OPT_FIRMWARE_RESET; starting_state = FW_INIT_STEP2_DATA; } else { - RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n"); + RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n"); } /* diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index 5f04afe53d69..c04d8eca0cfb 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -516,16 +516,6 @@ static void rtl8192_phyConfigBB(struct net_device *dev, { u32 i; -#ifdef TO_DO_LIST - u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL; - - if (Adapter->bInHctTest) { - PHY_REGArrayLen = PHY_REGArrayLengthDTM; - AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM; - Rtl8190PHY_REGArray_Table = Rtl819XPHY_REGArrayDTM; - Rtl8190AGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM; - } -#endif if (ConfigType == BASEBAND_CONFIG_PHY_REG) { for (i = 0; i < PHY_REG_1T2RArrayLength; i += 2) { rtl8192_setBBreg(dev, Rtl8192UsbPHY_REG_1T2RArray[i], @@ -1059,10 +1049,6 @@ static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel) switch (priv->rf_chip) { case RF_8225: -#ifdef TO_DO_LIST - PHY_SetRF8225CckTxPower(Adapter, powerlevel); - PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G); -#endif break; case RF_8256: @@ -1160,48 +1146,6 @@ bool rtl8192_SetRFPowerState(struct net_device *dev, RT_TRACE(COMP_ERR, "Not support rf_chip(%x)\n", priv->rf_chip); break; } -#ifdef TO_DO_LIST - if (bResult) { - /* Update current RF state variable. */ - pHalData->eRFPowerState = eRFPowerState; - switch (pHalData->RFChipID) { - case RF_8256: - switch (pHalData->eRFPowerState) { - case eRfOff: - /* If Rf off reason is from IPS, - * LED should blink with no link - */ - if (pMgntInfo->RfOffReason == RF_CHANGE_BY_IPS) - Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK); - else - /* Turn off LED if RF is not ON. */ - Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF); - break; - - case eRfOn: - /* Turn on RF we are still linked, which might - * happen when we quickly turn off and on HW RF. - */ - if (pMgntInfo->bMediaConnect) - Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK); - else - /* Turn off LED if RF is not ON. */ - Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK); - break; - - default: - break; - } - break; - - default: - RT_TRACE(COMP_RF, DBG_LOUD, "%s(): Unknown RF type\n", - __func__); - break; - } - - } -#endif priv->SetRFPowerStateInProgress = false; return bResult; @@ -1628,9 +1572,6 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) /* <3> Set RF related register */ switch (priv->rf_chip) { case RF_8225: -#ifdef TO_DO_LIST - PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW); -#endif break; case RF_8256: diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index b554cf8bd679..0c3ae8495afb 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -258,7 +258,7 @@ void r8712_stop_drv_timers(struct _adapter *padapter) del_timer_sync(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer); } -static u8 init_default_value(struct _adapter *padapter) +static void init_default_value(struct _adapter *padapter) { struct registry_priv *pregistrypriv = &padapter->registrypriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; @@ -292,37 +292,41 @@ static u8 init_default_value(struct _adapter *padapter) r8712_init_registrypriv_dev_network(padapter); r8712_update_registrypriv_dev_network(padapter); /*misc.*/ - return _SUCCESS; } -u8 r8712_init_drv_sw(struct _adapter *padapter) +int r8712_init_drv_sw(struct _adapter *padapter) { - if (r8712_init_cmd_priv(&padapter->cmdpriv)) - return _FAIL; + int ret; + + ret = r8712_init_cmd_priv(&padapter->cmdpriv); + if (ret) + return ret; padapter->cmdpriv.padapter = padapter; - if (r8712_init_evt_priv(&padapter->evtpriv)) - return _FAIL; - if (r8712_init_mlme_priv(padapter) == _FAIL) - return _FAIL; + ret = r8712_init_evt_priv(&padapter->evtpriv); + if (ret) + return ret; + ret = r8712_init_mlme_priv(padapter); + if (ret) + return ret; _r8712_init_xmit_priv(&padapter->xmitpriv, padapter); _r8712_init_recv_priv(&padapter->recvpriv, padapter); memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv)); timer_setup(&padapter->securitypriv.tkip_timer, r8712_use_tkipkey_handler, 0); - if (_r8712_init_sta_priv(&padapter->stapriv)) - return _FAIL; + ret = _r8712_init_sta_priv(&padapter->stapriv); + if (ret) + return ret; padapter->stapriv.padapter = padapter; r8712_init_bcmc_stainfo(padapter); r8712_init_pwrctrl_priv(padapter); mp871xinit(padapter); - if (init_default_value(padapter) != _SUCCESS) - return _FAIL; + init_default_value(padapter); r8712_InitSwLeds(padapter); - return _SUCCESS; + return ret; } -u8 r8712_free_drv_sw(struct _adapter *padapter) +void r8712_free_drv_sw(struct _adapter *padapter) { struct net_device *pnetdev = padapter->pnetdev; @@ -337,7 +341,6 @@ u8 r8712_free_drv_sw(struct _adapter *padapter) mp871xdeinit(padapter); if (pnetdev) free_netdev(pnetdev); - return _SUCCESS; } static void enable_video_mode(struct _adapter *padapter, int cbw40_value) diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 84c4c8580f9a..215fca4abb3a 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -29,24 +29,23 @@ /*init os related resource in struct recv_priv*/ /*alloc os related resource in union recv_frame*/ -int r8712_os_recv_resource_alloc(struct _adapter *padapter, - union recv_frame *precvframe) +void r8712_os_recv_resource_alloc(struct _adapter *padapter, + union recv_frame *precvframe) { precvframe->u.hdr.pkt_newalloc = NULL; precvframe->u.hdr.pkt = NULL; - return _SUCCESS; } /*alloc os related resource in struct recv_buf*/ int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter, struct recv_buf *precvbuf) { - int res = _SUCCESS; + int res = 0; precvbuf->irp_pending = false; precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); if (!precvbuf->purb) - res = _FAIL; + res = -ENOMEM; precvbuf->pskb = NULL; precvbuf->pallocated_buf = NULL; precvbuf->pbuf = NULL; @@ -60,8 +59,8 @@ int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter, } /*free os related resource in struct recv_buf*/ -int r8712_os_recvbuf_resource_free(struct _adapter *padapter, - struct recv_buf *precvbuf) +void r8712_os_recvbuf_resource_free(struct _adapter *padapter, + struct recv_buf *precvbuf) { if (precvbuf->pskb) dev_kfree_skb_any(precvbuf->pskb); @@ -69,7 +68,6 @@ int r8712_os_recvbuf_resource_free(struct _adapter *padapter, usb_kill_urb(precvbuf->purb); usb_free_urb(precvbuf->purb); } - return _SUCCESS; } void r8712_handle_tkip_mic_err(struct _adapter *adapter, u8 bgroup) @@ -115,8 +113,8 @@ void r8712_recv_indicatepkt(struct _adapter *adapter, skb->protocol = eth_type_trans(skb, adapter->pnetdev); netif_rx(skb); recvframe->u.hdr.pkt = NULL; /* pointers to NULL before - * r8712_free_recvframe() - */ + * r8712_free_recvframe() + */ r8712_free_recvframe(recvframe, free_recv_queue); return; _recv_indicatepkt_drop: diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h index dcd3b484c793..d8c1fa74f544 100644 --- a/drivers/staging/rtl8712/recv_osdep.h +++ b/drivers/staging/rtl8712/recv_osdep.h @@ -18,22 +18,22 @@ #include "drv_types.h" #include <linux/skbuff.h> -sint _r8712_init_recv_priv(struct recv_priv *precvpriv, +void _r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter); void _r8712_free_recv_priv(struct recv_priv *precvpriv); -s32 r8712_recv_entry(union recv_frame *precv_frame); +void r8712_recv_entry(union recv_frame *precv_frame); void r8712_recv_indicatepkt(struct _adapter *adapter, union recv_frame *precv_frame); void r8712_handle_tkip_mic_err(struct _adapter *padapter, u8 bgroup); -int r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter); +void r8712_init_recv_priv(struct recv_priv *precvpriv, + struct _adapter *padapter); void r8712_free_recv_priv(struct recv_priv *precvpriv); -int r8712_os_recv_resource_alloc(struct _adapter *padapter, - union recv_frame *precvframe); +void r8712_os_recv_resource_alloc(struct _adapter *padapter, + union recv_frame *precvframe); int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter, struct recv_buf *precvbuf); -int r8712_os_recvbuf_resource_free(struct _adapter *padapter, - struct recv_buf *precvbuf); +void r8712_os_recvbuf_resource_free(struct _adapter *padapter, + struct recv_buf *precvbuf); void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); #endif diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 6a72a4ad176a..ff3cb09c57a6 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -263,11 +263,6 @@ static struct cmd_obj *cmd_hdl_filter(struct _adapter *padapter, return pcmd_r; /* if returning pcmd_r == NULL, pcmd must be free. */ } -static u8 check_cmd_fifo(struct _adapter *padapter, uint sz) -{ - return _SUCCESS; -} - u8 r8712_fw_cmd(struct _adapter *pAdapter, u32 cmd) { int pollingcnts = 50; @@ -311,7 +306,7 @@ int r8712_cmd_thread(void *context) break; if (padapter->driver_stopped || padapter->surprise_removed) break; - if (r8712_register_cmd_alive(padapter) != _SUCCESS) + if (r8712_register_cmd_alive(padapter)) continue; _next: pcmd = r8712_dequeue_cmd(&pcmdpriv->cmd_queue); @@ -359,13 +354,6 @@ _next: (pcmdpriv->cmd_seq << 24)); pcmdbuf += 2; /* 8 bytes alignment */ memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); - while (check_cmd_fifo(padapter, wr_sz) == _FAIL) { - if (padapter->driver_stopped || - padapter->surprise_removed) - break; - msleep(100); - continue; - } if (blnPending) wr_sz += 8; /* Append 8 bytes */ r8712_write_mem(padapter, RTL8712_DMA_H2CCMD, wr_sz, diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 82ddc0c3ecd4..9901815604f4 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -35,11 +35,11 @@ static u8 rfc1042_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; static void recv_tasklet(void *priv); -int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter) +void r8712_init_recv_priv(struct recv_priv *precvpriv, + struct _adapter *padapter) { int i; struct recv_buf *precvbuf; - int res = _SUCCESS; addr_t tmpaddr = 0; int alignment = 0; struct sk_buff *pskb = NULL; @@ -49,15 +49,14 @@ int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter) precvpriv->pallocated_recv_buf = kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_ATOMIC); if (!precvpriv->pallocated_recv_buf) - return _FAIL; + return; precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 - ((addr_t)(precvpriv->pallocated_recv_buf) & 3); precvbuf = (struct recv_buf *)precvpriv->precv_buf; for (i = 0; i < NR_RECVBUFF; i++) { INIT_LIST_HEAD(&precvbuf->list); spin_lock_init(&precvbuf->recvbuf_lock); - res = r8712_os_recvbuf_resource_alloc(padapter, precvbuf); - if (res == _FAIL) + if (r8712_os_recvbuf_resource_alloc(padapter, precvbuf)) break; precvbuf->ref_cnt = 0; precvbuf->adapter = padapter; @@ -83,7 +82,6 @@ int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter) } pskb = NULL; } - return res; } void r8712_free_recv_priv(struct recv_priv *precvpriv) @@ -107,7 +105,7 @@ void r8712_free_recv_priv(struct recv_priv *precvpriv) skb_queue_len(&precvpriv->free_recv_skb_queue)); } -int r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf) +void r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf) { precvbuf->transfer_len = 0; precvbuf->len = 0; @@ -118,10 +116,9 @@ int r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf) precvbuf->ptail = precvbuf->pbuf; precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ; } - return _SUCCESS; } -int r8712_free_recvframe(union recv_frame *precvframe, +void r8712_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue) { unsigned long irqL; @@ -140,7 +137,6 @@ int r8712_free_recvframe(union recv_frame *precvframe, precvpriv->free_recvframe_cnt++; } spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL); - return _SUCCESS; } static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, @@ -323,7 +319,7 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter, return prtnframe; } -static int amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe) +static void amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe) { int a_len, padding_len; u16 eth_type, nSubframe_Length; @@ -421,7 +417,6 @@ static int amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe) exit: prframe->u.hdr.len = 0; r8712_free_recvframe(prframe, pfree_recv_queue); - return _SUCCESS; } void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) @@ -511,7 +506,6 @@ int r8712_recv_indicatepkts_in_order(struct _adapter *padapter, union recv_frame *prframe; struct rx_pkt_attrib *pattrib; int bPktInBuf = false; - struct recv_priv *precvpriv = &padapter->recvpriv; struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; @@ -548,10 +542,7 @@ int r8712_recv_indicatepkts_in_order(struct _adapter *padapter, prframe); } } else if (pattrib->amsdu == 1) { - if (amsdu_to_msdu(padapter, prframe) != - _SUCCESS) - r8712_free_recvframe(prframe, - &precvpriv->free_recv_queue); + amsdu_to_msdu(padapter, prframe); } /* Update local variables. */ bPktInBuf = false; @@ -579,9 +570,9 @@ static int recv_indicatepkt_reorder(struct _adapter *padapter, if (!padapter->driver_stopped && !padapter->surprise_removed) { r8712_recv_indicatepkt(padapter, prframe); - return _SUCCESS; + return 0; } else { - return _FAIL; + return -EINVAL; } } } @@ -603,8 +594,7 @@ static int recv_indicatepkt_reorder(struct _adapter *padapter, * 2. All packets with SeqNum larger than or equal to * WinStart => Buffer it. */ - if (r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == - true) { + if (r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, false)) { mod_timer(&preorder_ctrl->reordering_ctrl_timer, jiffies + msecs_to_jiffies(REORDER_WAIT_TIME)); spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); @@ -612,10 +602,10 @@ static int recv_indicatepkt_reorder(struct _adapter *padapter, spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); del_timer(&preorder_ctrl->reordering_ctrl_timer); } - return _SUCCESS; + return 0; _err_exit: spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); - return _FAIL; + return -ENOMEM; } void r8712_reordering_ctrl_timeout_handler(void *pcontext) @@ -641,7 +631,7 @@ static int r8712_process_recv_indicatepkts(struct _adapter *padapter, struct ht_priv *phtpriv = &pmlmepriv->htpriv; if (phtpriv->ht_option == 1) { /*B/G/N Mode*/ - if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) { + if (recv_indicatepkt_reorder(padapter, prframe)) { /* including perform A-MPDU Rx Ordering Buffer Control*/ if (!padapter->driver_stopped && !padapter->surprise_removed) @@ -649,8 +639,8 @@ static int r8712_process_recv_indicatepkts(struct _adapter *padapter, } } else { /*B/G mode*/ retval = r8712_wlanhdr_to_ethhdr(prframe); - if (retval != _SUCCESS) - return retval; + if (retval) + return _FAIL; if (!padapter->driver_stopped && !padapter->surprise_removed) { /* indicate this recv_frame */ r8712_recv_indicatepkt(padapter, prframe); @@ -991,7 +981,7 @@ _exit_recv_func: return retval; } -static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) +static void recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) { u8 *pbuf, shift_sz = 0; u8 frag, mf; @@ -1018,7 +1008,7 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) /* In this case, it means the MAX_RECVBUF_SZ is too small to * get the data from 8712u. */ - return _FAIL; + return; } do { prxstat = (struct recv_stat *)pbuf; @@ -1031,13 +1021,13 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; drvinfo_sz <<= 3; if (pkt_len <= 0) - goto _exit_recvbuf2recvframe; + return; /* Qos data, wireless lan header length is 26 */ if ((le32_to_cpu(prxstat->rxdw0) >> 23) & 0x01) shift_sz = 2; precvframe = r8712_alloc_recvframe(pfree_recv_queue); if (!precvframe) - goto _exit_recvbuf2recvframe; + return; INIT_LIST_HEAD(&precvframe->u.hdr.list); precvframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf*/ precvframe->u.hdr.len = 0; @@ -1068,7 +1058,7 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) } else { precvframe->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC); if (!precvframe->u.hdr.pkt) - return _FAIL; + return; precvframe->u.hdr.rx_head = pbuf; precvframe->u.hdr.rx_data = pbuf; precvframe->u.hdr.rx_tail = pbuf; @@ -1088,8 +1078,6 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) precvframe = NULL; pkt_copy = NULL; } while ((transfer_len > 0) && pkt_cnt > 0); -_exit_recvbuf2recvframe: - return _SUCCESS; } static void recv_tasklet(void *priv) diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h index 6954c5bfbcaf..3e385b2242d8 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.h +++ b/drivers/staging/rtl8712/rtl8712_recv.h @@ -136,7 +136,7 @@ union recv_frame { } u; }; -int r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf); +void r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf); void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf); s32 r8712_signal_scale_mapping(s32 cur_sig); void r8712_reordering_ctrl_timeout_handler(void *pcontext); diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index 307b0e292976..c247f92207f5 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -246,7 +246,7 @@ void r8712_do_queue_select(struct _adapter *padapter, } #ifdef CONFIG_R8712_TX_AGGR -u8 r8712_construct_txaggr_cmd_desc(struct xmit_buf *pxmitbuf) +void r8712_construct_txaggr_cmd_desc(struct xmit_buf *pxmitbuf) { struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf; @@ -260,11 +260,9 @@ u8 r8712_construct_txaggr_cmd_desc(struct xmit_buf *pxmitbuf) /* dw1 */ ptx_desc->txdw1 |= cpu_to_le32((0x13 << QSEL_SHT) & 0x00001f00); - - return _SUCCESS; } -u8 r8712_construct_txaggr_cmd_hdr(struct xmit_buf *pxmitbuf) +void r8712_construct_txaggr_cmd_hdr(struct xmit_buf *pxmitbuf) { struct xmit_frame *pxmitframe = (struct xmit_frame *) pxmitbuf->priv_data; @@ -278,12 +276,10 @@ u8 r8712_construct_txaggr_cmd_hdr(struct xmit_buf *pxmitbuf) pcmd_hdr->cmd_dw0 = cpu_to_le32((GEN_CMD_CODE(_AMSDU_TO_AMPDU) << 16) | (pcmdpriv->cmd_seq << 24)); pcmdpriv->cmd_seq++; - - return _SUCCESS; } -u8 r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) +void r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf, + struct xmit_frame *pxmitframe) { struct _adapter *padapter = pxmitframe->padapter; struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf; @@ -319,13 +315,11 @@ u8 r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf, ((ptx_desc->txdw0 & 0x0000ffff) + ((TXDESC_SIZE + last_txcmdsz + padding_sz) & 0x0000ffff))); - - return _SUCCESS; } -u8 r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) +void r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, + struct xmit_frame *pxmitframe) { /* linux complete context doesn't need to protect */ pxmitframe->pxmitbuf = pxmitbuf; @@ -336,10 +330,8 @@ u8 r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, /*RTL8712_DMA_H2CCMD */ r8712_construct_txaggr_cmd_desc(pxmitbuf); r8712_construct_txaggr_cmd_hdr(pxmitbuf); - if (r8712_append_mpdu_unit(pxmitbuf, pxmitframe) == _SUCCESS) - pxmitbuf->aggr_nr = 1; - - return _SUCCESS; + r8712_append_mpdu_unit(pxmitbuf, pxmitframe); + pxmitbuf->aggr_nr = 1; } u16 r8712_xmitframe_aggr_next(struct xmit_buf *pxmitbuf, @@ -351,18 +343,17 @@ u16 r8712_xmitframe_aggr_next(struct xmit_buf *pxmitbuf, /* buffer addr assoc */ pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE + (((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff); - if (r8712_append_mpdu_unit(pxmitbuf, pxmitframe) == _SUCCESS) { - r8712_free_xmitframe_ex(&pxmitframe->padapter->xmitpriv, - pxmitframe); - pxmitbuf->aggr_nr++; - } + r8712_append_mpdu_unit(pxmitbuf, pxmitframe); + r8712_free_xmitframe_ex(&pxmitframe->padapter->xmitpriv, + pxmitframe); + pxmitbuf->aggr_nr++; return TXDESC_SIZE + (((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff); } -u8 r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) +void r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, + struct xmit_frame *pxmitframe) { struct _adapter *padapter = pxmitframe->padapter; struct dvobj_priv *pdvobj = &padapter->dvobjpriv; @@ -399,8 +390,6 @@ u8 r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, } r8712_write_port(pxmitframe->padapter, RTL8712_DMA_H2CCMD, total_length + TXDESC_SIZE, (u8 *)pxmitframe); - - return _SUCCESS; } #endif @@ -737,20 +726,19 @@ static void dump_xframe(struct _adapter *padapter, } } -int r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe) +void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe) { - int res = _SUCCESS; + int res; res = r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); pxmitframe->pkt = NULL; if (res == _SUCCESS) dump_xframe(padapter, pxmitframe); - return res; } int r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe) { - if (r8712_xmit_classifier(padapter, pxmitframe) == _FAIL) { + if (r8712_xmit_classifier(padapter, pxmitframe)) { pxmitframe->pkt = NULL; return _FAIL; } diff --git a/drivers/staging/rtl8712/rtl8712_xmit.h b/drivers/staging/rtl8712/rtl8712_xmit.h index 9be8fb70c92e..0b56bd3ac4d0 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.h +++ b/drivers/staging/rtl8712/rtl8712_xmit.h @@ -102,10 +102,10 @@ void r8712_do_queue_select(struct _adapter *padapter, struct pkt_attrib *pattrib); #ifdef CONFIG_R8712_TX_AGGR -u8 r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe); -u8 r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe); +void r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, + struct xmit_frame *pxmitframe); +void r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, + struct xmit_frame *pxmitframe); #endif #endif diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h index 28941423b7ed..c20dd5a6bbd1 100644 --- a/drivers/staging/rtl8712/rtl871x_io.h +++ b/drivers/staging/rtl8712/rtl871x_io.h @@ -11,8 +11,8 @@ * Larry Finger <Larry.Finger@lwfinger.net> * ******************************************************************************/ -#ifndef _IO_H_ -#define _IO_H_ +#ifndef _RTL871X_IO_H_ +#define _RTL871X_IO_H_ #include "osdep_service.h" #include "osdep_intf.h" @@ -234,5 +234,4 @@ void r8712_write_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); uint r8712_alloc_io_queue(struct _adapter *adapter); void r8712_free_io_queue(struct _adapter *adapter); -#endif /*_RTL8711_IO_H_*/ - +#endif /*_RTL871X_IO_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index b08b9a191a34..944336e0d2e2 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -419,8 +419,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, pwep->KeyIndex |= 0x80000000; memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); if (param->u.crypt.set_tx) { - if (r8712_set_802_11_add_wep(padapter, pwep) == - (u8)_FAIL) + if (r8712_set_802_11_add_wep(padapter, pwep)) ret = -EOPNOTSUPP; } else { /* don't update "psecuritypriv->PrivacyAlgrthm" and @@ -1585,7 +1584,7 @@ static int r8711_wx_set_enc(struct net_device *dev, } wep.KeyIndex |= 0x80000000; /* transmit key */ memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); - if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL) + if (r8712_set_802_11_add_wep(padapter, &wep)) return -EOPNOTSUPP; return 0; } diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index f3c0a9348f56..6cdc6f1a6bc6 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -320,22 +320,22 @@ u8 r8712_set_802_11_authentication_mode(struct _adapter *padapter, psecuritypriv->ndisauthtype = authmode; if (psecuritypriv->ndisauthtype > 3) psecuritypriv->AuthAlgrthm = 2; /* 802.1x */ - if (r8712_set_auth(padapter, psecuritypriv) == _SUCCESS) - ret = true; - else + if (r8712_set_auth(padapter, psecuritypriv)) ret = false; + else + ret = true; return ret; } -u8 r8712_set_802_11_add_wep(struct _adapter *padapter, - struct NDIS_802_11_WEP *wep) +int r8712_set_802_11_add_wep(struct _adapter *padapter, + struct NDIS_802_11_WEP *wep) { sint keyid; struct security_priv *psecuritypriv = &padapter->securitypriv; keyid = wep->KeyIndex & 0x3fffffff; if (keyid >= WEP_KEYS) - return false; + return -EINVAL; switch (wep->KeyLength) { case 5: psecuritypriv->PrivacyAlgrthm = _WEP40_; @@ -351,7 +351,5 @@ u8 r8712_set_802_11_add_wep(struct _adapter *padapter, wep->KeyLength); psecuritypriv->DefKeylen[keyid] = wep->KeyLength; psecuritypriv->PrivacyKeyIndex = keyid; - if (r8712_set_key(padapter, psecuritypriv, keyid) == _FAIL) - return false; - return _SUCCESS; + return r8712_set_key(padapter, psecuritypriv, keyid); } diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.h b/drivers/staging/rtl8712/rtl871x_ioctl_set.h index 8b1085aea962..e2de820f61d9 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.h +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.h @@ -28,8 +28,8 @@ u8 r8712_set_802_11_authentication_mode(struct _adapter *pdapter, u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid); -u8 r8712_set_802_11_add_wep(struct _adapter *padapter, - struct NDIS_802_11_WEP *wep); +int r8712_set_802_11_add_wep(struct _adapter *padapter, + struct NDIS_802_11_WEP *wep); u8 r8712_set_802_11_disassociate(struct _adapter *padapter); diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 0cc879a4d43f..cabdb3549a5a 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -53,7 +53,7 @@ int r8712_init_mlme_priv(struct _adapter *padapter) pbuf = kmalloc_array(MAX_BSS_CNT, sizeof(struct wlan_network), GFP_ATOMIC); if (!pbuf) - return _FAIL; + return -ENOMEM; pmlmepriv->free_bss_buf = pbuf; pnetwork = (struct wlan_network *)pbuf; for (i = 0; i < MAX_BSS_CNT; i++) { @@ -67,7 +67,7 @@ int r8712_init_mlme_priv(struct _adapter *padapter) pmlmepriv->sitesurveyctrl.traffic_busy = false; /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ r8712_init_mlme_timer(padapter); - return _SUCCESS; + return 0; } struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv) @@ -1144,8 +1144,8 @@ ask_for_joinbss: return r8712_joinbss_cmd(adapter, pnetwork); } -sint r8712_set_auth(struct _adapter *adapter, - struct security_priv *psecuritypriv) +int r8712_set_auth(struct _adapter *adapter, + struct security_priv *psecuritypriv) { struct cmd_priv *pcmdpriv = &adapter->cmdpriv; struct cmd_obj *pcmd; @@ -1153,12 +1153,12 @@ sint r8712_set_auth(struct _adapter *adapter, pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) - return _FAIL; + return -ENOMEM; psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); if (!psetauthparm) { kfree(pcmd); - return _FAIL; + return -ENOMEM; } psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm; pcmd->cmdcode = _SetAuth_CMD_; @@ -1168,25 +1168,25 @@ sint r8712_set_auth(struct _adapter *adapter, pcmd->rspsz = 0; INIT_LIST_HEAD(&pcmd->list); r8712_enqueue_cmd(pcmdpriv, pcmd); - return _SUCCESS; + return 0; } -sint r8712_set_key(struct _adapter *adapter, - struct security_priv *psecuritypriv, - sint keyid) +int r8712_set_key(struct _adapter *adapter, + struct security_priv *psecuritypriv, + sint keyid) { struct cmd_priv *pcmdpriv = &adapter->cmdpriv; struct cmd_obj *pcmd; struct setkey_parm *psetkeyparm; u8 keylen; - sint ret = _SUCCESS; + int ret; pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); if (!pcmd) - return _FAIL; + return -ENOMEM; psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC); if (!psetkeyparm) { - ret = _FAIL; + ret = -ENOMEM; goto err_free_cmd; } if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */ @@ -1211,7 +1211,7 @@ sint r8712_set_key(struct _adapter *adapter, break; case _TKIP_: if (keyid < 1 || keyid > 2) { - ret = _FAIL; + ret = -EINVAL; goto err_free_parm; } keylen = 16; @@ -1221,7 +1221,7 @@ sint r8712_set_key(struct _adapter *adapter, break; case _AES_: if (keyid < 1 || keyid > 2) { - ret = _FAIL; + ret = -EINVAL; goto err_free_parm; } keylen = 16; @@ -1230,7 +1230,7 @@ sint r8712_set_key(struct _adapter *adapter, psetkeyparm->grpkey = 1; break; default: - ret = _FAIL; + ret = -EINVAL; goto err_free_parm; } pcmd->cmdcode = _SetKey_CMD_; @@ -1240,7 +1240,7 @@ sint r8712_set_key(struct _adapter *adapter, pcmd->rspsz = 0; INIT_LIST_HEAD(&pcmd->list); r8712_enqueue_cmd(pcmdpriv, pcmd); - return ret; + return 0; err_free_parm: kfree(psetkeyparm); diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h index a160107e9801..46effb469fd4 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.h +++ b/drivers/staging/rtl8712/rtl871x_mlme.h @@ -173,10 +173,10 @@ void r8712_free_network_queue(struct _adapter *adapter); int r8712_init_mlme_priv(struct _adapter *adapter); void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv); int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv); -sint r8712_set_key(struct _adapter *adapter, - struct security_priv *psecuritypriv, sint keyid); -sint r8712_set_auth(struct _adapter *adapter, - struct security_priv *psecuritypriv); +int r8712_set_key(struct _adapter *adapter, + struct security_priv *psecuritypriv, sint keyid); +int r8712_set_auth(struct _adapter *adapter, + struct security_priv *psecuritypriv); uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss); void r8712_generate_random_ibss(u8 *pibss); u8 *r8712_get_capability_from_ie(u8 *ie); diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c index edd3da05fc06..1a39a96b726f 100644 --- a/drivers/staging/rtl8712/rtl871x_mp.c +++ b/drivers/staging/rtl8712/rtl871x_mp.c @@ -35,7 +35,7 @@ static void _init_mp_priv_(struct mp_priv *pmp_priv) static int init_mp_priv(struct mp_priv *pmp_priv) { - int i, res; + int i; struct mp_xmit_frame *pmp_xmitframe; _init_mp_priv_(pmp_priv); @@ -45,8 +45,7 @@ static int init_mp_priv(struct mp_priv *pmp_priv) sizeof(struct mp_xmit_frame) + 4, GFP_ATOMIC); if (!pmp_priv->pallocated_mp_xmitframe_buf) { - res = _FAIL; - goto _exit_init_mp_priv; + return -ENOMEM; } pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf + 4 - @@ -62,9 +61,7 @@ static int init_mp_priv(struct mp_priv *pmp_priv) pmp_xmitframe++; } pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME; - res = _SUCCESS; -_exit_init_mp_priv: - return res; + return 0; } static int free_mp_priv(struct mp_priv *pmp_priv) diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index 2beafc7742b3..23cff43437e2 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c @@ -184,19 +184,19 @@ void r8712_init_pwrctrl_priv(struct _adapter *padapter) * will raise the cpwm to be greater than or equal to P2. * Calling Context: Passive * Return Value: - * _SUCCESS: r8712_cmd_thread can issue cmds to firmware afterwards. - * _FAIL: r8712_cmd_thread can not do anything. + * 0: r8712_cmd_thread can issue cmds to firmware afterwards. + * -EINVAL: r8712_cmd_thread can not do anything. */ -sint r8712_register_cmd_alive(struct _adapter *padapter) +int r8712_register_cmd_alive(struct _adapter *padapter) { - uint res = _SUCCESS; + int res = 0; struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv; mutex_lock(&pwrctrl->mutex_lock); register_task_alive(pwrctrl, CMD_ALIVE); if (pwrctrl->cpwm < PS_STATE_S2) { r8712_set_rpwm(padapter, PS_STATE_S3); - res = _FAIL; + res = -EINVAL; } mutex_unlock(&pwrctrl->mutex_lock); return res; diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h index 11b5034f203d..dd5a79f90b1a 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h @@ -104,7 +104,7 @@ struct pwrctrl_priv { }; void r8712_init_pwrctrl_priv(struct _adapter *adapter); -sint r8712_register_cmd_alive(struct _adapter *padapter); +int r8712_register_cmd_alive(struct _adapter *padapter); void r8712_unregister_cmd_alive(struct _adapter *padapter); void r8712_cpwm_int_hdl(struct _adapter *padapter, struct reportpwrstate_parm *preportpwrstate); diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 5298fe603437..e5092b6da4bd 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -48,7 +48,7 @@ void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) _init_queue(&psta_recvpriv->defrag_q); } -sint _r8712_init_recv_priv(struct recv_priv *precvpriv, +void _r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter) { sint i; @@ -64,7 +64,7 @@ sint _r8712_init_recv_priv(struct recv_priv *precvpriv, sizeof(union recv_frame) + RXFRAME_ALIGN_SZ, GFP_ATOMIC); if (precvpriv->pallocated_frame_buf == NULL) - return _FAIL; + return; kmemleak_not_leak(precvpriv->pallocated_frame_buf); precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - @@ -80,7 +80,7 @@ sint _r8712_init_recv_priv(struct recv_priv *precvpriv, precvframe++; } precvpriv->rx_pending_cnt = 1; - return r8712_init_recv_priv(precvpriv, padapter); + r8712_init_recv_priv(precvpriv, padapter); } void _r8712_free_recv_priv(struct recv_priv *precvpriv) @@ -245,8 +245,7 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter, if (auth_alg == 2) { /* get ether_type */ ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; - memcpy(ðer_type, ptr, 2); - be16_to_cpus(ðer_type); + ether_type = get_unaligned_be16(ptr); if ((psta != NULL) && (psta->ieee8021x_blocked)) { /* blocked @@ -586,7 +585,7 @@ sint r8712_validate_recv_frame(struct _adapter *adapter, return retval; } -sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) +int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) { /*remove the wlanhdr and add the eth_hdr*/ sint rmv_len; @@ -629,14 +628,14 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); if (!ptr) - return _FAIL; + return -ENOMEM; memcpy(ptr, get_rxmem(precvframe), 24); ptr += 24; } else { ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); if (!ptr) - return _FAIL; + return -ENOMEM; } memcpy(ptr, pattrib->dst, ETH_ALEN); @@ -646,10 +645,10 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) memcpy(ptr + 12, &be_tmp, 2); } - return _SUCCESS; + return 0; } -s32 r8712_recv_entry(union recv_frame *precvframe) +void r8712_recv_entry(union recv_frame *precvframe) { struct _adapter *padapter; struct recv_priv *precvpriv; @@ -667,9 +666,8 @@ s32 r8712_recv_entry(union recv_frame *precvframe) precvpriv->rx_pkts++; precvpriv->rx_bytes += (uint)(precvframe->u.hdr.rx_tail - precvframe->u.hdr.rx_data); - return ret; + return; _recv_entry_drop: precvpriv->rx_drop++; padapter->mppriv.rx_pktloss = precvpriv->rx_drop; - return ret; } diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h index f87b2ff5de1c..0146a774e19d 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ b/drivers/staging/rtl8712/rtl871x_recv.h @@ -128,7 +128,7 @@ struct sta_recv_priv { /* get a free recv_frame from pfree_recv_queue */ union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue); -int r8712_free_recvframe(union recv_frame *precvframe, +void r8712_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue); void r8712_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfree_recv_queue); diff --git a/drivers/staging/rtl8712/rtl871x_rf.h b/drivers/staging/rtl8712/rtl871x_rf.h index cc54453cd424..7d98921a48fa 100644 --- a/drivers/staging/rtl8712/rtl871x_rf.h +++ b/drivers/staging/rtl8712/rtl871x_rf.h @@ -52,5 +52,4 @@ enum { RTL8712_RFC_2T2R = 0x22 }; -#endif /*_RTL8711_RF_H_*/ - +#endif /*__RTL871X_RF_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index 693008bba83e..73e3d5ef3af2 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -636,7 +636,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) } /* The hlen doesn't include the IV */ -u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) +void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) { /* exclude ICV */ u16 pnl; u32 pnh; @@ -670,7 +670,7 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) prwskey = &psecuritypriv->XGrpKey[ ((idx >> 6) & 0x3) - 1].skey[0]; if (!psecuritypriv->binstallGrpkey) - return _FAIL; + return; } else { prwskey = &stainfo->x_UncstKey.skey[0]; } @@ -686,16 +686,8 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) arcfour_encrypt(&mycontext, payload, payload, length); *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4)); - if (crc[3] != payload[length - 1] || - crc[2] != payload[length - 2] || - crc[1] != payload[length - 3] || - crc[0] != payload[length - 4]) - return _FAIL; - } else { - return _FAIL; } } - return _SUCCESS; } /* 3 =====AES related===== */ @@ -1019,8 +1011,8 @@ static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) out[i] = ina[i] ^ inb[i]; } -static sint aes_cipher(u8 *key, uint hdrlen, - u8 *pframe, uint plen) +static void aes_cipher(u8 *key, uint hdrlen, + u8 *pframe, uint plen) { uint qc_exists, a4_exists, i, j, payload_remainder; uint num_blocks, payload_index; @@ -1140,7 +1132,6 @@ static sint aes_cipher(u8 *key, uint hdrlen, bitwise_xor(aes_out, padded_buffer, chain_buffer); for (j = 0; j < 8; j++) pframe[payload_index++] = chain_buffer[j]; - return _SUCCESS; } u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) @@ -1193,8 +1184,8 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) return res; } -static sint aes_decipher(u8 *key, uint hdrlen, - u8 *pframe, uint plen) +static void aes_decipher(u8 *key, uint hdrlen, + u8 *pframe, uint plen) { static u8 message[MAX_MSG_SIZE]; uint qc_exists, a4_exists, i, j, payload_remainder; @@ -1348,10 +1339,9 @@ static sint aes_decipher(u8 *key, uint hdrlen, for (j = 0; j < 8; j++) message[payload_index++] = chain_buffer[j]; /* compare the mic */ - return _SUCCESS; } -u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) +void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) { /* exclude ICV */ /* Intermediate Buffers */ sint length; @@ -1374,7 +1364,7 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) prwskey = &psecuritypriv->XGrpKey[ ((idx >> 6) & 0x3) - 1].skey[0]; if (!psecuritypriv->binstallGrpkey) - return _FAIL; + return; } else { prwskey = &stainfo->x_UncstKey.skey[0]; @@ -1384,11 +1374,8 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) prxattrib->iv_len; aes_decipher(prwskey, prxattrib->hdrlen, pframe, length); - } else { - return _FAIL; } } - return _SUCCESS; } void r8712_use_tkipkey_handler(struct timer_list *t) diff --git a/drivers/staging/rtl8712/rtl871x_security.h b/drivers/staging/rtl8712/rtl871x_security.h index 25b4d379766d..b2dda16cbd0a 100644 --- a/drivers/staging/rtl8712/rtl871x_security.h +++ b/drivers/staging/rtl8712/rtl871x_security.h @@ -209,8 +209,8 @@ void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst); u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe); u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe); void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe); -u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe); -u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe); +void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe); +void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe); void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe); void r8712_use_tkipkey_handler(struct timer_list *t); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 0a26d71e5340..cc5809e49e35 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -49,8 +49,8 @@ void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) INIT_LIST_HEAD(&psta_xmitpriv->apsd); } -sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, - struct _adapter *padapter) +int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, + struct _adapter *padapter) { sint i; struct xmit_buf *pxmitbuf; @@ -79,7 +79,7 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4, GFP_ATOMIC); if (!pxmitpriv->pallocated_frame_buf) { pxmitpriv->pxmit_frame_buf = NULL; - return _FAIL; + return -ENOMEM; } pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3); @@ -119,7 +119,7 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, if (!pxmitpriv->pallocated_xmitbuf) { kfree(pxmitpriv->pallocated_frame_buf); pxmitpriv->pallocated_frame_buf = NULL; - return _FAIL; + return -ENOMEM; } pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3); @@ -129,12 +129,12 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, pxmitbuf->pallocated_buf = kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC); if (!pxmitbuf->pallocated_buf) - return _FAIL; + return -ENOMEM; pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ - ((addr_t) (pxmitbuf->pallocated_buf) & (XMITBUF_ALIGN_SZ - 1)); if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) - return _FAIL; + return -ENOMEM; list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue)); pxmitbuf++; @@ -146,7 +146,7 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, tasklet_init(&pxmitpriv->xmit_tasklet, (void(*)(unsigned long))r8712_xmit_bh, (unsigned long)padapter); - return _SUCCESS; + return 0; } void _free_xmit_priv(struct xmit_priv *pxmitpriv) @@ -173,8 +173,8 @@ void _free_xmit_priv(struct xmit_priv *pxmitpriv) free_hwxmits(padapter); } -sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, - struct pkt_attrib *pattrib) +int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, + struct pkt_attrib *pattrib) { struct pkt_file pktfile; struct sta_info *psta = NULL; @@ -224,7 +224,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { /*firstly, filter packet not belongs to mp*/ if (pattrib->ether_type != 0x8712) - return _FAIL; + return -EINVAL; /* for mp storing the txcmd per packet, * according to the info of txcmd to update pattrib */ @@ -271,7 +271,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, } else { psta = r8712_get_stainfo(pstapriv, pattrib->ra); if (psta == NULL) /* drop the pkt */ - return _FAIL; + return -ENOMEM; if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) pattrib->mac_id = 5; else @@ -283,7 +283,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, pattrib->psta = psta; } else { /* if we cannot get psta => drrp the pkt */ - return _FAIL; + return -ENOMEM; } pattrib->ack_policy = 0; @@ -301,7 +301,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, pattrib->encrypt = 0; if ((pattrib->ether_type != 0x888e) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) - return _FAIL; + return -EINVAL; } else { GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); } @@ -315,7 +315,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, pattrib->iv_len = 8; pattrib->icv_len = 4; if (padapter->securitypriv.busetkipkey == _FAIL) - return _FAIL; + return -EINVAL; break; case _AES_: pattrib->iv_len = 8; @@ -339,11 +339,11 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) pattrib->priority = (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f; - return _SUCCESS; + return 0; } -static sint xmitframe_addmic(struct _adapter *padapter, - struct xmit_frame *pxmitframe) +static int xmitframe_addmic(struct _adapter *padapter, + struct xmit_frame *pxmitframe) { u32 curfragnum, length; u8 *pframe, *payload, mic[8]; @@ -372,7 +372,7 @@ static sint xmitframe_addmic(struct _adapter *padapter, if (!memcmp(psecuritypriv->XGrptxmickey [psecuritypriv->XGrpKeyid].skey, null_key, 16)) - return _FAIL; + return -ENOMEM; /*start to calculate the mic code*/ r8712_secmicsetkey(&micdata, psecuritypriv-> @@ -381,7 +381,7 @@ static sint xmitframe_addmic(struct _adapter *padapter, } else { if (!memcmp(&stainfo->tkiptxmickey.skey[0], null_key, 16)) - return _FAIL; + return -ENOMEM; /* start to calculate the mic code */ r8712_secmicsetkey(&micdata, &stainfo->tkiptxmickey.skey[0]); @@ -442,7 +442,7 @@ static sint xmitframe_addmic(struct _adapter *padapter, payload = payload - pattrib->last_txcmdsz + 8; } } - return _SUCCESS; + return 0; } static sint xmitframe_swencrypt(struct _adapter *padapter, @@ -469,8 +469,8 @@ static sint xmitframe_swencrypt(struct _adapter *padapter, return _SUCCESS; } -static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr, - struct pkt_attrib *pattrib) +static int make_wlanhdr(struct _adapter *padapter, u8 *hdr, + struct pkt_attrib *pattrib) { u16 *qc; @@ -509,7 +509,7 @@ static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr, memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); } else { - return _FAIL; + return -EINVAL; } if (pattrib->encrypt) @@ -547,7 +547,7 @@ static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr, } } } - return _SUCCESS; + return 0; } static sint r8712_put_snap(u8 *data, u16 h_proto) @@ -605,7 +605,7 @@ sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, pbuf_start = pxmitframe->buf_addr; ptxdesc = pbuf_start; mem_start = pbuf_start + TXDESC_OFFSET; - if (make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) + if (make_wlanhdr(padapter, mem_start, pattrib)) return _FAIL; _r8712_open_pktfile(pkt, &pktfile); _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen); @@ -696,7 +696,7 @@ sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen); } - if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) + if (xmitframe_addmic(padapter, pxmitframe)) return _FAIL; xmitframe_swencrypt(padapter, pxmitframe); return _SUCCESS; @@ -753,19 +753,18 @@ struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv) return pxmitbuf; } -int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) +void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) { unsigned long irqL; struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; if (pxmitbuf == NULL) - return _FAIL; + return; spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); list_del_init(&pxmitbuf->list); list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue); pxmitpriv->free_xmitbuf_cnt++; spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL); - return _SUCCESS; } /* @@ -894,8 +893,8 @@ static inline struct tx_servq *get_sta_pending(struct _adapter *padapter, * Will enqueue pxmitframe to the proper queue, and indicate it * to xx_pending list..... */ -sint r8712_xmit_classifier(struct _adapter *padapter, - struct xmit_frame *pxmitframe) +int r8712_xmit_classifier(struct _adapter *padapter, + struct xmit_frame *pxmitframe) { unsigned long irqL0; struct __queue *pstapending; @@ -920,7 +919,7 @@ sint r8712_xmit_classifier(struct _adapter *padapter, } } if (psta == NULL) - return _FAIL; + return -EINVAL; ptxservq = get_sta_pending(padapter, &pstapending, psta, pattrib->priority); spin_lock_irqsave(&pstapending->lock, irqL0); @@ -929,7 +928,7 @@ sint r8712_xmit_classifier(struct _adapter *padapter, list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue); ptxservq->qcnt++; spin_unlock_irqrestore(&pstapending->lock, irqL0); - return _SUCCESS; + return 0; } static void alloc_hwxmits(struct _adapter *padapter) diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h index 4199cb586fb1..b14da38bf652 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.h +++ b/drivers/staging/rtl8712/rtl871x_xmit.h @@ -41,7 +41,7 @@ do { \ pattrib_iv[0] = txpn._byte_.TSC0;\ pattrib_iv[1] = txpn._byte_.TSC1;\ pattrib_iv[2] = txpn._byte_.TSC2;\ - pattrib_iv[3] = ((keyidx & 0x3)<<6);\ + pattrib_iv[3] = ((keyidx & 0x3) << 6);\ txpn.val = (txpn.val == 0xffffff) ? 0 : (txpn.val+1);\ } while (0) @@ -249,8 +249,8 @@ struct xmit_priv { uint free_xmitbuf_cnt; }; -int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, - struct xmit_buf *pxmitbuf); +void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, + struct xmit_buf *pxmitbuf); struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv); void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len); struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv); @@ -258,25 +258,25 @@ void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue); -sint r8712_xmit_classifier(struct _adapter *padapter, - struct xmit_frame *pxmitframe); +int r8712_xmit_classifier(struct _adapter *padapter, + struct xmit_frame *pxmitframe); sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe); sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag); void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); -sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, - struct pkt_attrib *pattrib); +int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, + struct pkt_attrib *pattrib); int r8712_txframes_sta_ac_pending(struct _adapter *padapter, struct pkt_attrib *pattrib); -sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, - struct _adapter *padapter); +int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, + struct _adapter *padapter); void _free_xmit_priv(struct xmit_priv *pxmitpriv); void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe); int r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe); -int r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe); +void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe); void r8712_xmit_bh(void *priv); void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe, diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index d0daae0b8299..ba1288297ee4 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -389,7 +389,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, } /* step 4. */ status = r8712_init_drv_sw(padapter); - if (status == _FAIL) + if (status) goto error; /* step 5. read efuse/eeprom data and get mac_addr */ { diff --git a/drivers/staging/rtl8712/usb_osintf.h b/drivers/staging/rtl8712/usb_osintf.h index ddfa405d0c9b..2e512b4a564c 100644 --- a/drivers/staging/rtl8712/usb_osintf.h +++ b/drivers/staging/rtl8712/usb_osintf.h @@ -28,8 +28,8 @@ void rtl871x_intf_stop(struct _adapter *padapter); void r871x_dev_unload(struct _adapter *padapter); void r8712_stop_drv_threads(struct _adapter *padapter); void r8712_stop_drv_timers(struct _adapter *padapter); -u8 r8712_init_drv_sw(struct _adapter *padapter); -u8 r8712_free_drv_sw(struct _adapter *padapter); +int r8712_init_drv_sw(struct _adapter *padapter); +void r8712_free_drv_sw(struct _adapter *padapter); struct net_device *r8712_init_netdev(void); #endif diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h index 1a5b966a167e..be731f1a2209 100644 --- a/drivers/staging/rtl8712/wifi.h +++ b/drivers/staging/rtl8712/wifi.h @@ -300,7 +300,6 @@ static inline unsigned char *get_da(unsigned char *pframe) return da; } - static inline unsigned char *get_sa(unsigned char *pframe) { unsigned char *sa; @@ -346,8 +345,6 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) return sa; } - - /*----------------------------------------------------------------------------- * Below is for the security related definition *----------------------------------------------------------------------------- @@ -392,7 +389,6 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) #define _RESERVED47_ 47 - /* --------------------------------------------------------------------------- * Below is the fixed elements... * --------------------------------------------------------------------------- @@ -436,7 +432,6 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) #define _WMM_IE_Length_ 7 /* for WMM STA */ #define _WMM_Para_Element_Length_ 24 - /*----------------------------------------------------------------------------- * Below is the definition for 802.11n *------------------------------------------------------------------------------ @@ -456,7 +451,6 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) #define GetOrderBit(pbuf) (((*(__le16 *)(pbuf)) & \ le16_to_cpu(_ORDER_)) != 0) - /** * struct ieee80211_bar - HT Block Ack Request * @@ -476,7 +470,6 @@ struct ieee80211_bar { #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 #define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 - /* * struct ieee80211_ht_cap - HT capabilities * @@ -552,7 +545,6 @@ struct ieee80211_ht_addt_info { */ #define IEEE80211_MIN_AMPDU_BUF 0x8 - /* Spatial Multiplexing Power Save Modes */ #define WLAN_HT_CAP_SM_PS_STATIC 0 #define WLAN_HT_CAP_SM_PS_DYNAMIC 1 diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index 01d713d027b0..1f67d86c606f 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -160,7 +160,7 @@ int r8712_xmit_entry(_pkt *pkt, struct net_device *netdev) if (!xmitframe) goto _xmit_entry_drop; - if ((!r8712_update_attrib(adapter, pkt, &xmitframe->attrib))) + if (r8712_update_attrib(adapter, pkt, &xmitframe->attrib)) goto _xmit_entry_drop; adapter->ledpriv.LedControlHandler(adapter, LED_CTL_TX); diff --git a/drivers/staging/rtl8723bs/Makefile b/drivers/staging/rtl8723bs/Makefile index a12cf8dd8ed9..dfe410283ca0 100644 --- a/drivers/staging/rtl8723bs/Makefile +++ b/drivers/staging/rtl8723bs/Makefile @@ -60,7 +60,6 @@ r8723bs-y = \ os_dep/osdep_service.o \ os_dep/os_intfs.o \ os_dep/recv_linux.o \ - os_dep/rtw_proc.o \ os_dep/sdio_intf.o \ os_dep/sdio_ops_linux.o \ os_dep/wifi_regd.o \ diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c index 7bd5c61b055c..6d18d23acdc0 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ap.c +++ b/drivers/staging/rtl8723bs/core/rtw_ap.c @@ -13,11 +13,10 @@ extern unsigned char RTW_WPA_OUI[]; extern unsigned char WMM_OUI[]; extern unsigned char WPS_OUI[]; extern unsigned char P2P_OUI[]; -extern unsigned char WFD_OUI[]; void init_mlme_ap_info(struct adapter *padapter) { - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; @@ -34,9 +33,9 @@ void init_mlme_ap_info(struct adapter *padapter) void free_mlme_ap_info(struct adapter *padapter) { struct sta_info *psta = NULL; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; /* stop_ap_mode(padapter); */ @@ -58,9 +57,9 @@ void free_mlme_ap_info(struct adapter *padapter) static void update_BCNTIM(struct adapter *padapter) { struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; unsigned char *pie = pnetwork_mlmeext->IEs; /* DBG_871X("%s\n", __func__); */ @@ -83,7 +82,7 @@ static void update_BCNTIM(struct adapter *padapter) if (p != NULL && tim_ielen > 0) { tim_ielen += 2; - premainder_ie = p+tim_ielen; + premainder_ie = p + tim_ielen; tim_ie_offset = (sint)(p - pie); @@ -94,7 +93,7 @@ static void update_BCNTIM(struct adapter *padapter) } else { tim_ielen = 0; - /* calucate head_len */ + /* calculate head_len */ offset = _FIXED_IE_LENGTH_; /* get ssid_ie len */ @@ -105,7 +104,7 @@ static void update_BCNTIM(struct adapter *padapter) (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_) ); if (p != NULL) - offset += tmp_len+2; + offset += tmp_len + 2; /* get supported rates len */ p = rtw_get_ie( @@ -114,7 +113,7 @@ static void update_BCNTIM(struct adapter *padapter) (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_) ); if (p != NULL) - offset += tmp_len+2; + offset += tmp_len + 2; /* DS Parameter Set IE, len =3 */ offset += 3; @@ -135,7 +134,7 @@ static void update_BCNTIM(struct adapter *padapter) *dst_ie++ = _TIM_IE_; - if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fe)) + if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fe)) tim_ielen = 5; else tim_ielen = 4; @@ -143,9 +142,9 @@ static void update_BCNTIM(struct adapter *padapter) *dst_ie++ = tim_ielen; *dst_ie++ = 0;/* DTIM count */ - *dst_ie++ = 1;/* DTIM peroid */ + *dst_ie++ = 1;/* DTIM period */ - if (pstapriv->tim_bitmap&BIT(0))/* for bc/mc frames */ + if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */ *dst_ie++ = BIT(0);/* bitmap ctrl */ else *dst_ie++ = 0; @@ -153,7 +152,7 @@ static void update_BCNTIM(struct adapter *padapter) if (tim_ielen == 4) { __le16 pvb; - if (pstapriv->tim_bitmap&0xff00) + if (pstapriv->tim_bitmap & 0xff00) pvb = cpu_to_le16(pstapriv->tim_bitmap >> 8); else pvb = tim_bitmap_le; @@ -188,8 +187,8 @@ u8 chk_sta_is_alive(struct sta_info *psta) /* STA_RX_PKTS_ARG(psta) */ , STA_RX_PKTS_DIFF_ARG(psta) , psta->expire_to - , psta->state&WIFI_SLEEP_STATE?"PS, ":"" - , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":"" + , psta->state & WIFI_SLEEP_STATE ? "PS, " : "" + , psta->state & WIFI_STA_ALIVE_CHK_STATE ? "SAC, " : "" , psta->sleepq_len ); #endif @@ -292,7 +291,7 @@ void expire_timeout_chk(struct adapter *padapter) if (psta->state & WIFI_SLEEP_STATE) { if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) { - /* to check if alive by another methods if staion is at ps mode. */ + /* to check if alive by another methods if station is at ps mode. */ psta->expire_to = pstapriv->expire_to; psta->state |= WIFI_STA_ALIVE_CHK_STATE; @@ -325,10 +324,10 @@ void expire_timeout_chk(struct adapter *padapter) updated = ap_free_sta(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING); } else { /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */ - if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt) + if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt) && padapter->xmitpriv.free_xmitframe_cnt < (( - NR_XMITFRAME/pstapriv->asoc_list_cnt - )/2) + NR_XMITFRAME / pstapriv->asoc_list_cnt + ) / 2) ) { DBG_871X( "%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", @@ -586,8 +585,8 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta) phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable; phtpriv_sta->rx_ampdu_min_spacing = ( - phtpriv_sta->ht_cap.ampdu_params_info&IEEE80211_HT_CAP_AMPDU_DENSITY - )>>2; + phtpriv_sta->ht_cap.ampdu_params_info & IEEE80211_HT_CAP_AMPDU_DENSITY + ) >> 2; /* bwmode */ if (( @@ -782,8 +781,8 @@ void start_bss_network(struct adapter *padapter, u8 *pbuf) /* check if there is wps ie, */ /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */ /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */ - if (!rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, - pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL)) + if (!rtw_get_wps_ie(pnetwork->IEs + _FIXED_IE_LENGTH_, + pnetwork->IELength - _FIXED_IE_LENGTH_, NULL, NULL)) pmlmeext->bstart_bss = true; /* todo: update wmm, ht cap */ @@ -861,7 +860,7 @@ void start_bss_network(struct adapter *padapter, u8 *pbuf) (pnetwork->IELength - sizeof(struct ndis_802_11_fix_ie)) ); if (p && ie_len) { - pht_info = (struct HT_info_element *)(p+2); + pht_info = (struct HT_info_element *)(p + 2); if (cur_channel > 14) { if ((pregpriv->bw_mode & 0xf0) > 0) @@ -916,7 +915,7 @@ void start_bss_network(struct adapter *padapter, u8 *pbuf) UpdateBrateTbl(padapter, pnetwork->SupportedRates); rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates); - /* udpate capability after cur_wireless_mode updated */ + /* update capability after cur_wireless_mode updated */ update_capinfo( padapter, rtw_get_capability((struct wlan_bssid_ex *)pnetwork) @@ -1015,7 +1014,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pbss_network->Ssid.SsidLength = ie_len; } - /* chnnel */ + /* channel */ channel = 0; pbss_network->Configuration.Length = 0; p = rtw_get_ie( @@ -1037,7 +1036,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) (pbss_network->IELength - _BEACON_IE_OFFSET_) ); if (p != NULL) { - memcpy(supportRate, p+2, ie_len); + memcpy(supportRate, p + 2, ie_len); supportRateNum = ie_len; } @@ -1049,7 +1048,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pbss_network->IELength - _BEACON_IE_OFFSET_ ); if (p != NULL) { - memcpy(supportRate+supportRateNum, p+2, ie_len); + memcpy(supportRate + supportRateNum, p + 2, ie_len); supportRateNum += ie_len; } @@ -1088,7 +1087,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) if (p && ie_len > 0) { if (rtw_parse_wpa2_ie( p, - ie_len+2, + ie_len + 2, &group_cipher, &pairwise_cipher, NULL @@ -1115,10 +1114,10 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)) ); - if ((p) && (!memcmp(p+2, OUI1, 4))) { + if ((p) && (!memcmp(p + 2, OUI1, 4))) { if (rtw_parse_wpa_ie( p, - ie_len+2, + ie_len + 2, &group_cipher, &pairwise_cipher, NULL @@ -1151,10 +1150,10 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)) ); - if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) { + if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) { pmlmepriv->qospriv.qos_option = 1; - *(p+8) |= BIT(7);/* QoS Info, support U-APSD */ + *(p + 8) |= BIT(7);/* QoS Info, support U-APSD */ /* disable all ACM bits since the WMM admission control is not supported */ *(p + 10) &= ~BIT(4); /* BE */ @@ -1180,7 +1179,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) if (p && ie_len > 0) { u8 rf_type = 0; u8 max_rx_ampdu_factor = 0; - struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2); + struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2); pHT_caps_ie = p; @@ -1205,14 +1204,14 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_RX_STBC_3R)); pht_cap->ampdu_params_info &= ~( - IEEE80211_HT_CAP_AMPDU_FACTOR|IEEE80211_HT_CAP_AMPDU_DENSITY + IEEE80211_HT_CAP_AMPDU_FACTOR | IEEE80211_HT_CAP_AMPDU_DENSITY ); if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) || (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) { - pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2)); + pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2)); } else { - pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00); + pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); } rtw_hal_get_def_var( @@ -1230,7 +1229,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pht_cap->supp_mcs_set[1] = 0x0; } - memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len); + memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); } /* parsing HT_INFO_IE */ @@ -1265,8 +1264,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pmlmepriv->htpriv.ht_option = false; - if ((psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) || - (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP)) { + if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || + (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) { /* todo: */ /* ht_cap = false; */ } @@ -1341,7 +1340,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) MAC_ARG(addr) ); - if ((NUM_ACL-1) < pacl_list->num) + if ((NUM_ACL - 1) < pacl_list->num) return (-1); spin_lock_bh(&(pacl_node_q->lock)); @@ -1454,7 +1453,7 @@ u8 rtw_ap_set_pairwise_key(struct adapter *padapter, struct sta_info *psta) psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); if (psetstakey_para == NULL) { - kfree((u8 *) ph2c); + kfree((u8 *)ph2c); res = _FAIL; goto exit; } @@ -1604,10 +1603,10 @@ static void update_bcn_erpinfo_ie(struct adapter *padapter) struct ndis_80211_var_ie *pIE = (struct ndis_80211_var_ie *)p; if (pmlmepriv->num_sta_non_erp == 1) - pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION; + pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION; else pIE->data[0] &= ~( - RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION + RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION ); if (pmlmepriv->num_sta_no_short_preamble > 0) @@ -1662,8 +1661,8 @@ static void update_bcn_wps_ie(struct adapter *padapter) DBG_871X("%s\n", __func__); pwps_ie = rtw_get_wps_ie( - ie+_FIXED_IE_LENGTH_, - ielen-_FIXED_IE_LENGTH_, + ie + _FIXED_IE_LENGTH_, + ielen - _FIXED_IE_LENGTH_, NULL, &wps_ielen ); @@ -1675,7 +1674,7 @@ static void update_bcn_wps_ie(struct adapter *padapter) if (pwps_ie_src == NULL) return; - wps_offset = (uint)(pwps_ie-ie); + wps_offset = (uint)(pwps_ie - ie); premainder_ie = pwps_ie + wps_ielen; @@ -1688,22 +1687,22 @@ static void update_bcn_wps_ie(struct adapter *padapter) } wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */ - if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) { - memcpy(pwps_ie, pwps_ie_src, wps_ielen+2); + if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) { + memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2); pwps_ie += (wps_ielen+2); if (pbackup_remainder_ie) memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen); /* update IELength */ - pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen; + pnetwork->IELength = wps_offset + (wps_ielen + 2) + remainder_ielen; } kfree(pbackup_remainder_ie); /* deal with the case without set_tx_beacon_cmd() in update_beacon() */ #if defined(CONFIG_INTERRUPT_BASED_TXBCN) - if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { + if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { u8 sr = 0; rtw_get_wps_attr_content( @@ -1827,7 +1826,7 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx) /* op_mode -Set to 0 (HT pure) under the followign conditions +Set to 0 (HT pure) under the following conditions - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or - all STAs in the BSS are 20 MHz HT in 20 MHz BSS Set to 1 (HT non-member protection) if there may be non-HT STAs @@ -2196,7 +2195,7 @@ void rtw_sta_flush(struct adapter *padapter) DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); - if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) return; spin_lock_bh(&pstapriv->asoc_list_lock); @@ -2230,7 +2229,7 @@ void sta_info_update(struct adapter *padapter, struct sta_info *psta) struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); /* update wmm cap. */ - if (WLAN_STA_WME&flags) + if (WLAN_STA_WME & flags) psta->qos_option = 1; else psta->qos_option = 0; @@ -2239,7 +2238,7 @@ void sta_info_update(struct adapter *padapter, struct sta_info *psta) psta->qos_option = 0; /* update 802.11n ht cap. */ - if (WLAN_STA_HT&flags) { + if (WLAN_STA_HT & flags) { psta->htpriv.ht_option = true; psta->qos_option = 1; } else { diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index addc55706a3c..8d93c2f26890 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -402,7 +402,7 @@ int rtw_cmd_thread(void *context) { u8 ret; struct cmd_obj *pcmd; - u8 *pcmdbuf, *prspbuf; + u8 *pcmdbuf; unsigned long cmd_start_time; unsigned long cmd_process_time; u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); @@ -414,7 +414,6 @@ int rtw_cmd_thread(void *context) thread_enter("RTW_CMD_THREAD"); pcmdbuf = pcmdpriv->cmd_buf; - prspbuf = pcmdpriv->rsp_buf; pcmdpriv->stop_req = 0; atomic_set(&(pcmdpriv->cmdthd_running), true); @@ -768,7 +767,7 @@ exit: u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) { - u8 *auth, res = _SUCCESS; + u8 res = _SUCCESS; uint t_len = 0; struct wlan_bssid_ex *psecnetwork; struct cmd_obj *pcmd; @@ -825,7 +824,6 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network)); - auth = &psecuritypriv->authenticator_ie[0]; psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength; if ((psecnetwork->IELength-12) < (256-1)) { @@ -1819,11 +1817,6 @@ static void rtw_btinfo_hdl(struct adapter *adapter, u8 *buf, u16 buf_len) len = info->len; } -/* define DBG_PROC_SET_BTINFO_EVT */ -#ifdef DBG_PROC_SET_BTINFO_EVT - btinfo_evt_dump(RTW_DBGDUMP, info); -#endif - /* transform BT-FW btinfo to WiFI-FW C2H format and notify */ if (cmd_idx == BTINFO_WIFI_FETCH) buf[1] = 0; diff --git a/drivers/staging/rtl8723bs/core/rtw_debug.c b/drivers/staging/rtl8723bs/core/rtw_debug.c index 695a85999270..c48a8b80af4c 100644 --- a/drivers/staging/rtl8723bs/core/rtw_debug.c +++ b/drivers/staging/rtl8723bs/core/rtw_debug.c @@ -132,1310 +132,3 @@ void rf_reg_dump(void *sel, struct adapter *adapter) } } } - -#ifdef PROC_DEBUG -ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - u32 addr, val, len; - - if (count < 3) { - DBG_871X("argument size is less than 3\n"); - return -EFAULT; - } - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%x %x %x", &addr, &val, &len); - - if (num != 3) { - DBG_871X("invalid write_reg parameter!\n"); - return count; - } - - switch (len) { - case 1: - rtw_write8(padapter, addr, (u8)val); - break; - case 2: - rtw_write16(padapter, addr, (u16)val); - break; - case 4: - rtw_write32(padapter, addr, val); - break; - default: - DBG_871X("error write length =%d", len); - break; - } - - } - - return count; - -} - -static u32 proc_get_read_addr = 0xeeeeeeee; -static u32 proc_get_read_len = 0x4; - -int proc_get_read_reg(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - if (proc_get_read_addr == 0xeeeeeeee) { - DBG_871X_SEL_NL(m, "address not initialized\n"); - return 0; - } - - switch (proc_get_read_len) { - case 1: - DBG_871X_SEL_NL(m, "rtw_read8(0x%x) = 0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr)); - break; - case 2: - DBG_871X_SEL_NL(m, "rtw_read16(0x%x) = 0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr)); - break; - case 4: - DBG_871X_SEL_NL(m, "rtw_read32(0x%x) = 0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr)); - break; - default: - DBG_871X_SEL_NL(m, "error read length =%d\n", proc_get_read_len); - break; - } - - return 0; -} - -ssize_t proc_set_read_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - char tmp[16]; - u32 addr, len; - - if (count < 2) { - DBG_871X("argument size is less than 2\n"); - return -EFAULT; - } - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%x %x", &addr, &len); - - if (num != 2) { - DBG_871X("invalid read_reg parameter!\n"); - return count; - } - - proc_get_read_addr = addr; - - proc_get_read_len = len; - } - - return count; - -} - -int proc_get_fwstate(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - - DBG_871X_SEL_NL(m, "fwstate = 0x%x\n", get_fwstate(pmlmepriv)); - - return 0; -} - -int proc_get_sec_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct security_priv *sec = &padapter->securitypriv; - - DBG_871X_SEL_NL(m, "auth_alg = 0x%x, enc_alg = 0x%x, auth_type = 0x%x, enc_type = 0x%x\n", - sec->dot11AuthAlgrthm, sec->dot11PrivacyAlgrthm, - sec->ndisauthtype, sec->ndisencryptstatus); - - DBG_871X_SEL_NL(m, "hw_decrypted =%d\n", sec->hw_decrypted); - -#ifdef DBG_SW_SEC_CNT - DBG_871X_SEL_NL(m, "wep_sw_enc_cnt =%llu, %llu, %llu\n" - , sec->wep_sw_enc_cnt_bc, sec->wep_sw_enc_cnt_mc, sec->wep_sw_enc_cnt_uc); - DBG_871X_SEL_NL(m, "wep_sw_dec_cnt =%llu, %llu, %llu\n" - , sec->wep_sw_dec_cnt_bc, sec->wep_sw_dec_cnt_mc, sec->wep_sw_dec_cnt_uc); - - DBG_871X_SEL_NL(m, "tkip_sw_enc_cnt =%llu, %llu, %llu\n" - , sec->tkip_sw_enc_cnt_bc, sec->tkip_sw_enc_cnt_mc, sec->tkip_sw_enc_cnt_uc); - DBG_871X_SEL_NL(m, "tkip_sw_dec_cnt =%llu, %llu, %llu\n" - , sec->tkip_sw_dec_cnt_bc, sec->tkip_sw_dec_cnt_mc, sec->tkip_sw_dec_cnt_uc); - - DBG_871X_SEL_NL(m, "aes_sw_enc_cnt =%llu, %llu, %llu\n" - , sec->aes_sw_enc_cnt_bc, sec->aes_sw_enc_cnt_mc, sec->aes_sw_enc_cnt_uc); - DBG_871X_SEL_NL(m, "aes_sw_dec_cnt =%llu, %llu, %llu\n" - , sec->aes_sw_dec_cnt_bc, sec->aes_sw_dec_cnt_mc, sec->aes_sw_dec_cnt_uc); -#endif /* DBG_SW_SEC_CNT */ - - return 0; -} - -int proc_get_mlmext_state(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - - DBG_871X_SEL_NL(m, "pmlmeinfo->state = 0x%x\n", pmlmeinfo->state); - - return 0; -} - -int proc_get_roam_flags(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - DBG_871X_SEL_NL(m, "0x%02x\n", rtw_roam_flags(adapter)); - - return 0; -} - -ssize_t proc_set_roam_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - char tmp[32]; - u8 flags; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%hhx", &flags); - - if (num == 1) - rtw_assign_roam_flags(adapter, flags); - } - - return count; - -} - -int proc_get_roam_param(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *mlme = &adapter->mlmepriv; - - DBG_871X_SEL_NL(m, "%12s %12s %11s\n", "rssi_diff_th", "scanr_exp_ms", "scan_int_ms"); - DBG_871X_SEL_NL(m, "%-12u %-12u %-11u\n" - , mlme->roam_rssi_diff_th - , mlme->roam_scanr_exp_ms - , mlme->roam_scan_int_ms - ); - - return 0; -} - -ssize_t proc_set_roam_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *mlme = &adapter->mlmepriv; - - char tmp[32]; - u8 rssi_diff_th; - u32 scanr_exp_ms; - u32 scan_int_ms; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%hhu %u %u", &rssi_diff_th, &scanr_exp_ms, &scan_int_ms); - - if (num >= 1) - mlme->roam_rssi_diff_th = rssi_diff_th; - if (num >= 2) - mlme->roam_scanr_exp_ms = scanr_exp_ms; - if (num >= 3) - mlme->roam_scan_int_ms = scan_int_ms; - } - - return count; - -} - -ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - char tmp[32]; - u8 addr[ETH_ALEN]; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", addr, addr+1, addr+2, addr+3, addr+4, addr+5); - if (num == 6) - memcpy(adapter->mlmepriv.roam_tgt_addr, addr, ETH_ALEN); - - DBG_871X("set roam_tgt_addr to "MAC_FMT"\n", MAC_ARG(adapter->mlmepriv.roam_tgt_addr)); - } - - return count; -} - -int proc_get_qos_option(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - - DBG_871X_SEL_NL(m, "qos_option =%d\n", pmlmepriv->qospriv.qos_option); - - return 0; -} - -int proc_get_ht_option(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - - DBG_871X_SEL_NL(m, "ht_option =%d\n", pmlmepriv->htpriv.ht_option); - - return 0; -} - -int proc_get_rf_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - - DBG_871X_SEL_NL(m, "cur_ch =%d, cur_bw =%d, cur_ch_offet =%d\n", - pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); - - DBG_871X_SEL_NL(m, "oper_ch =%d, oper_bw =%d, oper_ch_offet =%d\n", - rtw_get_oper_ch(padapter), rtw_get_oper_bw(padapter), rtw_get_oper_choffset(padapter)); - - return 0; -} - -int proc_get_survey_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct __queue *queue = &(pmlmepriv->scanned_queue); - struct wlan_network *pnetwork = NULL; - struct list_head *plist, *phead; - s32 notify_signal; - s16 notify_noise = 0; - u16 index = 0; - - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); - phead = get_list_head(queue); - plist = phead ? get_next(phead) : NULL; - if ((!phead) || (!plist)) { - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); - return 0; - } - - DBG_871X_SEL_NL(m, "%5s %-17s %3s %-3s %-4s %-4s %5s %s\n", "index", "bssid", "ch", "RSSI", "SdBm", "Noise", "age", "ssid"); - while (1) { - if (phead == plist) - break; - - pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); - - if (!pnetwork) - break; - - if (check_fwstate(pmlmepriv, _FW_LINKED) == true && - is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { - notify_signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/*dbm*/ - } else { - notify_signal = translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);/*dbm*/ - } - - #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) - rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &(pnetwork->network.Configuration.DSConfig), &(notify_noise)); - #endif - - DBG_871X_SEL_NL(m, "%5d "MAC_FMT" %3d %3d %4d %4d %5d %s\n", - ++index, - MAC_ARG(pnetwork->network.MacAddress), - pnetwork->network.Configuration.DSConfig, - (int)pnetwork->network.Rssi, - notify_signal, - notify_noise, - jiffies_to_msecs(jiffies - pnetwork->last_scanned), - /*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength),*/ - pnetwork->network.Ssid.Ssid); - plist = get_next(plist); - } - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); - - return 0; -} - -int proc_get_ap_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct sta_info *psta; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct wlan_network *cur_network = &(pmlmepriv->cur_network); - struct sta_priv *pstapriv = &padapter->stapriv; - - psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); - if (psta) { - int i; - struct recv_reorder_ctrl *preorder_ctrl; - - DBG_871X_SEL_NL(m, "SSID =%s\n", cur_network->network.Ssid.Ssid); - DBG_871X_SEL_NL(m, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); - DBG_871X_SEL_NL(m, "cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); - DBG_871X_SEL_NL(m, "wireless_mode = 0x%x, rtsen =%d, cts2slef =%d\n", psta->wireless_mode, psta->rtsen, psta->cts2self); - DBG_871X_SEL_NL(m, "state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); - DBG_871X_SEL_NL(m, "qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); - DBG_871X_SEL_NL(m, "bwmode =%d, ch_offset =%d, sgi_20m =%d, sgi_40m =%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m); - DBG_871X_SEL_NL(m, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); - DBG_871X_SEL_NL(m, "agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); - DBG_871X_SEL_NL(m, "ldpc_cap = 0x%x, stbc_cap = 0x%x, beamform_cap = 0x%x\n", psta->htpriv.ldpc_cap, psta->htpriv.stbc_cap, psta->htpriv.beamform_cap); - - for (i = 0; i < 16; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - if (preorder_ctrl->enable) { - DBG_871X_SEL_NL(m, "tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq); - } - } - - } else { - DBG_871X_SEL_NL(m, "can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress)); - } - - return 0; -} - -int proc_get_adapter_state(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - DBG_871X_SEL_NL(m, "name =%s, bSurpriseRemoved =%d, bDriverStopped =%d\n", - dev->name, padapter->bSurpriseRemoved, padapter->bDriverStopped); - - return 0; -} - -int proc_get_trx_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - int i; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct recv_priv *precvpriv = &padapter->recvpriv; - struct hw_xmit *phwxmit; - - DBG_871X_SEL_NL(m, "free_xmitbuf_cnt =%d, free_xmitframe_cnt =%d\n" - , pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt); - DBG_871X_SEL_NL(m, "free_ext_xmitbuf_cnt =%d, free_xframe_ext_cnt =%d\n" - , pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt); - DBG_871X_SEL_NL(m, "free_recvframe_cnt =%d\n" - , precvpriv->free_recvframe_cnt); - - for (i = 0; i < 4; i++) { - phwxmit = pxmitpriv->hwxmits + i; - DBG_871X_SEL_NL(m, "%d, hwq.accnt =%d\n", i, phwxmit->accnt); - } - - return 0; -} - -int proc_get_rate_ctl(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - if (adapter->fix_rate != 0xff) { - DBG_871X_SEL_NL(m, "FIX\n"); - DBG_871X_SEL_NL(m, "0x%02x\n", adapter->fix_rate); - } else { - DBG_871X_SEL_NL(m, "RA\n"); - } - - return 0; -} - -ssize_t proc_set_rate_ctl(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - u8 fix_rate; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%hhx", &fix_rate); - - if (num >= 1) - adapter->fix_rate = fix_rate; - } - - return count; -} - -ssize_t proc_set_fwdl_test_case(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - char tmp[32]; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - sscanf(tmp, "%hhu %hhu", &g_fwdl_chksum_fail, &g_fwdl_wintint_rdy_fail); - } - - return count; -} - -ssize_t proc_set_wait_hiq_empty(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - char tmp[32]; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - sscanf(tmp, "%u", &g_wait_hiq_empty); - } - - return count; -} - -int proc_get_suspend_resume_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct dvobj_priv *dvobj = padapter->dvobj; - struct debug_priv *pdbgpriv = &dvobj->drv_dbg; - - DBG_871X_SEL_NL(m, "dbg_sdio_alloc_irq_cnt =%d\n", pdbgpriv->dbg_sdio_alloc_irq_cnt); - DBG_871X_SEL_NL(m, "dbg_sdio_free_irq_cnt =%d\n", pdbgpriv->dbg_sdio_free_irq_cnt); - DBG_871X_SEL_NL(m, "dbg_sdio_alloc_irq_error_cnt =%d\n", pdbgpriv->dbg_sdio_alloc_irq_error_cnt); - DBG_871X_SEL_NL(m, "dbg_sdio_free_irq_error_cnt =%d\n", pdbgpriv->dbg_sdio_free_irq_error_cnt); - DBG_871X_SEL_NL(m, "dbg_sdio_init_error_cnt =%d\n", pdbgpriv->dbg_sdio_init_error_cnt); - DBG_871X_SEL_NL(m, "dbg_sdio_deinit_error_cnt =%d\n", pdbgpriv->dbg_sdio_deinit_error_cnt); - DBG_871X_SEL_NL(m, "dbg_suspend_error_cnt =%d\n", pdbgpriv->dbg_suspend_error_cnt); - DBG_871X_SEL_NL(m, "dbg_suspend_cnt =%d\n", pdbgpriv->dbg_suspend_cnt); - DBG_871X_SEL_NL(m, "dbg_resume_cnt =%d\n", pdbgpriv->dbg_resume_cnt); - DBG_871X_SEL_NL(m, "dbg_resume_error_cnt =%d\n", pdbgpriv->dbg_resume_error_cnt); - DBG_871X_SEL_NL(m, "dbg_deinit_fail_cnt =%d\n", pdbgpriv->dbg_deinit_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_carddisable_cnt =%d\n", pdbgpriv->dbg_carddisable_cnt); - DBG_871X_SEL_NL(m, "dbg_ps_insuspend_cnt =%d\n", pdbgpriv->dbg_ps_insuspend_cnt); - DBG_871X_SEL_NL(m, "dbg_dev_unload_inIPS_cnt =%d\n", pdbgpriv->dbg_dev_unload_inIPS_cnt); - DBG_871X_SEL_NL(m, "dbg_scan_pwr_state_cnt =%d\n", pdbgpriv->dbg_scan_pwr_state_cnt); - DBG_871X_SEL_NL(m, "dbg_downloadfw_pwr_state_cnt =%d\n", pdbgpriv->dbg_downloadfw_pwr_state_cnt); - DBG_871X_SEL_NL(m, "dbg_carddisable_error_cnt =%d\n", pdbgpriv->dbg_carddisable_error_cnt); - DBG_871X_SEL_NL(m, "dbg_fw_read_ps_state_fail_cnt =%d\n", pdbgpriv->dbg_fw_read_ps_state_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_leave_ips_fail_cnt =%d\n", pdbgpriv->dbg_leave_ips_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_leave_lps_fail_cnt =%d\n", pdbgpriv->dbg_leave_lps_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_h2c_leave32k_fail_cnt =%d\n", pdbgpriv->dbg_h2c_leave32k_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_diswow_dload_fw_fail_cnt =%d\n", pdbgpriv->dbg_diswow_dload_fw_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_enwow_dload_fw_fail_cnt =%d\n", pdbgpriv->dbg_enwow_dload_fw_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_ips_drvopen_fail_cnt =%d\n", pdbgpriv->dbg_ips_drvopen_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_poll_fail_cnt =%d\n", pdbgpriv->dbg_poll_fail_cnt); - DBG_871X_SEL_NL(m, "dbg_rpwm_toggle_cnt =%d\n", pdbgpriv->dbg_rpwm_toggle_cnt); - DBG_871X_SEL_NL(m, "dbg_rpwm_timeout_fail_cnt =%d\n", pdbgpriv->dbg_rpwm_timeout_fail_cnt); - - return 0; -} - -#ifdef CONFIG_DBG_COUNTER - -int proc_get_rx_logs(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct rx_logs *rx_logs = &padapter->rx_logs; - - DBG_871X_SEL_NL(m, - "intf_rx =%d\n" - "intf_rx_err_recvframe =%d\n" - "intf_rx_err_skb =%d\n" - "intf_rx_report =%d\n" - "core_rx =%d\n" - "core_rx_pre =%d\n" - "core_rx_pre_ver_err =%d\n" - "core_rx_pre_mgmt =%d\n" - "core_rx_pre_mgmt_err_80211w =%d\n" - "core_rx_pre_mgmt_err =%d\n" - "core_rx_pre_ctrl =%d\n" - "core_rx_pre_ctrl_err =%d\n" - "core_rx_pre_data =%d\n" - "core_rx_pre_data_wapi_seq_err =%d\n" - "core_rx_pre_data_wapi_key_err =%d\n" - "core_rx_pre_data_handled =%d\n" - "core_rx_pre_data_err =%d\n" - "core_rx_pre_data_unknown =%d\n" - "core_rx_pre_unknown =%d\n" - "core_rx_enqueue =%d\n" - "core_rx_dequeue =%d\n" - "core_rx_post =%d\n" - "core_rx_post_decrypt =%d\n" - "core_rx_post_decrypt_wep =%d\n" - "core_rx_post_decrypt_tkip =%d\n" - "core_rx_post_decrypt_aes =%d\n" - "core_rx_post_decrypt_wapi =%d\n" - "core_rx_post_decrypt_hw =%d\n" - "core_rx_post_decrypt_unknown =%d\n" - "core_rx_post_decrypt_err =%d\n" - "core_rx_post_defrag_err =%d\n" - "core_rx_post_portctrl_err =%d\n" - "core_rx_post_indicate =%d\n" - "core_rx_post_indicate_in_oder =%d\n" - "core_rx_post_indicate_reoder =%d\n" - "core_rx_post_indicate_err =%d\n" - "os_indicate =%d\n" - "os_indicate_ap_mcast =%d\n" - "os_indicate_ap_forward =%d\n" - "os_indicate_ap_self =%d\n" - "os_indicate_err =%d\n" - "os_netif_ok =%d\n" - "os_netif_err =%d\n", - rx_logs->intf_rx, - rx_logs->intf_rx_err_recvframe, - rx_logs->intf_rx_err_skb, - rx_logs->intf_rx_report, - rx_logs->core_rx, - rx_logs->core_rx_pre, - rx_logs->core_rx_pre_ver_err, - rx_logs->core_rx_pre_mgmt, - rx_logs->core_rx_pre_mgmt_err_80211w, - rx_logs->core_rx_pre_mgmt_err, - rx_logs->core_rx_pre_ctrl, - rx_logs->core_rx_pre_ctrl_err, - rx_logs->core_rx_pre_data, - rx_logs->core_rx_pre_data_wapi_seq_err, - rx_logs->core_rx_pre_data_wapi_key_err, - rx_logs->core_rx_pre_data_handled, - rx_logs->core_rx_pre_data_err, - rx_logs->core_rx_pre_data_unknown, - rx_logs->core_rx_pre_unknown, - rx_logs->core_rx_enqueue, - rx_logs->core_rx_dequeue, - rx_logs->core_rx_post, - rx_logs->core_rx_post_decrypt, - rx_logs->core_rx_post_decrypt_wep, - rx_logs->core_rx_post_decrypt_tkip, - rx_logs->core_rx_post_decrypt_aes, - rx_logs->core_rx_post_decrypt_wapi, - rx_logs->core_rx_post_decrypt_hw, - rx_logs->core_rx_post_decrypt_unknown, - rx_logs->core_rx_post_decrypt_err, - rx_logs->core_rx_post_defrag_err, - rx_logs->core_rx_post_portctrl_err, - rx_logs->core_rx_post_indicate, - rx_logs->core_rx_post_indicate_in_oder, - rx_logs->core_rx_post_indicate_reoder, - rx_logs->core_rx_post_indicate_err, - rx_logs->os_indicate, - rx_logs->os_indicate_ap_mcast, - rx_logs->os_indicate_ap_forward, - rx_logs->os_indicate_ap_self, - rx_logs->os_indicate_err, - rx_logs->os_netif_ok, - rx_logs->os_netif_err - ); - - return 0; -} - -int proc_get_tx_logs(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct tx_logs *tx_logs = &padapter->tx_logs; - - DBG_871X_SEL_NL(m, - "os_tx =%d\n" - "os_tx_err_up =%d\n" - "os_tx_err_xmit =%d\n" - "os_tx_m2u =%d\n" - "os_tx_m2u_ignore_fw_linked =%d\n" - "os_tx_m2u_ignore_self =%d\n" - "os_tx_m2u_entry =%d\n" - "os_tx_m2u_entry_err_xmit =%d\n" - "os_tx_m2u_entry_err_skb =%d\n" - "os_tx_m2u_stop =%d\n" - "core_tx =%d\n" - "core_tx_err_pxmitframe =%d\n" - "core_tx_err_brtx =%d\n" - "core_tx_upd_attrib =%d\n" - "core_tx_upd_attrib_adhoc =%d\n" - "core_tx_upd_attrib_sta =%d\n" - "core_tx_upd_attrib_ap =%d\n" - "core_tx_upd_attrib_unknown =%d\n" - "core_tx_upd_attrib_dhcp =%d\n" - "core_tx_upd_attrib_icmp =%d\n" - "core_tx_upd_attrib_active =%d\n" - "core_tx_upd_attrib_err_ucast_sta =%d\n" - "core_tx_upd_attrib_err_ucast_ap_link =%d\n" - "core_tx_upd_attrib_err_sta =%d\n" - "core_tx_upd_attrib_err_link =%d\n" - "core_tx_upd_attrib_err_sec =%d\n" - "core_tx_ap_enqueue_warn_fwstate =%d\n" - "core_tx_ap_enqueue_warn_sta =%d\n" - "core_tx_ap_enqueue_warn_nosta =%d\n" - "core_tx_ap_enqueue_warn_link =%d\n" - "core_tx_ap_enqueue_warn_trigger =%d\n" - "core_tx_ap_enqueue_mcast =%d\n" - "core_tx_ap_enqueue_ucast =%d\n" - "core_tx_ap_enqueue =%d\n" - "intf_tx =%d\n" - "intf_tx_pending_ac =%d\n" - "intf_tx_pending_fw_under_survey =%d\n" - "intf_tx_pending_fw_under_linking =%d\n" - "intf_tx_pending_xmitbuf =%d\n" - "intf_tx_enqueue =%d\n" - "core_tx_enqueue =%d\n" - "core_tx_enqueue_class =%d\n" - "core_tx_enqueue_class_err_sta =%d\n" - "core_tx_enqueue_class_err_nosta =%d\n" - "core_tx_enqueue_class_err_fwlink =%d\n" - "intf_tx_direct =%d\n" - "intf_tx_direct_err_coalesce =%d\n" - "intf_tx_dequeue =%d\n" - "intf_tx_dequeue_err_coalesce =%d\n" - "intf_tx_dump_xframe =%d\n" - "intf_tx_dump_xframe_err_txdesc =%d\n" - "intf_tx_dump_xframe_err_port =%d\n", - tx_logs->os_tx, - tx_logs->os_tx_err_up, - tx_logs->os_tx_err_xmit, - tx_logs->os_tx_m2u, - tx_logs->os_tx_m2u_ignore_fw_linked, - tx_logs->os_tx_m2u_ignore_self, - tx_logs->os_tx_m2u_entry, - tx_logs->os_tx_m2u_entry_err_xmit, - tx_logs->os_tx_m2u_entry_err_skb, - tx_logs->os_tx_m2u_stop, - tx_logs->core_tx, - tx_logs->core_tx_err_pxmitframe, - tx_logs->core_tx_err_brtx, - tx_logs->core_tx_upd_attrib, - tx_logs->core_tx_upd_attrib_adhoc, - tx_logs->core_tx_upd_attrib_sta, - tx_logs->core_tx_upd_attrib_ap, - tx_logs->core_tx_upd_attrib_unknown, - tx_logs->core_tx_upd_attrib_dhcp, - tx_logs->core_tx_upd_attrib_icmp, - tx_logs->core_tx_upd_attrib_active, - tx_logs->core_tx_upd_attrib_err_ucast_sta, - tx_logs->core_tx_upd_attrib_err_ucast_ap_link, - tx_logs->core_tx_upd_attrib_err_sta, - tx_logs->core_tx_upd_attrib_err_link, - tx_logs->core_tx_upd_attrib_err_sec, - tx_logs->core_tx_ap_enqueue_warn_fwstate, - tx_logs->core_tx_ap_enqueue_warn_sta, - tx_logs->core_tx_ap_enqueue_warn_nosta, - tx_logs->core_tx_ap_enqueue_warn_link, - tx_logs->core_tx_ap_enqueue_warn_trigger, - tx_logs->core_tx_ap_enqueue_mcast, - tx_logs->core_tx_ap_enqueue_ucast, - tx_logs->core_tx_ap_enqueue, - tx_logs->intf_tx, - tx_logs->intf_tx_pending_ac, - tx_logs->intf_tx_pending_fw_under_survey, - tx_logs->intf_tx_pending_fw_under_linking, - tx_logs->intf_tx_pending_xmitbuf, - tx_logs->intf_tx_enqueue, - tx_logs->core_tx_enqueue, - tx_logs->core_tx_enqueue_class, - tx_logs->core_tx_enqueue_class_err_sta, - tx_logs->core_tx_enqueue_class_err_nosta, - tx_logs->core_tx_enqueue_class_err_fwlink, - tx_logs->intf_tx_direct, - tx_logs->intf_tx_direct_err_coalesce, - tx_logs->intf_tx_dequeue, - tx_logs->intf_tx_dequeue_err_coalesce, - tx_logs->intf_tx_dump_xframe, - tx_logs->intf_tx_dump_xframe_err_txdesc, - tx_logs->intf_tx_dump_xframe_err_port - ); - - return 0; -} - -int proc_get_int_logs(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - DBG_871X_SEL_NL(m, - "all =%d\n" - "err =%d\n" - "tbdok =%d\n" - "tbder =%d\n" - "bcnderr =%d\n" - "bcndma =%d\n" - "bcndma_e =%d\n" - "rx =%d\n" - "rx_rdu =%d\n" - "rx_fovw =%d\n" - "txfovw =%d\n" - "mgntok =%d\n" - "highdok =%d\n" - "bkdok =%d\n" - "bedok =%d\n" - "vidok =%d\n" - "vodok =%d\n", - padapter->int_logs.all, - padapter->int_logs.err, - padapter->int_logs.tbdok, - padapter->int_logs.tbder, - padapter->int_logs.bcnderr, - padapter->int_logs.bcndma, - padapter->int_logs.bcndma_e, - padapter->int_logs.rx, - padapter->int_logs.rx_rdu, - padapter->int_logs.rx_fovw, - padapter->int_logs.txfovw, - padapter->int_logs.mgntok, - padapter->int_logs.highdok, - padapter->int_logs.bkdok, - padapter->int_logs.bedok, - padapter->int_logs.vidok, - padapter->int_logs.vodok - ); - - return 0; -} - -#endif /* CONFIG_DBG_COUNTER*/ - -int proc_get_rx_signal(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - DBG_871X_SEL_NL(m, "rssi:%d\n", padapter->recvpriv.rssi); - /*DBG_871X_SEL_NL(m, "rxpwdb:%d\n", padapter->recvpriv.rxpwdb);*/ - DBG_871X_SEL_NL(m, "signal_strength:%u\n", padapter->recvpriv.signal_strength); - DBG_871X_SEL_NL(m, "signal_qual:%u\n", padapter->recvpriv.signal_qual); - DBG_871X_SEL_NL(m, "noise:%d\n", padapter->recvpriv.noise); - rtw_odm_get_perpkt_rssi(m, padapter); - #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA - rtw_get_raw_rssi_info(m, padapter); - #endif - return 0; -} - - -int proc_get_hw_status(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct dvobj_priv *dvobj = padapter->dvobj; - struct debug_priv *pdbgpriv = &dvobj->drv_dbg; - - DBG_871X_SEL_NL(m, "RX FIFO full count: last_time =%lld, current_time =%lld, differential =%lld\n" - , pdbgpriv->dbg_rx_fifo_last_overflow, pdbgpriv->dbg_rx_fifo_curr_overflow, pdbgpriv->dbg_rx_fifo_diff_overflow); - - return 0; -} - -ssize_t proc_set_rx_signal(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - u32 is_signal_dbg, signal_strength; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength); - - is_signal_dbg = is_signal_dbg == 0?0:1; - - if (is_signal_dbg && num != 2) - return count; - - signal_strength = signal_strength > 100?100:signal_strength; - - padapter->recvpriv.is_signal_dbg = is_signal_dbg; - padapter->recvpriv.signal_strength_dbg = signal_strength; - - if (is_signal_dbg) - DBG_871X("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength); - else - DBG_871X("set %s\n", "HW_SIGNAL_STRENGTH"); - - } - - return count; - -} - -int proc_get_ht_enable(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - - if (pregpriv) - DBG_871X_SEL_NL(m, "%d\n", pregpriv->ht_enable); - - return 0; -} - -ssize_t proc_set_ht_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - char tmp[32]; - u32 mode; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - sscanf(tmp, "%d ", &mode); - - if (pregpriv && mode < 2) { - pregpriv->ht_enable = mode; - printk("ht_enable =%d\n", pregpriv->ht_enable); - } - } - - return count; - -} - -int proc_get_bw_mode(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - - if (pregpriv) - DBG_871X_SEL_NL(m, "0x%02x\n", pregpriv->bw_mode); - - return 0; -} - -ssize_t proc_set_bw_mode(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - char tmp[32]; - u32 mode; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - sscanf(tmp, "%d ", &mode); - - if (pregpriv && mode < 2) { - - pregpriv->bw_mode = mode; - printk("bw_mode =%d\n", mode); - - } - } - - return count; - -} - -int proc_get_ampdu_enable(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - - if (pregpriv) - DBG_871X_SEL_NL(m, "%d\n", pregpriv->ampdu_enable); - - return 0; -} - -ssize_t proc_set_ampdu_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - char tmp[32]; - u32 mode; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - sscanf(tmp, "%d ", &mode); - - if (pregpriv && mode < 3) { - pregpriv->ampdu_enable = mode; - printk("ampdu_enable =%d\n", mode); - } - - } - - return count; - -} - -int proc_get_rx_ampdu(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - - if (pregpriv) - DBG_871X_SEL_NL(m, - "accept_addba_req = %d , 0:Reject AP's Add BA req, 1:Accept AP's Add BA req.\n", - pmlmeinfo->accept_addba_req - ); - - return 0; -} - -ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - char tmp[32]; - u32 mode; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - sscanf(tmp, "%d ", &mode); - - if (pregpriv && mode < 2) { - pmlmeinfo->accept_addba_req = mode; - DBG_871X("pmlmeinfo->accept_addba_req =%d\n", - pmlmeinfo->accept_addba_req); - if (mode == 0) { - /*tear down Rx AMPDU*/ - send_delba(padapter, 0, get_my_bssid(&(pmlmeinfo->network)));/* recipient*/ - } - } - - } - - return count; -} - -int proc_get_en_fwps(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - - if (pregpriv) - DBG_871X_SEL_NL(m, "check_fw_ps = %d , 1:enable get FW PS state , 0: disable get FW PS state\n" - , pregpriv->check_fw_ps); - - return 0; -} - -ssize_t proc_set_en_fwps(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - char tmp[32]; - u32 mode; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - sscanf(tmp, "%d ", &mode); - - if (pregpriv && mode < 2) { - pregpriv->check_fw_ps = mode; - DBG_871X("pregpriv->check_fw_ps =%d\n", pregpriv->check_fw_ps); - } - } - return count; -} - -int proc_get_rx_stbc(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - - if (pregpriv) - DBG_871X_SEL_NL(m, "%d\n", pregpriv->rx_stbc); - - return 0; -} - -ssize_t proc_set_rx_stbc(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct registry_priv *pregpriv = &padapter->registrypriv; - char tmp[32]; - u32 mode; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - sscanf(tmp, "%d ", &mode); - - if (pregpriv && (mode == 0 || mode == 1 || - mode == 2 || mode == 3)) { - pregpriv->rx_stbc = mode; - printk("rx_stbc =%d\n", mode); - } - } - - return count; - -} - -int proc_get_rssi_disp(struct seq_file *m, void *v) -{ - return 0; -} - -ssize_t proc_set_rssi_disp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - u32 enable = 0; - - if (count < 1) { - DBG_8192C("argument size is less than 1\n"); - return -EFAULT; - } - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - int num = sscanf(tmp, "%x", &enable); - - if (num != 1) { - DBG_8192C("invalid set_rssi_disp parameter!\n"); - return count; - } - - if (enable) { - DBG_8192C("Linked info Function Enable\n"); - padapter->bLinkInfoDump = enable; - } else { - DBG_8192C("Linked info Function Disable\n"); - padapter->bLinkInfoDump = 0; - } - } - return count; -} - -int proc_get_all_sta_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct sta_info *psta; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct sta_priv *pstapriv = &padapter->stapriv; - int i, j; - struct list_head *plist, *phead; - struct recv_reorder_ctrl *preorder_ctrl; - - DBG_871X_SEL_NL(m, "sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); - - spin_lock_bh(&pstapriv->sta_hash_lock); - - for (i = 0; i < NUM_STA; i++) { - phead = &(pstapriv->sta_hash[i]); - plist = get_next(phead); - - while (phead != plist) { - psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); - - plist = get_next(plist); - - DBG_871X_SEL_NL(m, "==============================\n"); - DBG_871X_SEL_NL(m, "sta's macaddr:" MAC_FMT "\n", - MAC_ARG(psta->hwaddr)); - DBG_871X_SEL_NL(m, "rtsen =%d, cts2slef =%d\n", - psta->rtsen, psta->cts2self); - DBG_871X_SEL_NL(m, "state = 0x%x, aid =%d, macid =%d, raid =%d\n", - psta->state, psta->aid, psta->mac_id, - psta->raid); - DBG_871X_SEL_NL(m, "qos_en =%d, ht_en =%d, init_rate =%d\n", - psta->qos_option, - psta->htpriv.ht_option, - psta->init_rate); - DBG_871X_SEL_NL(m, "bwmode =%d, ch_offset =%d, sgi_20m =%d, sgi_40m =%d\n", - psta->bw_mode, psta->htpriv.ch_offset, - psta->htpriv.sgi_20m, - psta->htpriv.sgi_40m); - DBG_871X_SEL_NL(m, "ampdu_enable = %d\n", - psta->htpriv.ampdu_enable); - DBG_871X_SEL_NL(m, "agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", - psta->htpriv.agg_enable_bitmap, - psta->htpriv.candidate_tid_bitmap); - DBG_871X_SEL_NL(m, "sleepq_len =%d\n", - psta->sleepq_len); - DBG_871X_SEL_NL(m, "sta_xmitpriv.vo_q_qcnt =%d\n", - psta->sta_xmitpriv.vo_q.qcnt); - DBG_871X_SEL_NL(m, "sta_xmitpriv.vi_q_qcnt =%d\n", - psta->sta_xmitpriv.vi_q.qcnt); - DBG_871X_SEL_NL(m, "sta_xmitpriv.be_q_qcnt =%d\n", - psta->sta_xmitpriv.be_q.qcnt); - DBG_871X_SEL_NL(m, "sta_xmitpriv.bk_q_qcnt =%d\n", - psta->sta_xmitpriv.bk_q.qcnt); - - DBG_871X_SEL_NL(m, "capability = 0x%x\n", - psta->capability); - DBG_871X_SEL_NL(m, "flags = 0x%x\n", psta->flags); - DBG_871X_SEL_NL(m, "wpa_psk = 0x%x\n", psta->wpa_psk); - DBG_871X_SEL_NL(m, "wpa2_group_cipher = 0x%x\n", - psta->wpa2_group_cipher); - DBG_871X_SEL_NL(m, "wpa2_pairwise_cipher = 0x%x\n", - psta->wpa2_pairwise_cipher); - DBG_871X_SEL_NL(m, "qos_info = 0x%x\n", psta->qos_info); - DBG_871X_SEL_NL(m, "dot118021XPrivacy = 0x%x\n", - psta->dot118021XPrivacy); - - for (j = 0; j < 16; j++) { - preorder_ctrl = &psta->recvreorder_ctrl[j]; - if (preorder_ctrl->enable) - DBG_871X_SEL_NL(m, "tid =%d, indicate_seq =%d\n", - j, preorder_ctrl->indicate_seq); - } - DBG_871X_SEL_NL(m, "==============================\n"); - } - } - - spin_unlock_bh(&pstapriv->sta_hash_lock); - - return 0; -} - -int proc_get_btcoex_dbg(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter; - char buf[512] = {0}; - padapter = (struct adapter *)rtw_netdev_priv(dev); - - hal_btcoex_GetDBG(padapter, buf, 512); - - DBG_871X_SEL(m, "%s", buf); - - return 0; -} - -ssize_t proc_set_btcoex_dbg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter; - u8 tmp[80] = {0}; - u32 module[2] = {0}; - u32 num; - - padapter = (struct adapter *)rtw_netdev_priv(dev); - -/* DBG_871X("+" FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));*/ - - if (NULL == buffer) { - DBG_871X(FUNC_ADPT_FMT ": input buffer is NULL!\n", - FUNC_ADPT_ARG(padapter)); - - return -EFAULT; - } - - if (count < 1) { - DBG_871X(FUNC_ADPT_FMT ": input length is 0!\n", - FUNC_ADPT_ARG(padapter)); - - return -EFAULT; - } - - num = count; - if (num > (sizeof(tmp) - 1)) - num = (sizeof(tmp) - 1); - - if (copy_from_user(tmp, buffer, num)) { - DBG_871X(FUNC_ADPT_FMT ": copy buffer from user space FAIL!\n", - FUNC_ADPT_ARG(padapter)); - - return -EFAULT; - } - - num = sscanf(tmp, "%x %x", module, module+1); - if (num == 1) { - if (module[0] == 0) - memset(module, 0, sizeof(module)); - else - memset(module, 0xFF, sizeof(module)); - } else if (num != 2) { - DBG_871X(FUNC_ADPT_FMT ": input(\"%s\") format incorrect!\n", - FUNC_ADPT_ARG(padapter), tmp); - - if (num == 0) - return -EFAULT; - } - - DBG_871X(FUNC_ADPT_FMT ": input 0x%08X 0x%08X\n", - FUNC_ADPT_ARG(padapter), module[0], module[1]); - hal_btcoex_SetDBG(padapter, module); - - return count; -} - -int proc_get_btcoex_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter; - const u32 bufsize = 30*100; - u8 *pbuf = NULL; - - padapter = (struct adapter *)rtw_netdev_priv(dev); - - pbuf = rtw_zmalloc(bufsize); - if (!pbuf) - return -ENOMEM; - - hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize); - - DBG_871X_SEL(m, "%s\n", pbuf); - - kfree(pbuf); - - return 0; -} - -#endif diff --git a/drivers/staging/rtl8723bs/core/rtw_io.c b/drivers/staging/rtl8723bs/core/rtw_io.c index a92bc19b196a..57168578663a 100644 --- a/drivers/staging/rtl8723bs/core/rtw_io.c +++ b/drivers/staging/rtl8723bs/core/rtw_io.c @@ -142,7 +142,7 @@ u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); struct io_priv *pio_priv = &adapter->iopriv; struct intf_hdl *pintfhdl = &(pio_priv->intf); - u32 ret = _SUCCESS; + u32 ret; _write_port = pintfhdl->io_ops._write_port; diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c index 8eb0ff57925f..eb08569db5ea 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c @@ -9,13 +9,6 @@ #include <drv_types.h> #include <rtw_debug.h> -#define IS_MAC_ADDRESS_BROADCAST(addr) \ -(\ - ((addr[0] == 0xff) && (addr[1] == 0xff) && \ - (addr[2] == 0xff) && (addr[3] == 0xff) && \ - (addr[4] == 0xff) && (addr[5] == 0xff)) ? true : false \ -) - u8 rtw_validate_bssid(u8 *bssid) { u8 ret = true; diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 4285844420cb..2128886c9924 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -295,11 +295,7 @@ static void init_mlme_ext_priv_value(struct adapter *padapter) init_mlme_default_rate_set(padapter); - if (pmlmeext->cur_channel > 14) - pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB; - else - pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; - + pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; pmlmeext->sitesurvey_res.state = SCAN_DISABLE; pmlmeext->sitesurvey_res.channel_idx = 0; pmlmeext->sitesurvey_res.bss_cnt = 0; @@ -459,9 +455,8 @@ static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, RT_CHANNEL_ return chanset_size; } -int init_mlme_ext_priv(struct adapter *padapter) +void init_mlme_ext_priv(struct adapter *padapter) { - int res = _SUCCESS; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -488,9 +483,6 @@ int init_mlme_ext_priv(struct adapter *padapter) #ifdef DBG_FIXED_CHAN pmlmeext->fixed_chan = 0xFF; #endif - - return res; - } void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) @@ -1882,7 +1874,6 @@ unsigned int OnAtim(struct adapter *padapter, union recv_frame *precv_frame) unsigned int on_action_spct(struct adapter *padapter, union recv_frame *precv_frame) { - unsigned int ret = _FAIL; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; u8 *pframe = precv_frame->u.hdr.rx_data; @@ -1914,7 +1905,7 @@ unsigned int on_action_spct(struct adapter *padapter, union recv_frame *precv_fr } exit: - return ret; + return _FAIL; } unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_frame) diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c index ae7fb7046c93..4075de07e0a9 100644 --- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c @@ -103,7 +103,7 @@ static bool rtw_pwr_unassociated_idle(struct adapter *adapter) bool ret = false; - if (adapter_to_pwrctl(adapter)->bpower_saving == true) { + if (adapter_to_pwrctl(adapter)->bpower_saving) { /* DBG_871X("%s: already in LPS or IPS mode\n", __func__); */ goto exit; } @@ -167,7 +167,7 @@ void rtw_ps_processor(struct adapter *padapter) goto exit; } - if (pwrpriv->bInSuspend == true) {/* system suspend or autosuspend */ + if (pwrpriv->bInSuspend) {/* system suspend or autosuspend */ pdbgpriv->dbg_ps_insuspend_cnt++; DBG_871X("%s, pwrpriv->bInSuspend == true ignore this process\n", __func__); return; @@ -219,10 +219,9 @@ void traffic_check_for_leave_lps(struct adapter *padapter, u8 tx, u32 tx_packets if (jiffies_to_msecs(jiffies - start_time) > 2000) { /* 2 sec == watch dog timer */ if (xmit_cnt > 8) { - if ((adapter_to_pwrctl(padapter)->bLeisurePs) - && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) - && (hal_btcoex_IsBtControlLps(padapter) == false) - ) { + if (adapter_to_pwrctl(padapter)->bLeisurePs + && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) + && !(hal_btcoex_IsBtControlLps(padapter))) { DBG_871X("leave lps via Tx = %d\n", xmit_cnt); bLeaveLPS = true; } @@ -234,10 +233,9 @@ void traffic_check_for_leave_lps(struct adapter *padapter, u8 tx, u32 tx_packets } else { /* from rx path */ if (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4/*2*/) { - if ((adapter_to_pwrctl(padapter)->bLeisurePs) - && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) - && (hal_btcoex_IsBtControlLps(padapter) == false) - ) { + if (adapter_to_pwrctl(padapter)->bLeisurePs + && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) + && !(hal_btcoex_IsBtControlLps(padapter))) { DBG_871X("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); bLeaveLPS = true; } @@ -267,7 +265,7 @@ void rtw_set_rpwm(struct adapter *padapter, u8 pslv) pslv = PS_STATE(pslv); - if (pwrpriv->brpwmtimeout == true) { + if (pwrpriv->brpwmtimeout) { DBG_871X("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __func__, pslv); } else { if ((pwrpriv->rpwm == pslv) @@ -278,8 +276,7 @@ void rtw_set_rpwm(struct adapter *padapter, u8 pslv) } } - if ((padapter->bSurpriseRemoved == true) || - (padapter->hw_init_completed == false)) { + if ((padapter->bSurpriseRemoved) || !(padapter->hw_init_completed)) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n", __func__, padapter->bSurpriseRemoved, padapter->hw_init_completed)); @@ -289,7 +286,7 @@ void rtw_set_rpwm(struct adapter *padapter, u8 pslv) return; } - if (padapter->bDriverStopped == true) { + if (padapter->bDriverStopped) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("%s: change power state(0x%02X) when DriverStopped\n", __func__, pslv)); @@ -355,14 +352,14 @@ static u8 PS_RDY_CHECK(struct adapter *padapter) struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) - if (true == pwrpriv->bInSuspend && pwrpriv->wowlan_mode) + if (pwrpriv->bInSuspend && pwrpriv->wowlan_mode) return true; - else if (true == pwrpriv->bInSuspend && pwrpriv->wowlan_ap_mode) + else if (pwrpriv->bInSuspend && pwrpriv->wowlan_ap_mode) return true; - else if (true == pwrpriv->bInSuspend) + else if (pwrpriv->bInSuspend) return false; #else - if (true == pwrpriv->bInSuspend) + if (pwrpriv->bInSuspend) return false; #endif @@ -381,7 +378,7 @@ static u8 PS_RDY_CHECK(struct adapter *padapter) ) return false; - if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == false)) { + if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && !(padapter->securitypriv.binstallGrpkey)) { DBG_871X("Group handshake still in progress !!!\n"); return false; } @@ -417,13 +414,9 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a /* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */ if (ps_mode == PS_MODE_ACTIVE) { - if (1 - && (((hal_btcoex_IsBtControlLps(padapter) == false) - ) - || ((hal_btcoex_IsBtControlLps(padapter) == true) - && (hal_btcoex_IsLpsOn(padapter) == false)) - ) - ) { + if (!(hal_btcoex_IsBtControlLps(padapter)) + || (hal_btcoex_IsBtControlLps(padapter) + && !(hal_btcoex_IsLpsOn(padapter)))) { DBG_871X(FUNC_ADPT_FMT" Leave 802.11 power save - %s\n", FUNC_ADPT_ARG(padapter), msg); @@ -431,8 +424,7 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a rtw_set_rpwm(padapter, PS_STATE_S4); #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) - if (pwrpriv->wowlan_mode == true || - pwrpriv->wowlan_ap_mode == true) { + if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode) { unsigned long start_time; u32 delay_ms; u8 val8; @@ -461,8 +453,8 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a } } else { if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) - || ((hal_btcoex_IsBtControlLps(padapter) == true) - && (hal_btcoex_IsLpsOn(padapter) == true)) + || ((hal_btcoex_IsBtControlLps(padapter)) + && (hal_btcoex_IsLpsOn(padapter))) ) { u8 pslv; @@ -481,8 +473,8 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a if (pwrpriv->alives == 0) pslv = PS_STATE_S0; - if ((hal_btcoex_IsBtDisabled(padapter) == false) - && (hal_btcoex_IsBtControlLps(padapter) == true)) { + if (!(hal_btcoex_IsBtDisabled(padapter)) + && (hal_btcoex_IsBtControlLps(padapter))) { u8 val8; val8 = hal_btcoex_LpsVal(padapter); @@ -513,10 +505,10 @@ s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) start_time = jiffies; while (1) { rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake); - if (true == bAwake) + if (bAwake) break; - if (true == padapter->bSurpriseRemoved) { + if (padapter->bSurpriseRemoved) { err = -2; DBG_871X("%s: device surprise removed!!\n", __func__); break; @@ -544,7 +536,7 @@ void LPS_Enter(struct adapter *padapter, const char *msg) int n_assoc_iface = 0; char buf[32] = {0}; - if (hal_btcoex_IsBtControlLps(padapter) == true) + if (hal_btcoex_IsBtControlLps(padapter)) return; /* Skip lps enter request if number of assocated adapters is not 1 */ @@ -557,8 +549,8 @@ void LPS_Enter(struct adapter *padapter, const char *msg) if (get_iface_type(padapter) != IFACE_PORT0) return; - if (PS_RDY_CHECK(dvobj->padapters) == false) - return; + if (!PS_RDY_CHECK(dvobj->padapters)) + return; if (pwrpriv->bLeisurePs) { /* Idle for a while if we connect to AP a while ago. */ @@ -589,7 +581,7 @@ void LPS_Leave(struct adapter *padapter, const char *msg) /* DBG_871X("+LeisurePSLeave\n"); */ - if (hal_btcoex_IsBtControlLps(padapter) == true) + if (hal_btcoex_IsBtControlLps(padapter)) return; if (pwrpriv->bLeisurePs) { @@ -615,13 +607,13 @@ void LeaveAllPowerSaveModeDirect(struct adapter *Adapter) DBG_871X("%s.....\n", __func__); - if (true == Adapter->bSurpriseRemoved) { + if (Adapter->bSurpriseRemoved) { DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved =%d Skip!\n", FUNC_ADPT_ARG(Adapter), Adapter->bSurpriseRemoved); return; } - if ((check_fwstate(pmlmepriv, _FW_LINKED) == true)) { /* connect */ + if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */ if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) { DBG_871X("%s: Driver Already Leave LPS\n", __func__); @@ -637,7 +629,7 @@ void LeaveAllPowerSaveModeDirect(struct adapter *Adapter) rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0); } else { if (pwrpriv->rf_pwrstate == rf_off) - if (false == ips_leave(pri_padapter)) + if (!ips_leave(pri_padapter)) DBG_871X("======> ips_leave fail.............\n"); } } @@ -675,7 +667,7 @@ void LeaveAllPowerSaveMode(struct adapter *Adapter) LPS_Leave_check(Adapter); } else { if (adapter_to_pwrctl(Adapter)->rf_pwrstate == rf_off) { - if (false == ips_leave(Adapter)) + if (!ips_leave(Adapter)) DBG_871X("======> ips_leave fail.............\n"); } } @@ -698,15 +690,14 @@ void LPS_Leave_check( while (1) { mutex_lock(&pwrpriv->lock); - if ((padapter->bSurpriseRemoved == true) - || (padapter->hw_init_completed == false) - || (pwrpriv->pwr_mode == PS_MODE_ACTIVE) - ) + if (padapter->bSurpriseRemoved + || !(padapter->hw_init_completed) + || (pwrpriv->pwr_mode == PS_MODE_ACTIVE)) bReady = true; mutex_unlock(&pwrpriv->lock); - if (true == bReady) + if (bReady) break; if (jiffies_to_msecs(jiffies - start_time) > 100) { @@ -830,12 +821,12 @@ static void pwr_rpwm_timeout_handler(struct timer_list *t) _set_workitem(&pwrpriv->rpwmtimeoutwi); } -static __inline void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) +static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) { pwrctrl->alives |= tag; } -static __inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) +static inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) { pwrctrl->alives &= ~tag; } @@ -870,7 +861,7 @@ s32 rtw_register_task_alive(struct adapter *padapter, u32 task) register_task_alive(pwrctrl, task); - if (pwrctrl->bFwCurrentInPSMode == true) { + if (pwrctrl->bFwCurrentInPSMode) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, ("%s: task = 0x%x cpwm = 0x%02x alives = 0x%08x\n", __func__, task, pwrctrl->cpwm, pwrctrl->alives)); @@ -910,8 +901,8 @@ void rtw_unregister_task_alive(struct adapter *padapter, u32 task) pwrctrl = adapter_to_pwrctl(padapter); pslv = PS_STATE_S0; - if ((hal_btcoex_IsBtDisabled(padapter) == false) - && (hal_btcoex_IsBtControlLps(padapter) == true)) { + if (!(hal_btcoex_IsBtDisabled(padapter)) + && hal_btcoex_IsBtControlLps(padapter)) { u8 val8; val8 = hal_btcoex_LpsVal(padapter); @@ -924,7 +915,7 @@ void rtw_unregister_task_alive(struct adapter *padapter, u32 task) unregister_task_alive(pwrctrl, task); if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) - && (pwrctrl->bFwCurrentInPSMode == true)) { + && pwrctrl->bFwCurrentInPSMode) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, ("%s: cpwm = 0x%02x alives = 0x%08x\n", __func__, pwrctrl->cpwm, pwrctrl->alives)); @@ -965,7 +956,7 @@ s32 rtw_register_tx_alive(struct adapter *padapter) register_task_alive(pwrctrl, XMIT_ALIVE); - if (pwrctrl->bFwCurrentInPSMode == true) { + if (pwrctrl->bFwCurrentInPSMode) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, ("rtw_register_tx_alive: cpwm = 0x%02x alives = 0x%08x\n", pwrctrl->cpwm, pwrctrl->alives)); @@ -1014,7 +1005,7 @@ s32 rtw_register_cmd_alive(struct adapter *padapter) register_task_alive(pwrctrl, CMD_ALIVE); - if (pwrctrl->bFwCurrentInPSMode == true) { + if (pwrctrl->bFwCurrentInPSMode) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_, ("rtw_register_cmd_alive: cpwm = 0x%02x alives = 0x%08x\n", pwrctrl->cpwm, pwrctrl->alives)); @@ -1051,8 +1042,8 @@ void rtw_unregister_tx_alive(struct adapter *padapter) pwrctrl = adapter_to_pwrctl(padapter); pslv = PS_STATE_S0; - if ((hal_btcoex_IsBtDisabled(padapter) == false) - && (hal_btcoex_IsBtControlLps(padapter) == true)) { + if (!(hal_btcoex_IsBtDisabled(padapter)) + && hal_btcoex_IsBtControlLps(padapter)) { u8 val8; val8 = hal_btcoex_LpsVal(padapter); @@ -1065,7 +1056,7 @@ void rtw_unregister_tx_alive(struct adapter *padapter) unregister_task_alive(pwrctrl, XMIT_ALIVE); if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) - && (pwrctrl->bFwCurrentInPSMode == true)) { + && pwrctrl->bFwCurrentInPSMode) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, ("%s: cpwm = 0x%02x alives = 0x%08x\n", __func__, pwrctrl->cpwm, pwrctrl->alives)); @@ -1093,8 +1084,8 @@ void rtw_unregister_cmd_alive(struct adapter *padapter) pwrctrl = adapter_to_pwrctl(padapter); pslv = PS_STATE_S0; - if ((hal_btcoex_IsBtDisabled(padapter) == false) - && (hal_btcoex_IsBtControlLps(padapter) == true)) { + if (!(hal_btcoex_IsBtDisabled(padapter)) + && hal_btcoex_IsBtControlLps(padapter)) { u8 val8; val8 = hal_btcoex_LpsVal(padapter); @@ -1107,7 +1098,7 @@ void rtw_unregister_cmd_alive(struct adapter *padapter) unregister_task_alive(pwrctrl, CMD_ALIVE); if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) - && (pwrctrl->bFwCurrentInPSMode == true)) { + && pwrctrl->bFwCurrentInPSMode) { RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_, ("%s: cpwm = 0x%02x alives = 0x%08x\n", __func__, pwrctrl->cpwm, pwrctrl->alives)); @@ -1237,7 +1228,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal DBG_871X("%s wait ps_processing done\n", __func__); } - if (pwrpriv->bInternalAutoSuspend == false && pwrpriv->bInSuspend) { + if (!(pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) { DBG_871X("%s wait bInSuspend...\n", __func__); while (pwrpriv->bInSuspend && jiffies_to_msecs(jiffies - start) <= 3000 @@ -1251,19 +1242,19 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal } /* System suspend is not allowed to wakeup */ - if ((pwrpriv->bInternalAutoSuspend == false) && (true == pwrpriv->bInSuspend)) { + if (!(pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) { ret = _FAIL; goto exit; } /* block??? */ - if ((pwrpriv->bInternalAutoSuspend == true) && (padapter->net_closed == true)) { + if (pwrpriv->bInternalAutoSuspend && padapter->net_closed) { ret = _FAIL; goto exit; } /* I think this should be check in IPS, LPS, autosuspend functions... */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { + if (check_fwstate(pmlmepriv, _FW_LINKED)) { ret = _SUCCESS; goto exit; } diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c index 979056c3d397..57cfe06d7d73 100644 --- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -2290,8 +2290,7 @@ static void gf_mulx(u8 *pad) static void aes_encrypt_deinit(void *ctx) { - memset(ctx, 0, AES_PRIV_SIZE); - kfree(ctx); + kzfree(ctx); } diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index 76c50377f0fe..ea3ea2a6b314 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -451,7 +451,7 @@ void set_channel_bwmode(struct adapter *padapter, unsigned char channel, unsigne mutex_unlock(&(adapter_to_dvobj(padapter)->setch_mutex)); } -__inline u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork) +inline u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork) { return pnetwork->MacAddress; } @@ -1996,11 +1996,6 @@ void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) } } -void beacon_timing_control(struct adapter *padapter) -{ - rtw_hal_bcn_related_reg_setting(padapter); -} - void rtw_alloc_macid(struct adapter *padapter, struct sta_info *psta) { int i; diff --git a/drivers/staging/rtl8723bs/hal/HalBtc8723b1Ant.c b/drivers/staging/rtl8723bs/hal/HalBtc8723b1Ant.c index 8e4caeeb4070..dd349c506da8 100644 --- a/drivers/staging/rtl8723bs/hal/HalBtc8723b1Ant.c +++ b/drivers/staging/rtl8723bs/hal/HalBtc8723b1Ant.c @@ -1758,7 +1758,6 @@ static void halbtc8723b1ant_TdmaDurationAdjustForAcl( static s32 up, dn, m, n, WaitCount; s32 result; /* 0: no change, +1: increase WiFi duration, -1: decrease WiFi duration */ u8 retryCount = 0, btInfoExt; - bool bWifiBusy = false; BTC_PRINT( BTC_MSG_ALGORITHM, @@ -1766,11 +1765,6 @@ static void halbtc8723b1ant_TdmaDurationAdjustForAcl( ("[BTCoex], TdmaDurationAdjustForAcl()\n") ); - if (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifiStatus) - bWifiBusy = true; - else - bWifiBusy = false; - if ( (BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || diff --git a/drivers/staging/rtl8723bs/hal/HalBtcOutSrc.h b/drivers/staging/rtl8723bs/hal/HalBtcOutSrc.h index aad86570b59c..7150d54d49ab 100644 --- a/drivers/staging/rtl8723bs/hal/HalBtcOutSrc.h +++ b/drivers/staging/rtl8723bs/hal/HalBtcOutSrc.h @@ -532,7 +532,6 @@ typedef struct _BTC_COEXIST { extern BTC_COEXIST GLBtCoexist; -u8 EXhalbtcoutsrc_InitlizeVariables(void *Adapter); void EXhalbtcoutsrc_PowerOnSetting(PBTC_COEXIST pBtCoexist); void EXhalbtcoutsrc_InitHwConfig(PBTC_COEXIST pBtCoexist, u8 bWifiOnly); void EXhalbtcoutsrc_InitCoexDm(PBTC_COEXIST pBtCoexist); diff --git a/drivers/staging/rtl8723bs/hal/hal_btcoex.c b/drivers/staging/rtl8723bs/hal/hal_btcoex.c index 5257287b4f4d..6e4a1fcb8790 100644 --- a/drivers/staging/rtl8723bs/hal/hal_btcoex.c +++ b/drivers/staging/rtl8723bs/hal/hal_btcoex.c @@ -389,7 +389,6 @@ static u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) u8 *pu8; s32 *pS4Tmp; u32 *pU4Tmp; - u8 *pU1Tmp; u8 ret; @@ -403,7 +402,6 @@ static u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) pu8 = pOutBuf; pS4Tmp = pOutBuf; pU4Tmp = pOutBuf; - pU1Tmp = pOutBuf; ret = true; switch (getType) { @@ -484,10 +482,8 @@ static u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) *pU4Tmp = BTC_WIFI_BW_LEGACY; else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_20) *pU4Tmp = BTC_WIFI_BW_HT20; - else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) - *pU4Tmp = BTC_WIFI_BW_HT40; else - *pU4Tmp = BTC_WIFI_BW_HT40; /* todo */ + *pU4Tmp = BTC_WIFI_BW_HT40; break; case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION: @@ -516,32 +512,32 @@ static u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) break; case BTC_GET_U1_WIFI_DOT11_CHNL: - *pU1Tmp = padapter->mlmeextpriv.cur_channel; + *pu8 = padapter->mlmeextpriv.cur_channel; break; case BTC_GET_U1_WIFI_CENTRAL_CHNL: - *pU1Tmp = pHalData->CurrentChannel; + *pu8 = pHalData->CurrentChannel; break; case BTC_GET_U1_WIFI_HS_CHNL: - *pU1Tmp = 0; + *pu8 = 0; ret = false; break; case BTC_GET_U1_MAC_PHY_MODE: - *pU1Tmp = BTC_SMSP; + *pu8 = BTC_SMSP; /* *pU1Tmp = BTC_DMSP; */ /* *pU1Tmp = BTC_DMDP; */ /* *pU1Tmp = BTC_MP_UNKNOWN; */ break; case BTC_GET_U1_AP_NUM: - *pU1Tmp = halbtcoutsrc_GetWifiScanAPNum(padapter); + *pu8 = halbtcoutsrc_GetWifiScanAPNum(padapter); break; /* 1Ant =========== */ case BTC_GET_U1_LPS_MODE: - *pU1Tmp = padapter->dvobj->pwrctl_priv.pwr_mode; + *pu8 = padapter->dvobj->pwrctl_priv.pwr_mode; break; default: @@ -959,9 +955,13 @@ static u8 EXhalbtcoutsrc_BindBtCoexWithAdapter(void *padapter) return true; } -u8 EXhalbtcoutsrc_InitlizeVariables(void *padapter) +void hal_btcoex_Initialize(void *padapter) { - PBTC_COEXIST pBtCoexist = &GLBtCoexist; + PBTC_COEXIST pBtCoexist; + + memset(&GLBtCoexist, 0, sizeof(GLBtCoexist)); + + pBtCoexist = &GLBtCoexist; /* pBtCoexist->statistics.cntBind++; */ @@ -1001,8 +1001,6 @@ u8 EXhalbtcoutsrc_InitlizeVariables(void *padapter) GLBtcWiFiInScanState = false; GLBtcWiFiInIQKState = false; - - return true; } void EXhalbtcoutsrc_PowerOnSetting(PBTC_COEXIST pBtCoexist) @@ -1337,7 +1335,7 @@ void hal_btcoex_SetBTCoexist(struct adapter *padapter, u8 bBtExist) *true Enable BT co-exist mechanism *false Disable BT co-exist mechanism */ -u8 hal_btcoex_IsBtExist(struct adapter *padapter) +bool hal_btcoex_IsBtExist(struct adapter *padapter) { struct hal_com_data *pHalData; @@ -1384,12 +1382,6 @@ void hal_btcoex_SetSingleAntPath(struct adapter *padapter, u8 singleAntPath) EXhalbtcoutsrc_SetSingleAntPath(singleAntPath); } -u8 hal_btcoex_Initialize(struct adapter *padapter) -{ - memset(&GLBtCoexist, 0, sizeof(GLBtCoexist)); - return EXhalbtcoutsrc_InitlizeVariables((void *)padapter); -} - void hal_btcoex_PowerOnSetting(struct adapter *padapter) { EXhalbtcoutsrc_PowerOnSetting(&GLBtCoexist); @@ -1477,9 +1469,9 @@ void hal_btcoex_SetManualControl(struct adapter *padapter, u8 bmanual) GLBtCoexist.bManualControl = bmanual; } -u8 hal_btcoex_IsBtControlLps(struct adapter *padapter) +bool hal_btcoex_IsBtControlLps(struct adapter *padapter) { - if (hal_btcoex_IsBtExist(padapter) == false) + if (!hal_btcoex_IsBtExist(padapter)) return false; if (GLBtCoexist.btInfo.bBtDisabled) @@ -1491,9 +1483,9 @@ u8 hal_btcoex_IsBtControlLps(struct adapter *padapter) return false; } -u8 hal_btcoex_IsLpsOn(struct adapter *padapter) +bool hal_btcoex_IsLpsOn(struct adapter *padapter) { - if (hal_btcoex_IsBtExist(padapter) == false) + if (!hal_btcoex_IsBtExist(padapter)) return false; if (GLBtCoexist.btInfo.bBtDisabled) diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c index 638b12ae6ee9..eddd56abbb2d 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com.c +++ b/drivers/staging/rtl8723bs/hal/hal_com.c @@ -152,10 +152,7 @@ bool HAL_IsLegalChannel(struct adapter *Adapter, u32 Channel) { bool bLegalChannel = true; - if (Channel > 14) { - bLegalChannel = false; - DBG_871X("Channel > 14 but wireless_mode do not support 5G\n"); - } else if ((Channel <= 14) && (Channel >= 1)) { + if ((Channel <= 14) && (Channel >= 1)) { if (IsSupported24G(Adapter->registrypriv.wireless_mode) == false) { bLegalChannel = false; DBG_871X("(Channel <= 14) && (Channel >= 1) but wireless_mode do not support 2.4G\n"); diff --git a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c index 336764464e7d..6539bee9b5ba 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c @@ -2040,24 +2040,6 @@ void PHY_SetTxPowerLimit( } } -u8 PHY_GetTxPowerIndex( - struct adapter *padapter, - u8 RFPath, - u8 Rate, - enum CHANNEL_WIDTH BandWidth, - u8 Channel -) -{ - return PHY_GetTxPowerIndex_8723B(padapter, RFPath, Rate, BandWidth, Channel); -} - -void PHY_SetTxPowerIndex( - struct adapter *padapter, u32 PowerIndex, u8 RFPath, u8 Rate -) -{ - PHY_SetTxPowerIndex_8723B(padapter, PowerIndex, RFPath, Rate); -} - void Hal_ChannelPlanToRegulation(struct adapter *Adapter, u16 ChannelPlan) { struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); diff --git a/drivers/staging/rtl8723bs/hal/hal_intf.c b/drivers/staging/rtl8723bs/hal/hal_intf.c index acb25978a46c..7d8f21f32fb9 100644 --- a/drivers/staging/rtl8723bs/hal/hal_intf.c +++ b/drivers/staging/rtl8723bs/hal/hal_intf.c @@ -369,7 +369,7 @@ void rtw_hal_dm_watchdog_in_lps(struct adapter *padapter) } } -void rtw_hal_bcn_related_reg_setting(struct adapter *padapter) +void beacon_timing_control(struct adapter *padapter) { if (padapter->HalFunc.SetBeaconRelatedRegistersHandler) padapter->HalFunc.SetBeaconRelatedRegistersHandler(padapter); diff --git a/drivers/staging/rtl8723bs/hal/hal_phy.c b/drivers/staging/rtl8723bs/hal/hal_phy.c deleted file mode 100644 index 24a9d8f783f0..000000000000 --- a/drivers/staging/rtl8723bs/hal/hal_phy.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#define _HAL_PHY_C_ - -#include <drv_types.h> - -/* */ -/* ==> RF shadow Operation API Code Section!!! */ -/* */ -/*----------------------------------------------------------------------------- - * Function: PHY_RFShadowRead - * PHY_RFShadowWrite - * PHY_RFShadowCompare - * PHY_RFShadowRecorver - * PHY_RFShadowCompareAll - * PHY_RFShadowRecorverAll - * PHY_RFShadowCompareFlagSet - * PHY_RFShadowRecorverFlagSet - * - * Overview: When we set RF register, we must write shadow at first. - * When we are running, we must compare shadow abd locate error addr. - * Decide to recorver or not. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 11/20/2008 MHC Create Version 0. - * - *---------------------------------------------------------------------------*/ -u32 PHY_RFShadowRead(IN PADAPTER Adapter, IN u8 eRFPath, IN u32 Offset) -{ - return RF_Shadow[eRFPath][Offset].Value; - -} /* PHY_RFShadowRead */ - - -void PHY_RFShadowWrite( - IN PADAPTER Adapter, IN u8 eRFPath, IN u32 Offset, IN u32 Data -) -{ - RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask); - RF_Shadow[eRFPath][Offset].Driver_Write = true; - -} /* PHY_RFShadowWrite */ - - -bool PHY_RFShadowCompare(IN PADAPTER Adapter, IN u8 eRFPath, IN u32 Offset) -{ - u32 reg; - /* Check if we need to check the register */ - if (RF_Shadow[eRFPath][Offset].Compare == true) { - reg = rtw_hal_read_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask); - /* Compare shadow and real rf register for 20bits!! */ - if (RF_Shadow[eRFPath][Offset].Value != reg) { - /* Locate error position. */ - RF_Shadow[eRFPath][Offset].ErrorOrNot = true; - /* RT_TRACE(COMP_INIT, DBG_LOUD, */ - /* PHY_RFShadowCompare RF-%d Addr%02lx Err = %05lx\n", */ - /* eRFPath, Offset, reg)); */ - } - return RF_Shadow[eRFPath][Offset].ErrorOrNot; - } - return false; -} /* PHY_RFShadowCompare */ - - -void PHY_RFShadowRecorver(IN PADAPTER Adapter, IN u8 eRFPath, IN u32 Offset) -{ - /* Check if the address is error */ - if (RF_Shadow[eRFPath][Offset].ErrorOrNot == true) { - /* Check if we need to recorver the register. */ - if (RF_Shadow[eRFPath][Offset].Recorver == true) { - rtw_hal_write_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask, - RF_Shadow[eRFPath][Offset].Value); - /* RT_TRACE(COMP_INIT, DBG_LOUD, */ - /* PHY_RFShadowRecorver RF-%d Addr%02lx=%05lx", */ - /* eRFPath, Offset, RF_Shadow[eRFPath][Offset].Value)); */ - } - } - -} /* PHY_RFShadowRecorver */ - - -void PHY_RFShadowCompareAll(IN PADAPTER Adapter) -{ - u8 eRFPath = 0; - u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter); - - for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) { - for (Offset = 0; Offset < maxReg; Offset++) { - PHY_RFShadowCompare(Adapter, eRFPath, Offset); - } - } - -} /* PHY_RFShadowCompareAll */ - - -void PHY_RFShadowRecorverAll(IN PADAPTER Adapter) -{ - u8 eRFPath = 0; - u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter); - - for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) { - for (Offset = 0; Offset < maxReg; Offset++) { - PHY_RFShadowRecorver(Adapter, eRFPath, Offset); - } - } - -} /* PHY_RFShadowRecorverAll */ - - -void -PHY_RFShadowCompareFlagSet( - IN PADAPTER Adapter, IN u8 eRFPath, IN u32 Offset, IN u8 Type -) -{ - /* Set True or False!!! */ - RF_Shadow[eRFPath][Offset].Compare = Type; - -} /* PHY_RFShadowCompareFlagSet */ - - -void PHY_RFShadowRecorverFlagSet( - IN PADAPTER Adapter, IN u8 eRFPath, IN u32 Offset, IN u8 Type -) -{ - /* Set True or False!!! */ - RF_Shadow[eRFPath][Offset].Recorver = Type; - -} /* PHY_RFShadowRecorverFlagSet */ - - -void PHY_RFShadowCompareFlagSetAll(IN PADAPTER Adapter) -{ - u8 eRFPath = 0; - u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter); - - for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) { - for (Offset = 0; Offset < maxReg; Offset++) { - /* 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! */ - if (Offset != 0x26 && Offset != 0x27) - PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, false); - else - PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, true); - } - } - -} /* PHY_RFShadowCompareFlagSetAll */ diff --git a/drivers/staging/rtl8723bs/hal/odm.c b/drivers/staging/rtl8723bs/hal/odm.c index e3f4307f3d20..aa6631ee4ea7 100644 --- a/drivers/staging/rtl8723bs/hal/odm.c +++ b/drivers/staging/rtl8723bs/hal/odm.c @@ -339,13 +339,9 @@ void ODM_TXPowerTrackingCheck(PDM_ODM_T pDM_Odm); void odm_RateAdaptiveMaskInit(PDM_ODM_T pDM_Odm); -void odm_TXPowerTrackingThermalMeterInit(PDM_ODM_T pDM_Odm); - void odm_TXPowerTrackingInit(PDM_ODM_T pDM_Odm); -void odm_TXPowerTrackingCheckCE(PDM_ODM_T pDM_Odm); - /* Remove Edca by Yu Chen */ @@ -1259,13 +1255,11 @@ void odm_RSSIMonitorCheckCE(PDM_ODM_T pDM_Odm) int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff; u8 sta_cnt = 0; u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */ - bool FirstConnect = false; pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; if (pDM_Odm->bLinked != true) return; - FirstConnect = (pDM_Odm->bLinked) && (pRA_Table->firstconnect == false); pRA_Table->firstconnect = pDM_Odm->bLinked; /* if (check_fwstate(&Adapter->mlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true) */ @@ -1324,11 +1318,6 @@ void odm_RSSIMonitorCheckCE(PDM_ODM_T pDM_Odm) /* 3 Tx Power Tracking */ /* 3 ============================================================ */ -void odm_TXPowerTrackingInit(PDM_ODM_T pDM_Odm) -{ - odm_TXPowerTrackingThermalMeterInit(pDM_Odm); -} - static u8 getSwingIndex(PDM_ODM_T pDM_Odm) { struct adapter *Adapter = pDM_Odm->Adapter; @@ -1353,7 +1342,7 @@ static u8 getSwingIndex(PDM_ODM_T pDM_Odm) return i; } -void odm_TXPowerTrackingThermalMeterInit(PDM_ODM_T pDM_Odm) +void odm_TXPowerTrackingInit(PDM_ODM_T pDM_Odm) { u8 defaultSwingIndex = getSwingIndex(pDM_Odm); u8 p = 0; @@ -1397,14 +1386,8 @@ void odm_TXPowerTrackingThermalMeterInit(PDM_ODM_T pDM_Odm) } - void ODM_TXPowerTrackingCheck(PDM_ODM_T pDM_Odm) { - odm_TXPowerTrackingCheckCE(pDM_Odm); -} - -void odm_TXPowerTrackingCheckCE(PDM_ODM_T pDM_Odm) -{ struct adapter *Adapter = pDM_Odm->Adapter; if (!(pDM_Odm->SupportAbility & ODM_RF_TX_PWR_TRACK)) diff --git a/drivers/staging/rtl8723bs/hal/odm.h b/drivers/staging/rtl8723bs/hal/odm.h index 6ba77bb70889..fba3b9e1491b 100644 --- a/drivers/staging/rtl8723bs/hal/odm.h +++ b/drivers/staging/rtl8723bs/hal/odm.h @@ -1365,10 +1365,6 @@ extern u32 TxScalingTable_Jaguar[TXSCALE_TABLE_SIZE]; #define SWAW_STEP_PEAK 0 #define SWAW_STEP_DETERMINE 1 -/* Remove DIG by yuchen */ - -void ODM_SetAntenna(PDM_ODM_T pDM_Odm, u8 Antenna); - /* Remove BB power saving by Yuchen */ #define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck diff --git a/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c b/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c index a73304639226..95edd148ac24 100644 --- a/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c +++ b/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c @@ -11,11 +11,6 @@ static void odm_SetCrystalCap(void *pDM_VOID, u8 CrystalCap) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PCFO_TRACKING pCfoTrack = &pDM_Odm->DM_CfoTrack; - bool bEEPROMCheck; - struct adapter *Adapter = pDM_Odm->Adapter; - struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); - - bEEPROMCheck = pHalData->EEPROMVersion >= 0x01; if (pCfoTrack->CrystalCap == CrystalCap) return; diff --git a/drivers/staging/rtl8723bs/hal/odm_HWConfig.c b/drivers/staging/rtl8723bs/hal/odm_HWConfig.c index 49fa814068b8..71919a3d81ab 100644 --- a/drivers/staging/rtl8723bs/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8723bs/hal/odm_HWConfig.c @@ -89,7 +89,6 @@ static void odm_RxPhyStatus92CSeries_Parsing( u8 RSSI, total_rssi = 0; bool isCCKrate = false; u8 rf_rx_num = 0; - u8 cck_highpwr = 0; u8 LNA_idx, VGA_idx; PPHY_STATUS_RPT_8192CD_T pPhyStaRpt = (PPHY_STATUS_RPT_8192CD_T)pPhyStatus; @@ -107,16 +106,10 @@ static void odm_RxPhyStatus92CSeries_Parsing( /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */ /* */ - /* if (pHalData->eRFPowerState == eRfOn) */ - cck_highpwr = pDM_Odm->bCckHighPower; - /* else */ - /* cck_highpwr = false; */ - cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a ; /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */ /* The RSSI formula should be modified according to the gain table */ - /* In 88E, cck_highpwr is always set to 1 */ LNA_idx = ((cck_agc_rpt & 0xE0)>>5); VGA_idx = (cck_agc_rpt & 0x1F); rx_pwr_all = odm_CCKRSSI_8723B(LNA_idx, VGA_idx); diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c index 080e974914b6..7760fd0eb6c9 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c @@ -1300,7 +1300,7 @@ static void rtl8723b_set_FwScanOffloadInfo_cmd(struct adapter *padapter, PRSVDPA } #endif /* CONFIG_PNO_SUPPORT */ -static void rtl8723b_set_FwWoWlanRelated_cmd(struct adapter *padapter, u8 enable) +void rtl8723b_set_wowlan_cmd(struct adapter *padapter, u8 enable) { struct security_priv *psecpriv = &padapter->securitypriv; struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter); @@ -1346,11 +1346,6 @@ static void rtl8723b_set_FwWoWlanRelated_cmd(struct adapter *padapter, u8 enable DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__); } - -void rtl8723b_set_wowlan_cmd(struct adapter *padapter, u8 enable) -{ - rtl8723b_set_FwWoWlanRelated_cmd(padapter, enable); -} #endif /* CONFIG_WOWLAN */ #ifdef CONFIG_AP_WOWLAN @@ -1398,7 +1393,7 @@ static void rtl8723b_set_Fw_AP_Offload_Cmd(struct adapter *padapter, u8 bFuncEn) H2C_AP_OFFLOAD_LEN, u1H2CAPOffloadCtrlParm); } -static void rtl8723b_set_AP_FwWoWlan_cmd(struct adapter *padapter, u8 enable) +void rtl8723b_set_ap_wowlan_cmd(struct adapter *padapter, u8 enable) { DBG_871X_LEVEL(_drv_always_, "+%s()+: enable =%d\n", __func__, enable); if (enable) { @@ -1411,12 +1406,6 @@ static void rtl8723b_set_AP_FwWoWlan_cmd(struct adapter *padapter, u8 enable) rtl8723b_set_Fw_AP_Offload_Cmd(padapter, enable); msleep(10); DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__); - return ; -} - -void rtl8723b_set_ap_wowlan_cmd(struct adapter *padapter, u8 enable) -{ - rtl8723b_set_AP_FwWoWlan_cmd(padapter, enable); } #endif /* CONFIG_AP_WOWLAN */ diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c index 25c75b977666..6df2b58bdc67 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c @@ -431,14 +431,12 @@ static int phy_BB8723b_Config_ParaFile(struct adapter *Adapter) u8 sz8723BBRegFile[] = RTL8723B_PHY_REG; u8 sz8723AGCTableFile[] = RTL8723B_AGC_TAB; u8 sz8723BBBRegPgFile[] = RTL8723B_PHY_REG_PG; - u8 sz8723BBRegMpFile[] = RTL8723B_PHY_REG_MP; u8 sz8723BRFTxPwrLmtFile[] = RTL8723B_TXPWR_LMT; - u8 *pszBBRegFile = NULL, *pszAGCTableFile = NULL, *pszBBRegPgFile = NULL, *pszBBRegMpFile = NULL, *pszRFTxPwrLmtFile = NULL; + u8 *pszBBRegFile = NULL, *pszAGCTableFile = NULL, *pszBBRegPgFile = NULL, *pszRFTxPwrLmtFile = NULL; pszBBRegFile = sz8723BBRegFile; pszAGCTableFile = sz8723AGCTableFile; pszBBRegPgFile = sz8723BBBRegPgFile; - pszBBRegMpFile = sz8723BBRegMpFile; pszRFTxPwrLmtFile = sz8723BRFTxPwrLmtFile; /* Read Tx Power Limit File */ @@ -585,7 +583,7 @@ int PHY_RFConfig8723B(struct adapter *Adapter) * <20120830, Kordan> **************************************************************************************************************/ -void PHY_SetTxPowerIndex_8723B( +void PHY_SetTxPowerIndex( struct adapter *Adapter, u32 PowerIndex, u8 RFPath, @@ -668,7 +666,7 @@ void PHY_SetTxPowerIndex_8723B( } } -u8 PHY_GetTxPowerIndex_8723B( +u8 PHY_GetTxPowerIndex( struct adapter *padapter, u8 RFPath, u8 Rate, diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c index e23b39ab16c5..0f3301091258 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c @@ -486,7 +486,6 @@ initbuferror: } if (precvpriv->pallocated_recv_buf) { - n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; kfree(precvpriv->pallocated_recv_buf); precvpriv->pallocated_recv_buf = NULL; } @@ -503,7 +502,7 @@ exit: */ void rtl8723bs_free_recv_priv(struct adapter *padapter) { - u32 i, n; + u32 i; struct recv_priv *precvpriv; struct recv_buf *precvbuf; @@ -515,9 +514,8 @@ void rtl8723bs_free_recv_priv(struct adapter *padapter) /* 3 2. free all recv buffers */ precvbuf = (struct recv_buf *)precvpriv->precv_buf; if (precvbuf) { - n = NR_RECVBUFF; precvpriv->free_recv_buf_queue_cnt = 0; - for (i = 0; i < n ; i++) { + for (i = 0; i < NR_RECVBUFF; i++) { list_del_init(&precvbuf->list); rtw_os_recvbuf_resource_free(padapter, precvbuf); precvbuf++; @@ -526,7 +524,6 @@ void rtl8723bs_free_recv_priv(struct adapter *padapter) } if (precvpriv->pallocated_recv_buf) { - n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; kfree(precvpriv->pallocated_recv_buf); precvpriv->pallocated_recv_buf = NULL; } diff --git a/drivers/staging/rtl8723bs/include/autoconf.h b/drivers/staging/rtl8723bs/include/autoconf.h index 196aca3aed7b..8f4c1e734473 100644 --- a/drivers/staging/rtl8723bs/include/autoconf.h +++ b/drivers/staging/rtl8723bs/include/autoconf.h @@ -57,9 +57,5 @@ #define DBG 0 /* for ODM & BTCOEX debug */ #endif /* !DEBUG */ -#ifdef CONFIG_PROC_FS -#define PROC_DEBUG -#endif - /* define DBG_XMIT_BUF */ /* define DBG_XMIT_BUF_EXT */ diff --git a/drivers/staging/rtl8723bs/include/drv_types.h b/drivers/staging/rtl8723bs/include/drv_types.h index 96346ce064aa..8d7fce1e39b7 100644 --- a/drivers/staging/rtl8723bs/include/drv_types.h +++ b/drivers/staging/rtl8723bs/include/drv_types.h @@ -478,7 +478,7 @@ struct sdio_data intf_data; #define dvobj_to_pwrctl(dvobj) (&(dvobj->pwrctl_priv)) #define pwrctl_to_dvobj(pwrctl) container_of(pwrctl, struct dvobj_priv, pwrctl_priv) -__inline static struct device *dvobj_to_dev(struct dvobj_priv *dvobj) +static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj) { /* todo: get interface type from dvobj and the return the dev accordingly */ #ifdef RTW_DVOBJ_CHIP_HW_TYPE @@ -576,8 +576,6 @@ struct adapter { int bup; struct net_device_stats stats; struct iw_statistics iwstats; - struct proc_dir_entry *dir_dev;/* for proc directory */ - struct proc_dir_entry *dir_odm; struct wireless_dev *rtw_wdev; struct rtw_wdev_priv wdev_data; @@ -636,14 +634,14 @@ struct adapter { /* define RTW_DISABLE_FUNC(padapter, func) (atomic_add(&adapter_to_dvobj(padapter)->disable_func, (func))) */ /* define RTW_ENABLE_FUNC(padapter, func) (atomic_sub(&adapter_to_dvobj(padapter)->disable_func, (func))) */ -__inline static void RTW_DISABLE_FUNC(struct adapter *padapter, int func_bit) +static inline void RTW_DISABLE_FUNC(struct adapter *padapter, int func_bit) { int df = atomic_read(&adapter_to_dvobj(padapter)->disable_func); df |= func_bit; atomic_set(&adapter_to_dvobj(padapter)->disable_func, df); } -__inline static void RTW_ENABLE_FUNC(struct adapter *padapter, int func_bit) +static inline void RTW_ENABLE_FUNC(struct adapter *padapter, int func_bit) { int df = atomic_read(&adapter_to_dvobj(padapter)->disable_func); df &= ~(func_bit); diff --git a/drivers/staging/rtl8723bs/include/hal_btcoex.h b/drivers/staging/rtl8723bs/include/hal_btcoex.h index 6f7514be998f..eb03813fdcb9 100644 --- a/drivers/staging/rtl8723bs/include/hal_btcoex.h +++ b/drivers/staging/rtl8723bs/include/hal_btcoex.h @@ -22,13 +22,13 @@ typedef struct _BT_COEXIST void DBG_BT_INFO(u8 *dbgmsg); void hal_btcoex_SetBTCoexist(struct adapter *padapter, u8 bBtExist); -u8 hal_btcoex_IsBtExist(struct adapter *padapter); +bool hal_btcoex_IsBtExist(struct adapter *padapter); bool hal_btcoex_IsBtDisabled(struct adapter *); void hal_btcoex_SetChipType(struct adapter *padapter, u8 chipType); void hal_btcoex_SetPgAntNum(struct adapter *padapter, u8 antNum); void hal_btcoex_SetSingleAntPath(struct adapter *padapter, u8 singleAntPath); -u8 hal_btcoex_Initialize(struct adapter *padapter); +void hal_btcoex_Initialize(void *padapter); void hal_btcoex_PowerOnSetting(struct adapter *padapter); void hal_btcoex_InitHwConfig(struct adapter *padapter, u8 bWifiOnly); @@ -47,8 +47,8 @@ void hal_btcoex_Handler(struct adapter *padapter); s32 hal_btcoex_IsBTCoexCtrlAMPDUSize(struct adapter *padapter); void hal_btcoex_SetManualControl(struct adapter *padapter, u8 bmanual); -u8 hal_btcoex_IsBtControlLps(struct adapter *); -u8 hal_btcoex_IsLpsOn(struct adapter *); +bool hal_btcoex_IsBtControlLps(struct adapter *padapter); +bool hal_btcoex_IsLpsOn(struct adapter *padapter); u8 hal_btcoex_RpwmVal(struct adapter *); u8 hal_btcoex_LpsVal(struct adapter *); u32 hal_btcoex_GetRaMask(struct adapter *); diff --git a/drivers/staging/rtl8723bs/include/hal_com_phycfg.h b/drivers/staging/rtl8723bs/include/hal_com_phycfg.h index f841546584a7..9167f1e7827f 100644 --- a/drivers/staging/rtl8723bs/include/hal_com_phycfg.h +++ b/drivers/staging/rtl8723bs/include/hal_com_phycfg.h @@ -213,23 +213,6 @@ PHY_GetTxPowerTrackingOffset( u8 RFPath ); -u8 -PHY_GetTxPowerIndex( -struct adapter * padapter, -u8 RFPath, -u8 Rate, -enum CHANNEL_WIDTH BandWidth, -u8 Channel - ); - -void -PHY_SetTxPowerIndex( -struct adapter * padapter, -u32 PowerIndex, -u8 RFPath, -u8 Rate - ); - void Hal_ChannelPlanToRegulation( struct adapter * Adapter, diff --git a/drivers/staging/rtl8723bs/include/hal_intf.h b/drivers/staging/rtl8723bs/include/hal_intf.h index 3a0c3d079d50..24926ebaf950 100644 --- a/drivers/staging/rtl8723bs/include/hal_intf.h +++ b/drivers/staging/rtl8723bs/include/hal_intf.h @@ -362,7 +362,7 @@ void rtw_hal_add_ra_tid(struct adapter *padapter, u32 bitmap, u8 *arg, u8 rssi_l void rtw_hal_start_thread(struct adapter *padapter); void rtw_hal_stop_thread(struct adapter *padapter); -void rtw_hal_bcn_related_reg_setting(struct adapter *padapter); +void beacon_timing_control(struct adapter *padapter); u32 rtw_hal_read_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask); void rtw_hal_write_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data); diff --git a/drivers/staging/rtl8723bs/include/hal_phy_cfg.h b/drivers/staging/rtl8723bs/include/hal_phy_cfg.h index 640427f407e3..b40868b2e76f 100644 --- a/drivers/staging/rtl8723bs/include/hal_phy_cfg.h +++ b/drivers/staging/rtl8723bs/include/hal_phy_cfg.h @@ -65,7 +65,7 @@ int PHY_RFConfig8723B(struct adapter *Adapter ); s32 PHY_MACConfig8723B(struct adapter *padapter); void -PHY_SetTxPowerIndex_8723B( +PHY_SetTxPowerIndex( struct adapter * Adapter, u32 PowerIndex, u8 RFPath, @@ -73,7 +73,7 @@ u8 Rate ); u8 -PHY_GetTxPowerIndex_8723B( +PHY_GetTxPowerIndex( struct adapter * padapter, u8 RFPath, u8 Rate, diff --git a/drivers/staging/rtl8723bs/include/osdep_intf.h b/drivers/staging/rtl8723bs/include/osdep_intf.h index 40313d17a242..fa16139fcce6 100644 --- a/drivers/staging/rtl8723bs/include/osdep_intf.h +++ b/drivers/staging/rtl8723bs/include/osdep_intf.h @@ -64,8 +64,6 @@ u16 rtw_recv_select_queue(struct sk_buff *skb); int rtw_ndev_notifier_register(void); void rtw_ndev_notifier_unregister(void); -#include "../os_dep/rtw_proc.h" - void rtw_ips_dev_unload(struct adapter *padapter); int rtw_ips_pwr_up(struct adapter *padapter); diff --git a/drivers/staging/rtl8723bs/include/osdep_service.h b/drivers/staging/rtl8723bs/include/osdep_service.h index d2616af95ffa..81a9c19ecc6a 100644 --- a/drivers/staging/rtl8723bs/include/osdep_service.h +++ b/drivers/staging/rtl8723bs/include/osdep_service.h @@ -110,12 +110,12 @@ int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb); extern void _rtw_init_queue(struct __queue *pqueue); -static __inline void thread_enter(char *name) +static inline void thread_enter(char *name) { allow_signal(SIGTERM); } -__inline static void flush_signals_thread(void) +static inline void flush_signals_thread(void) { if (signal_pending (current)) { @@ -125,7 +125,7 @@ __inline static void flush_signals_thread(void) #define rtw_warn_on(condition) WARN_ON(condition) -__inline static int rtw_bug_check(void *parg1, void *parg2, void *parg3, void *parg4) +static inline int rtw_bug_check(void *parg1, void *parg2, void *parg3, void *parg4) { int ret = true; @@ -136,7 +136,7 @@ __inline static int rtw_bug_check(void *parg1, void *parg2, void *parg3, void *p #define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) #define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2) -__inline static u32 _RND4(u32 sz) +static inline u32 _RND4(u32 sz) { u32 val; @@ -147,7 +147,7 @@ __inline static u32 _RND4(u32 sz) } -__inline static u32 _RND8(u32 sz) +static inline u32 _RND8(u32 sz) { u32 val; diff --git a/drivers/staging/rtl8723bs/include/osdep_service_linux.h b/drivers/staging/rtl8723bs/include/osdep_service_linux.h index 2f1b51e614fb..c582ede1ac12 100644 --- a/drivers/staging/rtl8723bs/include/osdep_service_linux.h +++ b/drivers/staging/rtl8723bs/include/osdep_service_linux.h @@ -64,12 +64,12 @@ typedef struct work_struct _workitem; -__inline static struct list_head *get_next(struct list_head *list) +static inline struct list_head *get_next(struct list_head *list) { return list->next; } -__inline static struct list_head *get_list_head(struct __queue *queue) +static inline struct list_head *get_list_head(struct __queue *queue) { return (&(queue->queue)); } @@ -78,28 +78,28 @@ __inline static struct list_head *get_list_head(struct __queue *queue) #define LIST_CONTAINOR(ptr, type, member) \ container_of(ptr, type, member) -__inline static void _set_timer(_timer *ptimer, u32 delay_time) +static inline void _set_timer(_timer *ptimer, u32 delay_time) { mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); } -__inline static void _cancel_timer(_timer *ptimer, u8 *bcancelled) +static inline void _cancel_timer(_timer *ptimer, u8 *bcancelled) { del_timer_sync(ptimer); *bcancelled = true;/* true == 1; false == 0 */ } -__inline static void _init_workitem(_workitem *pwork, void *pfunc, void *cntx) +static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx) { INIT_WORK(pwork, pfunc); } -__inline static void _set_workitem(_workitem *pwork) +static inline void _set_workitem(_workitem *pwork) { schedule_work(pwork); } -__inline static void _cancel_workitem_sync(_workitem *pwork) +static inline void _cancel_workitem_sync(_workitem *pwork) { cancel_work_sync(pwork); } diff --git a/drivers/staging/rtl8723bs/include/rtw_debug.h b/drivers/staging/rtl8723bs/include/rtw_debug.h index 216d9492575e..22fc5d730d7b 100644 --- a/drivers/staging/rtl8723bs/include/rtw_debug.h +++ b/drivers/staging/rtl8723bs/include/rtw_debug.h @@ -267,81 +267,4 @@ void mac_reg_dump(void *sel, struct adapter *adapter); void bb_reg_dump(void *sel, struct adapter *adapter); void rf_reg_dump(void *sel, struct adapter *adapter); -#ifdef PROC_DEBUG -ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -int proc_get_read_reg(struct seq_file *m, void *v); -ssize_t proc_set_read_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_fwstate(struct seq_file *m, void *v); -int proc_get_sec_info(struct seq_file *m, void *v); -int proc_get_mlmext_state(struct seq_file *m, void *v); - -int proc_get_roam_flags(struct seq_file *m, void *v); -ssize_t proc_set_roam_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -int proc_get_roam_param(struct seq_file *m, void *v); -ssize_t proc_set_roam_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_qos_option(struct seq_file *m, void *v); -int proc_get_ht_option(struct seq_file *m, void *v); -int proc_get_rf_info(struct seq_file *m, void *v); -int proc_get_survey_info(struct seq_file *m, void *v); -int proc_get_ap_info(struct seq_file *m, void *v); -int proc_get_adapter_state(struct seq_file *m, void *v); -int proc_get_trx_info(struct seq_file *m, void *v); -int proc_get_rate_ctl(struct seq_file *m, void *v); -ssize_t proc_set_rate_ctl(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -int proc_get_suspend_resume_info(struct seq_file *m, void *v); - -ssize_t proc_set_fwdl_test_case(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -ssize_t proc_set_wait_hiq_empty(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_all_sta_info(struct seq_file *m, void *v); - -int proc_get_rx_signal(struct seq_file *m, void *v); -ssize_t proc_set_rx_signal(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -int proc_get_hw_status(struct seq_file *m, void *v); - -int proc_get_ht_enable(struct seq_file *m, void *v); -ssize_t proc_set_ht_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_bw_mode(struct seq_file *m, void *v); -ssize_t proc_set_bw_mode(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_ampdu_enable(struct seq_file *m, void *v); -ssize_t proc_set_ampdu_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_rx_ampdu(struct seq_file *m, void *v); -ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_rx_stbc(struct seq_file *m, void *v); -ssize_t proc_set_rx_stbc(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_en_fwps(struct seq_file *m, void *v); -ssize_t proc_set_en_fwps(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -/* int proc_get_two_path_rssi(struct seq_file *m, void *v); */ -int proc_get_rssi_disp(struct seq_file *m, void *v); -ssize_t proc_set_rssi_disp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_btcoex_dbg(struct seq_file *m, void *v); -ssize_t proc_set_btcoex_dbg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -int proc_get_btcoex_info(struct seq_file *m, void *v); - -int proc_get_odm_dbg_comp(struct seq_file *m, void *v); -ssize_t proc_set_odm_dbg_comp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -int proc_get_odm_dbg_level(struct seq_file *m, void *v); -ssize_t proc_set_odm_dbg_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -int proc_get_odm_adaptivity(struct seq_file *m, void *v); -ssize_t proc_set_odm_adaptivity(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - -#ifdef CONFIG_DBG_COUNTER -int proc_get_rx_logs(struct seq_file *m, void *v); -int proc_get_tx_logs(struct seq_file *m, void *v); -int proc_get_int_logs(struct seq_file *m, void *v); -#endif - -#endif /* PROC_DEBUG */ - #endif /* __RTW_DEBUG_H__ */ diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme.h b/drivers/staging/rtl8723bs/include/rtw_mlme.h index d3c07d1c36e9..362737b83c3a 100644 --- a/drivers/staging/rtl8723bs/include/rtw_mlme.h +++ b/drivers/staging/rtl8723bs/include/rtw_mlme.h @@ -81,15 +81,13 @@ enum dot11AuthAlgrthmNum { }; /* Scan type including active and passive scan. */ -typedef enum _RT_SCAN_TYPE -{ +typedef enum _RT_SCAN_TYPE { SCAN_PASSIVE, SCAN_ACTIVE, SCAN_MIX, }RT_SCAN_TYPE, *PRT_SCAN_TYPE; -enum _BAND -{ +enum _BAND { GHZ24_50 = 0, GHZ_50, GHZ_24, @@ -498,13 +496,13 @@ extern sint rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv); extern sint rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, sint keyid, u8 set_tx, bool enqueue); extern sint rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv); -__inline static u8 *get_bssid(struct mlme_priv *pmlmepriv) +static inline u8 *get_bssid(struct mlme_priv *pmlmepriv) { /* if sta_mode:pmlmepriv->cur_network.network.MacAddress => bssid */ /* if adhoc_mode:pmlmepriv->cur_network.network.MacAddress => ibss mac address */ return pmlmepriv->cur_network.network.MacAddress; } -__inline static sint check_fwstate(struct mlme_priv *pmlmepriv, sint state) +static inline sint check_fwstate(struct mlme_priv *pmlmepriv, sint state) { if (pmlmepriv->fw_state & state) return true; @@ -512,7 +510,7 @@ __inline static sint check_fwstate(struct mlme_priv *pmlmepriv, sint state) return false; } -__inline static sint get_fwstate(struct mlme_priv *pmlmepriv) +static inline sint get_fwstate(struct mlme_priv *pmlmepriv) { return pmlmepriv->fw_state; } @@ -524,7 +522,7 @@ __inline static sint get_fwstate(struct mlme_priv *pmlmepriv) * ### NOTE:#### (!!!!) * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock */ -__inline static void set_fwstate(struct mlme_priv *pmlmepriv, sint state) +static inline void set_fwstate(struct mlme_priv *pmlmepriv, sint state) { pmlmepriv->fw_state |= state; /* FOR HW integration */ @@ -533,7 +531,7 @@ __inline static void set_fwstate(struct mlme_priv *pmlmepriv, sint state) } } -__inline static void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) +static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) { pmlmepriv->fw_state &= ~state; /* FOR HW integration */ @@ -546,7 +544,7 @@ __inline static void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) * No Limit on the calling context, * therefore set it to be the critical section... */ -__inline static void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) +static inline void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) { spin_lock_bh(&pmlmepriv->lock); if (check_fwstate(pmlmepriv, state) == true) @@ -554,7 +552,7 @@ __inline static void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) spin_unlock_bh(&pmlmepriv->lock); } -__inline static void set_scanned_network_val(struct mlme_priv *pmlmepriv, sint val) +static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv, sint val) { spin_lock_bh(&pmlmepriv->lock); pmlmepriv->num_of_scanned = val; diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h index 733bb9425448..fd3cf955c9f8 100644 --- a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h @@ -535,7 +535,7 @@ struct mlme_ext_priv }; void init_mlme_default_rate_set(struct adapter *padapter); -int init_mlme_ext_priv(struct adapter *padapter); +void init_mlme_ext_priv(struct adapter *padapter); int init_hw_mlme_ext(struct adapter *padapter); void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); extern void init_mlme_ext_timer(struct adapter *padapter); @@ -650,7 +650,6 @@ void report_del_sta_event(struct adapter *padapter, unsigned char* MacAddr, unsi void report_add_sta_event(struct adapter *padapter, unsigned char* MacAddr, int cam_idx); void report_wmm_edca_update(struct adapter *padapter); -void beacon_timing_control(struct adapter *padapter); u8 chk_bmc_sleepq_cmd(struct adapter *padapter); extern u8 set_tx_beacon_cmd(struct adapter *padapter); unsigned int setup_beacon_frame(struct adapter *padapter, unsigned char *beacon_frame); diff --git a/drivers/staging/rtl8723bs/include/rtw_recv.h b/drivers/staging/rtl8723bs/include/rtw_recv.h index 5de946e66302..012d8f54814f 100644 --- a/drivers/staging/rtl8723bs/include/rtw_recv.h +++ b/drivers/staging/rtl8723bs/include/rtw_recv.h @@ -405,7 +405,7 @@ struct recv_buf *rtw_dequeue_recvbuf (struct __queue *queue); void rtw_reordering_ctrl_timeout_handler(struct timer_list *t); -__inline static u8 *get_rxmem(union recv_frame *precvframe) +static inline u8 *get_rxmem(union recv_frame *precvframe) { /* always return rx_head... */ if (precvframe == NULL) @@ -414,7 +414,7 @@ __inline static u8 *get_rxmem(union recv_frame *precvframe) return precvframe->u.hdr.rx_head; } -__inline static u8 *get_recvframe_data(union recv_frame *precvframe) +static inline u8 *get_recvframe_data(union recv_frame *precvframe) { /* alwasy return rx_data */ @@ -425,7 +425,7 @@ __inline static u8 *get_recvframe_data(union recv_frame *precvframe) } -__inline static u8 *recvframe_pull(union recv_frame *precvframe, sint sz) +static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz) { /* rx_data += sz; move rx_data sz bytes hereafter */ @@ -450,7 +450,7 @@ __inline static u8 *recvframe_pull(union recv_frame *precvframe, sint sz) } -__inline static u8 *recvframe_put(union recv_frame *precvframe, sint sz) +static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz) { /* rx_tai += sz; move rx_tail sz bytes hereafter */ @@ -479,7 +479,7 @@ __inline static u8 *recvframe_put(union recv_frame *precvframe, sint sz) -__inline static u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) +static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) { /* rmv data from rx_tail (by yitsen) */ @@ -503,7 +503,7 @@ __inline static u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) } -__inline static union recv_frame *rxmem_to_recvframe(u8 *rxmem) +static inline union recv_frame *rxmem_to_recvframe(u8 *rxmem) { /* due to the design of 2048 bytes alignment of recv_frame, we can reference the union recv_frame */ /* from any given member of recv_frame. */ @@ -513,13 +513,13 @@ __inline static union recv_frame *rxmem_to_recvframe(u8 *rxmem) } -__inline static sint get_recvframe_len(union recv_frame *precvframe) +static inline sint get_recvframe_len(union recv_frame *precvframe) { return precvframe->u.hdr.len; } -__inline static s32 translate_percentage_to_dbm(u32 SignalStrengthIndex) +static inline s32 translate_percentage_to_dbm(u32 SignalStrengthIndex) { s32 SignalPower; /* in dBm. */ diff --git a/drivers/staging/rtl8723bs/include/sta_info.h b/drivers/staging/rtl8723bs/include/sta_info.h index b9df42d0677e..3acce5630f8e 100644 --- a/drivers/staging/rtl8723bs/include/sta_info.h +++ b/drivers/staging/rtl8723bs/include/sta_info.h @@ -348,7 +348,7 @@ struct sta_priv { }; -__inline static u32 wifi_mac_hash(u8 *mac) +static inline u32 wifi_mac_hash(u8 *mac) { u32 x; diff --git a/drivers/staging/rtl8723bs/include/wifi.h b/drivers/staging/rtl8723bs/include/wifi.h index 8c50bbb20f3b..2faf83704ff0 100644 --- a/drivers/staging/rtl8723bs/include/wifi.h +++ b/drivers/staging/rtl8723bs/include/wifi.h @@ -347,7 +347,7 @@ enum WIFI_REG_DOMAIN { (addr[4] == 0xff) && (addr[5] == 0xff)) ? true : false \ ) -__inline static int IS_MCAST(unsigned char *da) +static inline int IS_MCAST(unsigned char *da) { if ((*da) & 0x01) return true; @@ -355,20 +355,20 @@ __inline static int IS_MCAST(unsigned char *da) return false; } -__inline static unsigned char * get_ra(unsigned char *pframe) +static inline unsigned char * get_ra(unsigned char *pframe) { unsigned char *ra; ra = GetAddr1Ptr(pframe); return ra; } -__inline static unsigned char * get_ta(unsigned char *pframe) +static inline unsigned char * get_ta(unsigned char *pframe) { unsigned char *ta; ta = GetAddr2Ptr(pframe); return ta; } -__inline static unsigned char * get_da(unsigned char *pframe) +static inline unsigned char * get_da(unsigned char *pframe) { unsigned char *da; unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); @@ -392,7 +392,7 @@ __inline static unsigned char * get_da(unsigned char *pframe) } -__inline static unsigned char * get_sa(unsigned char *pframe) +static inline unsigned char * get_sa(unsigned char *pframe) { unsigned char *sa; unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); @@ -415,7 +415,7 @@ __inline static unsigned char * get_sa(unsigned char *pframe) return sa; } -__inline static unsigned char * get_hdr_bssid(unsigned char *pframe) +static inline unsigned char * get_hdr_bssid(unsigned char *pframe) { unsigned char *sa = NULL; unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); @@ -439,7 +439,7 @@ __inline static unsigned char * get_hdr_bssid(unsigned char *pframe) } -__inline static int IsFrameTypeCtrl(unsigned char *pframe) +static inline int IsFrameTypeCtrl(unsigned char *pframe) { if (WIFI_CTRL_TYPE == GetFrameType(pframe)) return true; diff --git a/drivers/staging/rtl8723bs/include/wlan_bssdef.h b/drivers/staging/rtl8723bs/include/wlan_bssdef.h index 88890b1c3c4c..723fc5b546ef 100644 --- a/drivers/staging/rtl8723bs/include/wlan_bssdef.h +++ b/drivers/staging/rtl8723bs/include/wlan_bssdef.h @@ -223,7 +223,7 @@ struct wlan_bssid_ex { u8 IEs[MAX_IE_SZ]; /* timestamp, beacon interval, and capability information) */ } __packed; -__inline static uint get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) +static inline uint get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) { return (sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + bss->IELength); } diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 9bc685632651..f819abb756dc 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -19,8 +19,6 @@ #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 /* ms */ #define RTW_MAX_NUM_PMKIDS 4 -#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ - static const u32 rtw_cipher_suites[] = { WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, @@ -2024,8 +2022,6 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); - padapter->mlmepriv.not_indic_disco = true; - old_type = rtw_wdev->iftype; rtw_set_to_roam(padapter, 0); @@ -2047,8 +2043,6 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) } leave_ibss: - padapter->mlmepriv.not_indic_disco = false; - return 0; } @@ -2246,8 +2240,6 @@ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); - padapter->mlmepriv.not_indic_disco = true; - rtw_set_to_roam(padapter, 0); rtw_scan_abort(padapter); @@ -2261,8 +2253,6 @@ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, rtw_free_assoc_resources(padapter, 1); rtw_pwr_wakeup(padapter); - padapter->mlmepriv.not_indic_disco = false; - DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev)); return 0; } diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c index 99e6b1028f71..d1b199e3e5bd 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c @@ -21,13 +21,10 @@ #define RATE_COUNT 4 /* combo scan */ -#define WEXT_CSCAN_AMOUNT 9 -#define WEXT_CSCAN_BUF_LEN 360 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" #define WEXT_CSCAN_HEADER_SIZE 12 #define WEXT_CSCAN_SSID_SECTION 'S' #define WEXT_CSCAN_CHANNEL_SECTION 'C' -#define WEXT_CSCAN_NPROBE_SECTION 'N' #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' #define WEXT_CSCAN_PASV_DWELL_SECTION 'P' #define WEXT_CSCAN_HOME_DWELL_SECTION 'H' @@ -215,8 +212,6 @@ static char *translate_scan(struct adapter *padapter, } else if (ht_cap) { if (mcs_rate&0x8000) { /* MCS15 */ max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); - } else if (mcs_rate&0x0080) { /* MCS7 */ - max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); } else { /* default MCS7 */ /* DBG_871X("wx_get_scan, mcs_rate_bitmap = 0x%x\n", mcs_rate); */ max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); @@ -4912,7 +4907,6 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_ s32 k; const iw_handler *priv; /* Private ioctl */ const struct iw_priv_args *priv_args; /* Private ioctl description */ - u32 num_priv; /* Number of ioctl */ u32 num_priv_args; /* Number of descriptions */ iw_handler handler; int temp; @@ -4948,7 +4942,6 @@ static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_ priv = rtw_private_handler; priv_args = rtw_private_args; - num_priv = ARRAY_SIZE(rtw_private_handler); num_priv_args = ARRAY_SIZE(rtw_private_args); if (num_priv_args == 0) { diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index 544e799d0a03..ec3a75485233 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -239,9 +239,6 @@ static void loadparam(struct adapter *padapter, _nic_hdl pnetdev) registry_par->channel = (u8)rtw_channel; registry_par->wireless_mode = (u8)rtw_wireless_mode; - if (registry_par->channel > 14) - registry_par->channel = 1; - registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense ; registry_par->vcs_type = (u8)rtw_vcs_type; registry_par->rts_thresh = (u16)rtw_rts_thresh; @@ -448,12 +445,6 @@ static int rtw_ndev_notifier_call(struct notifier_block *nb, unsigned long state DBG_871X_LEVEL(_drv_info_, FUNC_NDEV_FMT " state:%lu\n", FUNC_NDEV_ARG(dev), state); - switch (state) { - case NETDEV_CHANGENAME: - rtw_adapter_proc_replace(dev); - break; - } - return NOTIFY_DONE; } @@ -478,7 +469,6 @@ static int rtw_ndev_init(struct net_device *dev) DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter)); strncpy(adapter->old_ifname, dev->name, IFNAMSIZ); - rtw_adapter_proc_init(dev); return 0; } @@ -488,7 +478,6 @@ static void rtw_ndev_uninit(struct net_device *dev) struct adapter *adapter = rtw_netdev_priv(dev); DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter)); - rtw_adapter_proc_deinit(dev); } static const struct net_device_ops rtw_netdev_ops = { @@ -768,11 +757,7 @@ u8 rtw_init_drv_sw(struct adapter *padapter) goto exit; } - if (init_mlme_ext_priv(padapter) == _FAIL) { - RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init mlme_ext_priv\n")); - ret8 = _FAIL; - goto exit; - } + init_mlme_ext_priv(padapter); if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { DBG_871X("Can't _rtw_init_xmit_priv\n"); @@ -1361,13 +1346,12 @@ void rtw_suspend_wow(struct adapter *padapter) #endif /* ifdef CONFIG_WOWLAN */ #ifdef CONFIG_AP_WOWLAN -int rtw_suspend_ap_wow(struct adapter *padapter) +void rtw_suspend_ap_wow(struct adapter *padapter) { u8 ch, bw, offset; struct net_device *pnetdev = padapter->pnetdev; struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct wowlan_ioctl_param poidparam; - int ret = _SUCCESS; DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); @@ -1409,7 +1393,6 @@ int rtw_suspend_ap_wow(struct adapter *padapter) rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, 0, "AP-WOWLAN"); DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); - return ret; } #endif /* ifdef CONFIG_AP_WOWLAN */ diff --git a/drivers/staging/rtl8723bs/os_dep/osdep_service.c b/drivers/staging/rtl8723bs/os_dep/osdep_service.c index 62fdd24ba427..25a80041ce87 100644 --- a/drivers/staging/rtl8723bs/os_dep/osdep_service.c +++ b/drivers/staging/rtl8723bs/os_dep/osdep_service.c @@ -318,13 +318,9 @@ error: void rtw_buf_free(u8 **buf, u32 *buf_len) { - u32 ori_len; - if (!buf || !buf_len) return; - ori_len = *buf_len; - if (*buf) { *buf_len = 0; kfree(*buf); diff --git a/drivers/staging/rtl8723bs/os_dep/rtw_proc.c b/drivers/staging/rtl8723bs/os_dep/rtw_proc.c deleted file mode 100644 index 5f950fda48ea..000000000000 --- a/drivers/staging/rtl8723bs/os_dep/rtw_proc.c +++ /dev/null @@ -1,779 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ - -#include <drv_types.h> -#include <rtw_debug.h> -#include "rtw_proc.h" - -#ifdef PROC_DEBUG - -static struct proc_dir_entry *rtw_proc; - -#define RTW_PROC_NAME "rtl8723bs" - -#define get_proc_net init_net.proc_net - -inline struct proc_dir_entry *rtw_proc_create_dir(const char *name, struct proc_dir_entry *parent, void *data) -{ - struct proc_dir_entry *entry; - - entry = proc_mkdir_data(name, S_IRUGO|S_IXUGO, parent, data); - - return entry; -} - -inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent, - const struct file_operations *fops, void *data) -{ - struct proc_dir_entry *entry; - - entry = proc_create_data(name, S_IFREG|S_IRUGO, parent, fops, data); - - return entry; -} - -static int proc_get_dummy(struct seq_file *m, void *v) -{ - return 0; -} - -static int proc_get_drv_version(struct seq_file *m, void *v) -{ - dump_drv_version(m); - return 0; -} - -static int proc_get_log_level(struct seq_file *m, void *v) -{ - dump_log_level(m); - return 0; -} - -static ssize_t proc_set_log_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - char tmp[32]; - int log_level; - - if (count < 1) - return -EINVAL; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - sscanf(tmp, "%d ", &log_level); - if (log_level >= _drv_always_ && log_level <= _drv_debug_) { - GlobalDebugLevel = log_level; - printk("%d\n", GlobalDebugLevel); - } - } else { - return -EFAULT; - } - - return count; -} - -/* -* rtw_drv_proc: -* init/deinit when register/unregister driver -*/ -static const struct rtw_proc_hdl drv_proc_hdls[] = { - {"ver_info", proc_get_drv_version, NULL}, - {"log_level", proc_get_log_level, proc_set_log_level}, -}; - -static const int drv_proc_hdls_num = sizeof(drv_proc_hdls) / sizeof(struct rtw_proc_hdl); - -static int rtw_drv_proc_open(struct inode *inode, struct file *file) -{ - /* struct net_device *dev = proc_get_parent_data(inode); */ - ssize_t index = (ssize_t)PDE_DATA(inode); - const struct rtw_proc_hdl *hdl = drv_proc_hdls+index; - - return single_open(file, hdl->show, NULL); -} - -static ssize_t rtw_drv_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) -{ - ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); - const struct rtw_proc_hdl *hdl = drv_proc_hdls+index; - ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; - - if (write) - return write(file, buffer, count, pos, NULL); - - return -EROFS; -} - -static const struct file_operations rtw_drv_proc_fops = { - .owner = THIS_MODULE, - .open = rtw_drv_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = rtw_drv_proc_write, -}; - -int rtw_drv_proc_init(void) -{ - int ret = _FAIL; - ssize_t i; - struct proc_dir_entry *entry = NULL; - - if (rtw_proc) { - rtw_warn_on(1); - goto exit; - } - - rtw_proc = rtw_proc_create_dir(RTW_PROC_NAME, get_proc_net, NULL); - - if (!rtw_proc) { - rtw_warn_on(1); - goto exit; - } - - for (i = 0; i < drv_proc_hdls_num; i++) { - entry = rtw_proc_create_entry(drv_proc_hdls[i].name, rtw_proc, &rtw_drv_proc_fops, (void *)i); - if (!entry) { - rtw_warn_on(1); - goto exit; - } - } - - ret = _SUCCESS; - -exit: - return ret; -} - -void rtw_drv_proc_deinit(void) -{ - int i; - - if (!rtw_proc) - return; - - for (i = 0; i < drv_proc_hdls_num; i++) - remove_proc_entry(drv_proc_hdls[i].name, rtw_proc); - - remove_proc_entry(RTW_PROC_NAME, get_proc_net); - rtw_proc = NULL; -} - -static int proc_get_sd_f0_reg_dump(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - sd_f0_reg_dump(m, adapter); - - return 0; -} - -static int proc_get_mac_reg_dump(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - mac_reg_dump(m, adapter); - - return 0; -} - -static int proc_get_bb_reg_dump(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - bb_reg_dump(m, adapter); - - return 0; -} - -static int proc_get_rf_reg_dump(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - rf_reg_dump(m, adapter); - - return 0; -} -static int proc_get_linked_info_dump(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - if (padapter) - DBG_871X_SEL_NL(m, "linked_info_dump :%s\n", (padapter->bLinkInfoDump)?"enable":"disable"); - - return 0; -} - -static ssize_t proc_set_linked_info_dump(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - char tmp[2]; - int mode = 0; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - if (padapter) { - /* padapter->bLinkInfoDump = mode; */ - /* DBG_871X("linked_info_dump =%s\n", (padapter->bLinkInfoDump)?"enable":"disable"); */ - linked_info_dump(padapter, mode); - } - - } - - return count; - -} - -static int proc_get_rx_info(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; - - /* Counts of packets whose seq_num is less than preorder_ctrl->indicate_seq, Ex delay, retransmission, redundant packets and so on */ - DBG_871X_SEL_NL(m,"Counts of Packets Whose Seq_Num Less Than Reorder Control Seq_Num: %llu\n", (unsigned long long)pdbgpriv->dbg_rx_ampdu_drop_count); - /* How many times the Rx Reorder Timer is triggered. */ - DBG_871X_SEL_NL(m,"Rx Reorder Time-out Trigger Counts: %llu\n", (unsigned long long)pdbgpriv->dbg_rx_ampdu_forced_indicate_count); - /* Total counts of packets loss */ - DBG_871X_SEL_NL(m,"Rx Packet Loss Counts: %llu\n", (unsigned long long)pdbgpriv->dbg_rx_ampdu_loss_count); - DBG_871X_SEL_NL(m,"Duplicate Management Frame Drop Count: %llu\n", (unsigned long long)pdbgpriv->dbg_rx_dup_mgt_frame_drop_count); - DBG_871X_SEL_NL(m,"AMPDU BA window shift Count: %llu\n", (unsigned long long)pdbgpriv->dbg_rx_ampdu_window_shift_cnt); - return 0; -} - - -static ssize_t proc_reset_rx_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; - char cmd[32]; - if (buffer && !copy_from_user(cmd, buffer, sizeof(cmd))) { - if ('0' == cmd[0]) { - pdbgpriv->dbg_rx_ampdu_drop_count = 0; - pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0; - pdbgpriv->dbg_rx_ampdu_loss_count = 0; - pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0; - pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0; - } - } - - return count; -} - -static int proc_get_cam(struct seq_file *m, void *v) -{ - return 0; -} - -static ssize_t proc_set_cam(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter; - - char tmp[32]; - char cmd[5]; - u8 id; - - adapter = (struct adapter *)rtw_netdev_priv(dev); - if (!adapter) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - /* c <id>: clear specific cam entry */ - /* wfc <id>: write specific cam entry from cam cache */ - - int num = sscanf(tmp, "%4s %hhu", cmd, &id); - - if (num < 2) - return count; - if (id >= TOTAL_CAM_ENTRY) - return -EINVAL; - - if (strcmp("c", cmd) == 0) { - _clear_cam_entry(adapter, id); - adapter->securitypriv.hw_decrypted = false; /* temporarily set this for TX path to use SW enc */ - } else if (strcmp("wfc", cmd) == 0) { - write_cam_from_cache(adapter, id); - } - } - - return count; -} - -static int proc_get_cam_cache(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); - u8 i; - - DBG_871X_SEL_NL(m, "cam bitmap:0x%016llx\n", dvobj->cam_ctl.bitmap); - - DBG_871X_SEL_NL(m, "%-2s %-6s %-17s %-32s %-3s %-7s" - /* %-2s %-2s %-4s %-5s" */ - "\n" - , "id", "ctrl", "addr", "key", "kid", "type" - /* "MK", "GK", "MFB", "valid" */ - ); - - for (i = 0; i < 32; i++) { - if (dvobj->cam_cache[i].ctrl != 0) - DBG_871X_SEL_NL(m, "%2u 0x%04x "MAC_FMT" "KEY_FMT" %3u %-7s" - /* %2u %2u 0x%02x %5u" */ - "\n", i - , dvobj->cam_cache[i].ctrl - , MAC_ARG(dvobj->cam_cache[i].mac) - , KEY_ARG(dvobj->cam_cache[i].key) - , (dvobj->cam_cache[i].ctrl)&0x03 - , security_type_str(((dvobj->cam_cache[i].ctrl)>>2)&0x07) - /* ((dvobj->cam_cache[i].ctrl)>>5)&0x01 */ - /* ((dvobj->cam_cache[i].ctrl)>>6)&0x01 */ - /* ((dvobj->cam_cache[i].ctrl)>>8)&0x7f */ - /* ((dvobj->cam_cache[i].ctrl)>>15)&0x01 */ - ); - } - - return 0; -} - -/* -* rtw_adapter_proc: -* init/deinit when register/unregister net_device -*/ -static const struct rtw_proc_hdl adapter_proc_hdls[] = { - {"write_reg", proc_get_dummy, proc_set_write_reg}, - {"read_reg", proc_get_read_reg, proc_set_read_reg}, - {"fwstate", proc_get_fwstate, NULL}, - {"sec_info", proc_get_sec_info, NULL}, - {"mlmext_state", proc_get_mlmext_state, NULL}, - {"qos_option", proc_get_qos_option, NULL}, - {"ht_option", proc_get_ht_option, NULL}, - {"rf_info", proc_get_rf_info, NULL}, - {"survey_info", proc_get_survey_info, NULL}, - {"ap_info", proc_get_ap_info, NULL}, - {"adapter_state", proc_get_adapter_state, NULL}, - {"trx_info", proc_get_trx_info, NULL}, - {"rate_ctl", proc_get_rate_ctl, proc_set_rate_ctl}, - {"cam", proc_get_cam, proc_set_cam}, - {"cam_cache", proc_get_cam_cache, NULL}, - {"suspend_info", proc_get_suspend_resume_info, NULL}, - {"rx_info", proc_get_rx_info, proc_reset_rx_info}, - - {"roam_flags", proc_get_roam_flags, proc_set_roam_flags}, - {"roam_param", proc_get_roam_param, proc_set_roam_param}, - {"roam_tgt_addr", proc_get_dummy, proc_set_roam_tgt_addr}, - - {"sd_f0_reg_dump", proc_get_sd_f0_reg_dump, NULL}, - - {"fwdl_test_case", proc_get_dummy, proc_set_fwdl_test_case}, - {"wait_hiq_empty", proc_get_dummy, proc_set_wait_hiq_empty}, - - {"mac_reg_dump", proc_get_mac_reg_dump, NULL}, - {"bb_reg_dump", proc_get_bb_reg_dump, NULL}, - {"rf_reg_dump", proc_get_rf_reg_dump, NULL}, - - {"all_sta_info", proc_get_all_sta_info, NULL}, - - {"rx_signal", proc_get_rx_signal, proc_set_rx_signal}, - {"hw_info", proc_get_hw_status, NULL}, - - {"ht_enable", proc_get_ht_enable, proc_set_ht_enable}, - {"bw_mode", proc_get_bw_mode, proc_set_bw_mode}, - {"ampdu_enable", proc_get_ampdu_enable, proc_set_ampdu_enable}, - {"rx_stbc", proc_get_rx_stbc, proc_set_rx_stbc}, - {"rx_ampdu", proc_get_rx_ampdu, proc_set_rx_ampdu}, - - {"en_fwps", proc_get_en_fwps, proc_set_en_fwps}, - - /* path_rssi", proc_get_two_path_rssi, NULL}, */ - {"rssi_disp", proc_get_rssi_disp, proc_set_rssi_disp}, - - {"btcoex_dbg", proc_get_btcoex_dbg, proc_set_btcoex_dbg}, - {"btcoex", proc_get_btcoex_info, NULL}, - - {"linked_info_dump", proc_get_linked_info_dump, proc_set_linked_info_dump}, -#ifdef CONFIG_DBG_COUNTER - {"rx_logs", proc_get_rx_logs, NULL}, - {"tx_logs", proc_get_tx_logs, NULL}, - {"int_logs", proc_get_int_logs, NULL}, -#endif -}; - -static const int adapter_proc_hdls_num = sizeof(adapter_proc_hdls) / sizeof(struct rtw_proc_hdl); - -static int rtw_adapter_proc_open(struct inode *inode, struct file *file) -{ - ssize_t index = (ssize_t)PDE_DATA(inode); - const struct rtw_proc_hdl *hdl = adapter_proc_hdls+index; - - return single_open(file, hdl->show, proc_get_parent_data(inode)); -} - -static ssize_t rtw_adapter_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) -{ - ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); - const struct rtw_proc_hdl *hdl = adapter_proc_hdls+index; - ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; - - if (write) - return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private); - - return -EROFS; -} - -static const struct file_operations rtw_adapter_proc_fops = { - .owner = THIS_MODULE, - .open = rtw_adapter_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = rtw_adapter_proc_write, -}; - -int proc_get_odm_dbg_comp(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - rtw_odm_dbg_comp_msg(m, adapter); - - return 0; -} - -ssize_t proc_set_odm_dbg_comp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - - u64 dbg_comp; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%llx", &dbg_comp); - - if (num != 1) - return count; - - rtw_odm_dbg_comp_set(adapter, dbg_comp); - } - - return count; -} - -int proc_get_odm_dbg_level(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - rtw_odm_dbg_level_msg(m, adapter); - - return 0; -} - -ssize_t proc_set_odm_dbg_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - - u32 dbg_level; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%u", &dbg_level); - - if (num != 1) - return count; - - rtw_odm_dbg_level_set(adapter, dbg_level); - } - - return count; -} - -static int proc_get_odm_ability(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - - rtw_odm_ability_msg(m, adapter); - - return 0; -} - -static ssize_t proc_set_odm_ability(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - - u32 ability; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%x", &ability); - - if (num != 1) - return count; - - rtw_odm_ability_set(adapter, ability); - } - - return count; -} - -int proc_get_odm_adaptivity(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - rtw_odm_adaptivity_parm_msg(m, padapter); - - return 0; -} - -ssize_t proc_set_odm_adaptivity(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) -{ - struct net_device *dev = data; - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - char tmp[32]; - u32 TH_L2H_ini; - s8 TH_EDCCA_HL_diff; - u32 IGI_Base; - int ForceEDCCA; - u8 AdapEn_RSSI; - u8 IGI_LowerBound; - - if (count < 1) - return -EFAULT; - - if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { - - int num = sscanf(tmp, "%x %hhd %x %d %hhu %hhu", - &TH_L2H_ini, &TH_EDCCA_HL_diff, &IGI_Base, &ForceEDCCA, &AdapEn_RSSI, &IGI_LowerBound); - - if (num != 6) - return count; - - rtw_odm_adaptivity_parm_set(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)IGI_Base, (bool)ForceEDCCA, AdapEn_RSSI, IGI_LowerBound); - } - - return count; -} - -/* -* rtw_odm_proc: -* init/deinit when register/unregister net_device, along with rtw_adapter_proc -*/ -static const struct rtw_proc_hdl odm_proc_hdls[] = { - {"dbg_comp", proc_get_odm_dbg_comp, proc_set_odm_dbg_comp}, - {"dbg_level", proc_get_odm_dbg_level, proc_set_odm_dbg_level}, - {"ability", proc_get_odm_ability, proc_set_odm_ability}, - {"adaptivity", proc_get_odm_adaptivity, proc_set_odm_adaptivity}, -}; - -static const int odm_proc_hdls_num = sizeof(odm_proc_hdls) / sizeof(struct rtw_proc_hdl); - -static int rtw_odm_proc_open(struct inode *inode, struct file *file) -{ - ssize_t index = (ssize_t)PDE_DATA(inode); - const struct rtw_proc_hdl *hdl = odm_proc_hdls+index; - - return single_open(file, hdl->show, proc_get_parent_data(inode)); -} - -static ssize_t rtw_odm_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) -{ - ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); - const struct rtw_proc_hdl *hdl = odm_proc_hdls+index; - ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; - - if (write) - return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private); - - return -EROFS; -} - -static const struct file_operations rtw_odm_proc_fops = { - .owner = THIS_MODULE, - .open = rtw_odm_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = rtw_odm_proc_write, -}; - -static struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev) -{ - struct proc_dir_entry *dir_odm = NULL; - struct proc_dir_entry *entry = NULL; - struct adapter *adapter = rtw_netdev_priv(dev); - ssize_t i; - - if (!adapter->dir_dev) { - rtw_warn_on(1); - goto exit; - } - - if (adapter->dir_odm) { - rtw_warn_on(1); - goto exit; - } - - dir_odm = rtw_proc_create_dir("odm", adapter->dir_dev, dev); - if (!dir_odm) { - rtw_warn_on(1); - goto exit; - } - - adapter->dir_odm = dir_odm; - - for (i = 0; i < odm_proc_hdls_num; i++) { - entry = rtw_proc_create_entry(odm_proc_hdls[i].name, dir_odm, &rtw_odm_proc_fops, (void *)i); - if (!entry) { - rtw_warn_on(1); - goto exit; - } - } - -exit: - return dir_odm; -} - -static void rtw_odm_proc_deinit(struct adapter *adapter) -{ - struct proc_dir_entry *dir_odm = NULL; - int i; - - dir_odm = adapter->dir_odm; - - if (!dir_odm) { - rtw_warn_on(1); - return; - } - - for (i = 0; i < odm_proc_hdls_num; i++) - remove_proc_entry(odm_proc_hdls[i].name, dir_odm); - - remove_proc_entry("odm", adapter->dir_dev); - - adapter->dir_odm = NULL; -} - -struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev) -{ - struct proc_dir_entry *drv_proc = rtw_proc; - struct proc_dir_entry *dir_dev = NULL; - struct proc_dir_entry *entry = NULL; - struct adapter *adapter = rtw_netdev_priv(dev); - ssize_t i; - - if (!drv_proc) { - rtw_warn_on(1); - goto exit; - } - - if (adapter->dir_dev) { - rtw_warn_on(1); - goto exit; - } - - dir_dev = rtw_proc_create_dir(dev->name, drv_proc, dev); - if (!dir_dev) { - rtw_warn_on(1); - goto exit; - } - - adapter->dir_dev = dir_dev; - - for (i = 0; i < adapter_proc_hdls_num; i++) { - entry = rtw_proc_create_entry(adapter_proc_hdls[i].name, dir_dev, &rtw_adapter_proc_fops, (void *)i); - if (!entry) { - rtw_warn_on(1); - goto exit; - } - } - - rtw_odm_proc_init(dev); - -exit: - return dir_dev; -} - -void rtw_adapter_proc_deinit(struct net_device *dev) -{ - struct proc_dir_entry *drv_proc = rtw_proc; - struct proc_dir_entry *dir_dev = NULL; - struct adapter *adapter = rtw_netdev_priv(dev); - int i; - - dir_dev = adapter->dir_dev; - - if (!dir_dev) { - rtw_warn_on(1); - return; - } - - for (i = 0; i < adapter_proc_hdls_num; i++) - remove_proc_entry(adapter_proc_hdls[i].name, dir_dev); - - rtw_odm_proc_deinit(adapter); - - remove_proc_entry(dev->name, drv_proc); - - adapter->dir_dev = NULL; -} - -void rtw_adapter_proc_replace(struct net_device *dev) -{ - struct proc_dir_entry *drv_proc = rtw_proc; - struct proc_dir_entry *dir_dev = NULL; - struct adapter *adapter = rtw_netdev_priv(dev); - int i; - - dir_dev = adapter->dir_dev; - - if (!dir_dev) { - rtw_warn_on(1); - return; - } - - for (i = 0; i < adapter_proc_hdls_num; i++) - remove_proc_entry(adapter_proc_hdls[i].name, dir_dev); - - rtw_odm_proc_deinit(adapter); - - remove_proc_entry(adapter->old_ifname, drv_proc); - - adapter->dir_dev = NULL; - - rtw_adapter_proc_init(dev); - -} - -#endif /* PROC_DEBUG */ diff --git a/drivers/staging/rtl8723bs/os_dep/rtw_proc.h b/drivers/staging/rtl8723bs/os_dep/rtw_proc.h deleted file mode 100644 index c7e6f62b61ef..000000000000 --- a/drivers/staging/rtl8723bs/os_dep/rtw_proc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTW_PROC_H__ -#define __RTW_PROC_H__ - -#include <linux/proc_fs.h> -#include <linux/seq_file.h> - -struct rtw_proc_hdl { - char *name; - int (*show)(struct seq_file *, void *); - ssize_t (*write)(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -}; - -#ifdef PROC_DEBUG - -int rtw_drv_proc_init(void); -void rtw_drv_proc_deinit(void); -struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev); -void rtw_adapter_proc_deinit(struct net_device *dev); -void rtw_adapter_proc_replace(struct net_device *dev); - -#else //!PROC_DEBUG - -static inline int rtw_drv_proc_init(void) {return 0;} -static inline void rtw_drv_proc_deinit(void) {} -static inline struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev){return NULL;} -static inline void rtw_adapter_proc_deinit(struct net_device *dev){} -static inline void rtw_adapter_proc_replace(struct net_device *dev){} - -#endif //!PROC_DEBUG - -#endif //__RTW_PROC_H__ diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c index 540a7eed621d..d3784c44f6d0 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -371,7 +371,7 @@ static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct rtw_hal_chip_configure(padapter); - hal_btcoex_Initialize(padapter); + hal_btcoex_Initialize((void *) padapter); /* 3 6. read efuse/eeprom data */ rtw_hal_read_chip_info(padapter); @@ -620,12 +620,10 @@ static int __init rtw_drv_entry(void) #endif /* BTCOEXVERSION */ sdio_drvpriv.drv_registered = true; - rtw_drv_proc_init(); ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv); if (ret != 0) { sdio_drvpriv.drv_registered = false; - rtw_drv_proc_deinit(); rtw_ndev_notifier_unregister(); DBG_871X("%s: register driver failed!!(%d)\n", __func__, ret); goto exit; @@ -646,7 +644,6 @@ static void __exit rtw_drv_halt(void) sdio_unregister_driver(&sdio_drvpriv.r871xs_drv); - rtw_drv_proc_deinit(); rtw_ndev_notifier_unregister(); DBG_871X_LEVEL(_drv_always_, "module exit success\n"); diff --git a/drivers/staging/rtl8723bs/os_dep/wifi_regd.c b/drivers/staging/rtl8723bs/os_dep/wifi_regd.c index aa2f62acc994..578b9f734231 100644 --- a/drivers/staging/rtl8723bs/os_dep/wifi_regd.c +++ b/drivers/staging/rtl8723bs/os_dep/wifi_regd.c @@ -33,11 +33,6 @@ REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20, \ NL80211_RRF_PASSIVE_SCAN) -/* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */ -#define RTW_2GHZ_CH14 \ - REG_RULE(2484 - 10, 2484 + 10, 40, 0, 20, \ - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) - static const struct ieee80211_regdomain rtw_regdom_rd = { .n_reg_rules = 3, .alpha2 = "99", diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 1128eec3bd08..e853fa9cc950 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -3842,7 +3842,7 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip) { - int retval = STATUS_FAIL; + int retval; int bufflen; unsigned int lun = SCSI_LUN(srb); u8 *buf = NULL; diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 8277d7895608..561851cc8780 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -393,10 +393,9 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, *offset = 0; *index = *index + 1; } - if ((i == (sg_cnt - 1)) || !resid) - option = RTSX_SG_VALID | RTSX_SG_END | RTSX_SG_TRANS_DATA; - else - option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; + option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; + if ((i == sg_cnt - 1) || !resid) + option |= RTSX_SG_END; rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); @@ -541,10 +540,9 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n", (unsigned int)addr, len); + option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; if (j == (sg_cnt - 1)) - option = RTSX_SG_VALID | RTSX_SG_END | RTSX_SG_TRANS_DATA; - else - option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; + option |= RTSX_SG_END; rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index a06045344301..25c31496757e 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -2573,17 +2573,13 @@ SD_UNLOCK_ENTRY: retval = sd_sdr_tuning(chip); if (retval != STATUS_SUCCESS) { - if (sd20_mode) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) goto status_fail; - } else { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - try_sdio = false; - sd20_mode = true; - goto switch_fail; - } + try_sdio = false; + sd20_mode = true; + goto switch_fail; } sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, @@ -2598,17 +2594,13 @@ SD_UNLOCK_ENTRY: if (read_lba0) { retval = sd_read_lba0(chip); if (retval != STATUS_SUCCESS) { - if (sd20_mode) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) goto status_fail; - } else { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - try_sdio = false; - sd20_mode = true; - goto switch_fail; - } + try_sdio = false; + sd20_mode = true; + goto switch_fail; } } } diff --git a/drivers/staging/sm750fb/ddk750.h b/drivers/staging/sm750fb/ddk750.h index 482c1c6ba422..64ef4d258a91 100644 --- a/drivers/staging/sm750fb/ddk750.h +++ b/drivers/staging/sm750fb/ddk750.h @@ -2,9 +2,6 @@ /* * Copyright (c) 2007 by Silicon Motion, Inc. (SMI) * - * All rights are reserved. Reproduction or in part is prohibited - * without the written consent of the copyright owner. - * * RegSC.h --- SM718 SDK * This file contains the definitions for the System Configuration registers. */ diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c index 5c0ac747ea2b..0ef8d4ff2ef9 100644 --- a/drivers/staging/sm750fb/ddk750_swi2c.c +++ b/drivers/staging/sm750fb/ddk750_swi2c.c @@ -2,9 +2,6 @@ /* * Copyright (c) 2007 by Silicon Motion, Inc. (SMI) * - * All rights are reserved. Reproduction or in part is prohibited - * without the written consent of the copyright owner. - * * swi2c.c --- SM750/SM718 DDK * This file contains the source code for I2C using software * implementation. diff --git a/drivers/staging/sm750fb/ddk750_swi2c.h b/drivers/staging/sm750fb/ddk750_swi2c.h index 5868feea791b..dfa166060da7 100644 --- a/drivers/staging/sm750fb/ddk750_swi2c.h +++ b/drivers/staging/sm750fb/ddk750_swi2c.h @@ -2,9 +2,6 @@ /* * Copyright (c) 2007 by Silicon Motion, Inc. (SMI) * - * All rights are reserved. Reproduction or in part is prohibited - * without the written consent of the copyright owner. - * * swi2c.h --- SM750/SM718 DDK * This file contains the definitions for i2c using software * implementation. diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h index f738e7f99e96..47897e81ec58 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h @@ -56,7 +56,7 @@ struct vchiq_mmal_port { /* component port belongs to, allows simple deref */ struct vchiq_mmal_component *component; - struct vchiq_mmal_port *connected; /* port conencted to */ + struct vchiq_mmal_port *connected; /* port connected to */ /* buffer info */ struct vchiq_mmal_port_buffer minimum_buffer; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 61c69f353cdb..8dc730cfe7a6 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -141,10 +141,8 @@ int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state) return PTR_ERR(g_regs); irq = platform_get_irq(pdev, 0); - if (irq <= 0) { - dev_err(dev, "failed to get IRQ\n"); + if (irq <= 0) return irq; - } err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL, "VCHIQ doorbell", state); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index cc4383d1ec3e..b1595b13dea8 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -2824,7 +2824,6 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) VCHIQ_STATUS_T ret = VCHIQ_SUCCESS; char entity[16]; int *entity_uc; - int local_uc, local_entity_uc; if (!arm_state) goto out; @@ -2849,8 +2848,8 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) ret = VCHIQ_ERROR; goto unlock; } - local_uc = --arm_state->videocore_use_count; - local_entity_uc = --(*entity_uc); + --arm_state->videocore_use_count; + --(*entity_uc); if (!vchiq_videocore_wanted(state)) { if (vchiq_platform_use_suspend_timer() && diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index 183f5cf887e0..56a23a297fa4 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -3322,13 +3322,13 @@ vchiq_dump_shared_state(void *dump_context, struct vchiq_state *state, char buf[80]; int len; - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " %s: slots %d-%d tx_pos=%x recycle=%x", label, shared->slot_first, shared->slot_last, shared->tx_pos, shared->slot_queue_recycle); vchiq_dump(dump_context, buf, len + 1); - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " Slots claimed:"); vchiq_dump(dump_context, buf, len + 1); @@ -3336,7 +3336,7 @@ vchiq_dump_shared_state(void *dump_context, struct vchiq_state *state, struct vchiq_slot_info slot_info = *SLOT_INFO_FROM_INDEX(state, i); if (slot_info.use_count != slot_info.release_count) { - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " %d: %d/%d", i, slot_info.use_count, slot_info.release_count); vchiq_dump(dump_context, buf, len + 1); @@ -3344,7 +3344,7 @@ vchiq_dump_shared_state(void *dump_context, struct vchiq_state *state, } for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++) { - len = snprintf(buf, sizeof(buf), " DEBUG: %s = %d(%x)", + len = scnprintf(buf, sizeof(buf), " DEBUG: %s = %d(%x)", debug_names[i], shared->debug[i], shared->debug[i]); vchiq_dump(dump_context, buf, len + 1); } @@ -3357,11 +3357,11 @@ vchiq_dump_state(void *dump_context, struct vchiq_state *state) int len; int i; - len = snprintf(buf, sizeof(buf), "State %d: %s", state->id, + len = scnprintf(buf, sizeof(buf), "State %d: %s", state->id, conn_state_names[state->conn_state]); vchiq_dump(dump_context, buf, len + 1); - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " tx_pos=%x(@%pK), rx_pos=%x(@%pK)", state->local->tx_pos, state->tx_data + (state->local_tx_pos & VCHIQ_SLOT_MASK), @@ -3369,13 +3369,13 @@ vchiq_dump_state(void *dump_context, struct vchiq_state *state) state->rx_data + (state->rx_pos & VCHIQ_SLOT_MASK)); vchiq_dump(dump_context, buf, len + 1); - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " Version: %d (min %d)", VCHIQ_VERSION, VCHIQ_VERSION_MIN); vchiq_dump(dump_context, buf, len + 1); if (VCHIQ_ENABLE_STATS) { - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, " "error_count=%d", state->stats.ctrl_tx_count, state->stats.ctrl_rx_count, @@ -3383,7 +3383,7 @@ vchiq_dump_state(void *dump_context, struct vchiq_state *state) vchiq_dump(dump_context, buf, len + 1); } - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " Slots: %d available (%d data), %d recyclable, %d stalls " "(%d data)", ((state->slot_queue_available * VCHIQ_SLOT_SIZE) - @@ -3416,7 +3416,7 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) char buf[80]; int len; - len = snprintf(buf, sizeof(buf), "Service %u: %s (ref %u)", + len = scnprintf(buf, sizeof(buf), "Service %u: %s (ref %u)", service->localport, srvstate_names[service->srvstate], service->ref_count - 1); /*Don't include the lock just taken*/ @@ -3428,17 +3428,17 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) int tx_pending, rx_pending; if (service->remoteport != VCHIQ_PORT_FREE) { - int len2 = snprintf(remoteport, sizeof(remoteport), + int len2 = scnprintf(remoteport, sizeof(remoteport), "%u", service->remoteport); if (service->public_fourcc != VCHIQ_FOURCC_INVALID) - snprintf(remoteport + len2, + scnprintf(remoteport + len2, sizeof(remoteport) - len2, " (client %x)", service->client_id); } else strcpy(remoteport, "n/a"); - len += snprintf(buf + len, sizeof(buf) - len, + len += scnprintf(buf + len, sizeof(buf) - len, " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)", VCHIQ_FOURCC_AS_4CHARS(fourcc), remoteport, @@ -3455,7 +3455,7 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) rx_pending = service->bulk_rx.local_insert - service->bulk_rx.remote_insert; - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " Bulk: tx_pending=%d (size %d)," " rx_pending=%d (size %d)", tx_pending, @@ -3468,7 +3468,7 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) if (VCHIQ_ENABLE_STATS) { vchiq_dump(dump_context, buf, len + 1); - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " Ctrl: tx_count=%d, tx_bytes=%llu, " "rx_count=%d, rx_bytes=%llu", service->stats.ctrl_tx_count, @@ -3477,7 +3477,7 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) service->stats.ctrl_rx_bytes); vchiq_dump(dump_context, buf, len + 1); - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " Bulk: tx_count=%d, tx_bytes=%llu, " "rx_count=%d, rx_bytes=%llu", service->stats.bulk_tx_count, @@ -3486,7 +3486,7 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) service->stats.bulk_rx_bytes); vchiq_dump(dump_context, buf, len + 1); - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), " %d quota stalls, %d slot stalls, " "%d bulk stalls, %d aborted, %d errors", service->stats.quota_stalls, @@ -3562,9 +3562,9 @@ void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem, for (offset = 0; offset < 16; offset++) { if (offset < num_bytes) - s += snprintf(s, 4, "%02x ", mem[offset]); + s += scnprintf(s, 4, "%02x ", mem[offset]); else - s += snprintf(s, 4, " "); + s += scnprintf(s, 4, " "); } for (offset = 0; offset < 16; offset++) { diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 9def0748ffee..4e9cfacf75f2 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -287,12 +287,12 @@ static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context, buf->duration_a = vnt_get_duration_le(priv, tx_context->pkt_type, need_ack); buf->duration_b = vnt_get_duration_le(priv, - PK_TYPE_11B, need_ack); + PK_TYPE_11B, need_ack); } buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate); buf->time_stamp_off_b = vnt_time_stamp_off(priv, - priv->top_cck_basic_rate); + priv->top_cck_basic_rate); tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); @@ -325,7 +325,7 @@ static u16 vnt_rxtx_datahead_g_fb(struct vnt_usb_send_context *tx_context, buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate); buf->time_stamp_off_b = vnt_time_stamp_off(priv, - priv->top_cck_basic_rate); + priv->top_cck_basic_rate); tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr); @@ -655,7 +655,7 @@ static u16 vnt_rxtx_ab(struct vnt_usb_send_context *tx_context, u8 need_ack = tx_context->need_ack; buf->rrv_time = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type, - frame_len, current_rate, need_ack); + frame_len, current_rate, need_ack); if (need_mic) head = &tx_head->tx_ab.tx.mic.head; @@ -1036,7 +1036,7 @@ static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) /* Get Duration and TimeStampOff */ short_head->duration = vnt_get_duration_le(priv, - PK_TYPE_11B, false); + PK_TYPE_11B, false); short_head->time_stamp_off = vnt_time_stamp_off(priv, current_rate); } diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index ff351a7a0876..d3304df6bd53 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -216,7 +216,7 @@ static void vnt_submit_rx_urb_complete(struct urb *urb) } urb->transfer_buffer = skb_put(rcb->skb, - skb_tailroom(rcb->skb)); + skb_tailroom(rcb->skb)); } if (usb_submit_urb(urb, GFP_ATOMIC)) { diff --git a/drivers/staging/wilc1000/microchip,wilc1000,sdio.txt b/drivers/staging/wilc1000/microchip,wilc1000,sdio.txt index 4f7d1c2be4d0..da5235950a70 100644 --- a/drivers/staging/wilc1000/microchip,wilc1000,sdio.txt +++ b/drivers/staging/wilc1000/microchip,wilc1000,sdio.txt @@ -10,7 +10,9 @@ Required properties: Optional: - bus-width : Number of data lines wired up the slot. Default 1 bit. - +- rtc_clk : Clock connected on the rtc clock line. Must be assigned + a frequency with assigned-clocks property, and must be + connected to a clock provider. Examples: mmc1: mmc@fc000000 { @@ -24,6 +26,10 @@ mmc1: mmc@fc000000 { wilc_sdio@0 { compatible = "microchip,wilc1000-sdio"; irq-gpios = <&pioC 27 0>; + clocks = <&pck1>; + clock-names = "rtc_clk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <32768>; status = "okay"; reg = <0>; bus-width = <4>; diff --git a/drivers/staging/wilc1000/microchip,wilc1000,spi.txt b/drivers/staging/wilc1000/microchip,wilc1000,spi.txt index 87db87b2d901..34236932dbb6 100644 --- a/drivers/staging/wilc1000/microchip,wilc1000,spi.txt +++ b/drivers/staging/wilc1000/microchip,wilc1000,spi.txt @@ -9,6 +9,10 @@ Required properties: - reg : Chip select address of device - irq-gpios : Connect to a host IRQ +Optional: +- rtc_clk : Clock connected on the rtc clock line. Must be assigned + a frequency with assigned-clocks property, and must be + connected to a clock provider. Examples: @@ -21,6 +25,10 @@ spi1: spi@fc018000 { spi-max-frequency = <48000000>; reg = <0>; irq-gpios = <&pioC 27 0>; + clocks = <&pck1>; + clock-names = "rtc_clk"; + assigned-clocks = <&pck1>; + assigned-clock-rates = <32768>; status = "okay"; }; }; diff --git a/drivers/staging/wilc1000/wilc_hif.c b/drivers/staging/wilc1000/wilc_hif.c index 9345cabe3c93..f2b7d5a1be17 100644 --- a/drivers/staging/wilc1000/wilc_hif.c +++ b/drivers/staging/wilc1000/wilc_hif.c @@ -248,7 +248,7 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type, goto error; } - if (vif->obtaining_ip || vif->connecting) { + if (vif->connecting) { netdev_err(vif->ndev, "Don't do obss scan\n"); result = -EBUSY; goto error; @@ -679,13 +679,7 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, if (mac_status == WILC_MAC_STATUS_CONNECTED && conn_info->status == WLAN_STATUS_SUCCESS) { ether_addr_copy(hif_drv->assoc_bssid, conn_info->bssid); - wilc_set_power_mgmt(vif, 0, 0); - hif_drv->hif_state = HOST_IF_CONNECTED; - - vif->obtaining_ip = true; - mod_timer(&vif->during_ip_timer, - jiffies + msecs_to_jiffies(10000)); } else { hif_drv->hif_state = HOST_IF_IDLE; } @@ -708,15 +702,11 @@ static inline void host_int_handle_disconnect(struct wilc_vif *vif) handle_scan_done(vif, SCAN_EVENT_ABORTED); } - if (hif_drv->conn_info.conn_result) { - vif->obtaining_ip = false; - wilc_set_power_mgmt(vif, 0, 0); - + if (hif_drv->conn_info.conn_result) hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, 0, hif_drv->conn_info.arg); - } else { + else netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__); - } eth_zero_addr(hif_drv->assoc_bssid); @@ -772,9 +762,6 @@ int wilc_disconnect(struct wilc_vif *vif) wid.val = (s8 *)&dummy_reason_code; wid.size = sizeof(char); - vif->obtaining_ip = false; - wilc_set_power_mgmt(vif, 0, 0); - result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1); if (result) { netdev_err(vif->ndev, "Failed to send disconnect\n"); @@ -811,15 +798,6 @@ int wilc_disconnect(struct wilc_vif *vif) return 0; } -void wilc_resolve_disconnect_aberration(struct wilc_vif *vif) -{ - if (!vif->hif_drv) - return; - if (vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP || - vif->hif_drv->hif_state == HOST_IF_CONNECTING) - wilc_disconnect(vif); -} - int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats) { struct wid wid_list[5]; @@ -924,7 +902,7 @@ static int handle_remain_on_chan(struct wilc_vif *vif, if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) return -EBUSY; - if (vif->obtaining_ip || vif->connecting) + if (vif->connecting) return -EBUSY; remain_on_chan_flag = true; @@ -1069,13 +1047,9 @@ static void handle_scan_timer(struct work_struct *work) static void handle_scan_complete(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); - struct wilc *wilc = msg->vif->wilc; del_timer(&msg->vif->hif_drv->scan_timer); - if (!wilc_wlan_get_num_conn_ifcs(wilc)) - wilc_chip_sleep_manually(wilc); - handle_scan_done(msg->vif, SCAN_EVENT_DONE); kfree(msg); @@ -1426,18 +1400,14 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel) return result; } -int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, - u8 ifc_id) +int wilc_set_operation_mode(struct wilc_vif *vif, int index, u8 mode, + u8 ifc_id) { struct wid wid; - struct host_if_drv *hif_drv = vif->hif_drv; int result; struct wilc_drv_handler drv; - if (!hif_drv) - return -EFAULT; - - wid.id = WID_SET_DRV_HANDLER; + wid.id = WID_SET_OPERATION_MODE; wid.type = WID_STR; wid.size = sizeof(drv); wid.val = (u8 *)&drv; @@ -1452,26 +1422,6 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, return result; } -int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode) -{ - struct wid wid; - struct wilc_op_mode op_mode; - int result; - - wid.id = WID_SET_OPERATION_MODE; - wid.type = WID_INT; - wid.size = sizeof(op_mode); - wid.val = (u8 *)&op_mode; - - op_mode.mode = cpu_to_le32(mode); - - result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1); - if (result) - netdev_err(vif->ndev, "Failed to set operation mode\n"); - - return result; -} - s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val) { struct wid wid; @@ -1610,7 +1560,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) *hif_drv_handler = hif_drv; vif->hif_drv = hif_drv; - vif->obtaining_ip = false; if (wilc->clients_count == 0) mutex_init(&wilc->deinit_lock); @@ -1648,8 +1597,6 @@ int wilc_deinit(struct wilc_vif *vif) del_timer_sync(&vif->periodic_rssi); del_timer_sync(&hif_drv->remain_on_ch_timer); - wilc_set_wfi_drv_handler(vif, 0, 0, 0); - if (hif_drv->usr_scan_req.scan_result) { hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, hif_drv->usr_scan_req.arg); @@ -2024,9 +1971,6 @@ int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout) int result; s8 power_mode; - if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled) - return 0; - if (enabled) power_mode = WILC_FW_MIN_FAST_PS; else diff --git a/drivers/staging/wilc1000/wilc_hif.h b/drivers/staging/wilc1000/wilc_hif.h index be1d2497cde9..ac5fe57f872b 100644 --- a/drivers/staging/wilc1000/wilc_hif.h +++ b/drivers/staging/wilc1000/wilc_hif.h @@ -219,11 +219,9 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie, void *user_arg); int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie); void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg); -int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, - u8 ifc_id); -int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode); +int wilc_set_operation_mode(struct wilc_vif *vif, int index, u8 mode, + u8 ifc_id); int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats); -void wilc_resolve_disconnect_aberration(struct wilc_vif *vif); int wilc_get_vif_idx(struct wilc_vif *vif); int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power); int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power); diff --git a/drivers/staging/wilc1000/wilc_mon.c b/drivers/staging/wilc1000/wilc_mon.c index 7d7933d40924..d6f14f69ad64 100644 --- a/drivers/staging/wilc1000/wilc_mon.c +++ b/drivers/staging/wilc1000/wilc_mon.c @@ -35,8 +35,7 @@ void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size) return; /* Get WILC header */ - memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); - le32_to_cpus(&header); + header = get_unaligned_le32(buff - HOST_HDR_OFFSET); /* * The packet offset field contain info about what type of management * the frame we are dealing with and ack status diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c index 565e2b5d0616..508acb8bb089 100644 --- a/drivers/staging/wilc1000/wilc_netdev.c +++ b/drivers/staging/wilc1000/wilc_netdev.c @@ -11,6 +11,7 @@ #include <linux/inetdevice.h> #include "wilc_wfi_cfgoperations.h" +#include "wilc_wlan_cfg.h" #define WILC_MULTICAST_TABLE_SIZE 8 @@ -59,7 +60,7 @@ static int init_irq(struct net_device *dev) ret = request_threaded_irq(wl->dev_irq_num, isr_uh_routine, isr_bh_routine, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "WILC_IRQ", dev); if (ret < 0) netdev_err(dev, "Failed to request IRQ\n"); @@ -474,7 +475,7 @@ static void wilc_wlan_deinitialize(struct net_device *dev) wlan_deinitialize_threads(dev); deinit_irq(dev); - wilc_wlan_stop(wl); + wilc_wlan_stop(wl, vif); wilc_wlan_cleanup(dev); wlan_deinit_locks(dev); @@ -503,12 +504,6 @@ static int wlan_initialize_threads(struct net_device *dev) return 0; } -static int dev_state_ev_handler(struct notifier_block *this, - unsigned long event, void *ptr); -static struct notifier_block g_dev_notifier = { - .notifier_call = dev_state_ev_handler -}; - static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) { int ret = 0; @@ -574,12 +569,11 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) ret = -EIO; goto fail_fw_start; } - register_inetaddr_notifier(&g_dev_notifier); wl->initialized = true; return 0; fail_fw_start: - wilc_wlan_stop(wl); + wilc_wlan_stop(wl, vif); fail_irq_enable: if (!wl->dev_irq_num && @@ -632,10 +626,8 @@ static int wilc_mac_open(struct net_device *ndev) return ret; } - wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), vif->iftype, - vif->idx); - wilc_set_operation_mode(vif, vif->iftype); - + wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype, + vif->idx); wilc_get_mac_address(vif, mac_add); netdev_dbg(ndev, "Mac address: %pM\n", mac_add); ether_addr_copy(ndev->dev_addr, mac_add); @@ -780,7 +772,6 @@ static int wilc_mac_close(struct net_device *ndev) if (wl->open_ifcs == 0) { netdev_dbg(ndev, "Deinitializing wilc1000\n"); wl->close = 1; - unregister_inetaddr_notifier(&g_dev_notifier); wilc_wlan_deinitialize(ndev); } @@ -863,63 +854,6 @@ static const struct net_device_ops wilc_netdev_ops = { .ndo_set_rx_mode = wilc_set_multicast_list, }; -static int dev_state_ev_handler(struct notifier_block *this, - unsigned long event, void *ptr) -{ - struct in_ifaddr *dev_iface = ptr; - struct wilc_priv *priv; - struct host_if_drv *hif_drv; - struct net_device *dev; - struct wilc_vif *vif; - - if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev) - return NOTIFY_DONE; - - dev = (struct net_device *)dev_iface->ifa_dev->dev; - if (dev->netdev_ops != &wilc_netdev_ops) - return NOTIFY_DONE; - - if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) - return NOTIFY_DONE; - - vif = netdev_priv(dev); - priv = &vif->priv; - - hif_drv = (struct host_if_drv *)priv->hif_drv; - - switch (event) { - case NETDEV_UP: - if (vif->iftype == WILC_STATION_MODE || - vif->iftype == WILC_CLIENT_MODE) { - hif_drv->ifc_up = 1; - vif->obtaining_ip = false; - del_timer(&vif->during_ip_timer); - } - - if (vif->wilc->enable_ps) - wilc_set_power_mgmt(vif, 1, 0); - - break; - - case NETDEV_DOWN: - if (vif->iftype == WILC_STATION_MODE || - vif->iftype == WILC_CLIENT_MODE) { - hif_drv->ifc_up = 0; - vif->obtaining_ip = false; - wilc_set_power_mgmt(vif, 0, 0); - } - - wilc_resolve_disconnect_aberration(vif); - - break; - - default: - break; - } - - return NOTIFY_DONE; -} - void wilc_netdev_cleanup(struct wilc *wilc) { int i; diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 4c1c81fed11f..c787c5da8f2b 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -4,6 +4,7 @@ * All rights reserved. */ +#include <linux/clk.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/host.h> @@ -151,6 +152,12 @@ static int wilc_sdio_probe(struct sdio_func *func, wilc->dev = &func->dev; wilc->gpio_irq = gpio; + wilc->rtc_clk = devm_clk_get(&func->card->dev, "rtc_clk"); + if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + else if (!IS_ERR(wilc->rtc_clk)) + clk_prepare_enable(wilc->rtc_clk); + dev_info(&func->dev, "Driver Initializing success\n"); return 0; } @@ -162,6 +169,10 @@ static void wilc_sdio_remove(struct sdio_func *func) /* free the GPIO in module remove */ if (wilc->gpio_irq) gpiod_put(wilc->gpio_irq); + + if (!IS_ERR(wilc->rtc_clk)) + clk_disable_unprepare(wilc->rtc_clk); + wilc_netdev_cleanup(wilc); } @@ -193,9 +204,10 @@ static int wilc_sdio_suspend(struct device *dev) dev_info(dev, "sdio suspend\n"); chip_wakeup(wilc); - if (!wilc->suspend_event) { - wilc_chip_sleep_manually(wilc); - } else { + if (!IS_ERR(wilc->rtc_clk)) + clk_disable_unprepare(wilc->rtc_clk); + + if (wilc->suspend_event) { host_sleep_notify(wilc); chip_allow_sleep(wilc); } diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 736eedef23b6..22f21831649b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -70,15 +70,6 @@ struct wilc_p2p_mgmt_data { static const u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; static const u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; -#define WILC_IP_TIMEOUT_MS 15000 - -static void clear_during_ip(struct timer_list *t) -{ - struct wilc_vif *vif = from_timer(vif, t, during_ip_timer); - - vif->obtaining_ip = false; -} - static void cfg_scan_result(enum scan_event scan_event, struct wilc_rcvd_net_info *info, void *user_void) { @@ -176,7 +167,6 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status, } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) { u16 reason = 0; - vif->obtaining_ip = false; priv->p2p.local_random = 0x01; priv->p2p.recv_random = 0x00; priv->p2p.is_wilc_ie = false; @@ -1038,8 +1028,7 @@ void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size) s32 freq; __le16 fc; - memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); - le32_to_cpus(&header); + header = get_unaligned_le32(buff - HOST_HDR_OFFSET); pkt_offset = GET_PKT_OFFSET(header); if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { @@ -1404,8 +1393,7 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, if (!priv->hif_drv) return -EIO; - if (vif->wilc->enable_ps) - wilc_set_power_mgmt(vif, enabled, timeout); + wilc_set_power_mgmt(vif, enabled, timeout); return 0; } @@ -1421,8 +1409,6 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, priv->p2p.local_random = 0x01; priv->p2p.recv_random = 0x00; priv->p2p.is_wilc_ie = false; - vif->obtaining_ip = false; - del_timer(&vif->during_ip_timer); switch (type) { case NL80211_IFTYPE_STATION: @@ -1433,13 +1419,11 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) wilc_wfi_deinit_mon_interface(wl, true); vif->iftype = WILC_STATION_MODE; - wilc_set_operation_mode(vif, WILC_STATION_MODE); + wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), + WILC_STATION_MODE, vif->idx); memset(priv->assoc_stainfo.sta_associated_bss, 0, WILC_MAX_NUM_STA * ETH_ALEN); - - wl->enable_ps = true; - wilc_set_power_mgmt(vif, 1, 0); break; case NL80211_IFTYPE_P2P_CLIENT: @@ -1448,37 +1432,26 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, priv->wdev.iftype = type; vif->monitor_flag = 0; vif->iftype = WILC_CLIENT_MODE; - wilc_set_operation_mode(vif, WILC_STATION_MODE); - - wl->enable_ps = false; - wilc_set_power_mgmt(vif, 0, 0); + wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), + WILC_STATION_MODE, vif->idx); break; case NL80211_IFTYPE_AP: - wl->enable_ps = false; dev->ieee80211_ptr->iftype = type; priv->wdev.iftype = type; vif->iftype = WILC_AP_MODE; - if (wl->initialized) { - wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), - 0, vif->idx); - wilc_set_operation_mode(vif, WILC_AP_MODE); - wilc_set_power_mgmt(vif, 0, 0); - } + if (wl->initialized) + wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), + WILC_AP_MODE, vif->idx); break; case NL80211_IFTYPE_P2P_GO: - vif->obtaining_ip = true; - mod_timer(&vif->during_ip_timer, - jiffies + msecs_to_jiffies(WILC_IP_TIMEOUT_MS)); - wilc_set_operation_mode(vif, WILC_AP_MODE); dev->ieee80211_ptr->iftype = type; priv->wdev.iftype = type; vif->iftype = WILC_GO_MODE; - - wl->enable_ps = false; - wilc_set_power_mgmt(vif, 0, 0); + wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), + WILC_AP_MODE, vif->idx); break; default: @@ -1500,7 +1473,6 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, netdev_err(dev, "Error in setting channel\n"); wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE); - wilc_set_power_mgmt(vif, 0, 0); return wilc_add_beacon(vif, settings->beacon_interval, settings->dtim_period, &settings->beacon); @@ -1687,16 +1659,16 @@ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) vif->monitor_flag = 0; mutex_lock(&wl->vif_mutex); - wilc_set_wfi_drv_handler(vif, 0, 0, 0); - for (i = vif->idx; i < wl->vif_num ; i++) { + wilc_set_operation_mode(vif, 0, 0, 0); + for (i = vif->idx; i < wl->vif_num; i++) { if ((i + 1) >= wl->vif_num) { wl->vif[i] = NULL; } else { vif = wl->vif[i + 1]; vif->idx = i; wl->vif[i] = vif; - wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), - vif->iftype, vif->idx); + wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), + vif->iftype, vif->idx); } } wl->vif_num--; @@ -1851,7 +1823,6 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type, *wilc = wl; wl->io_type = io_type; wl->hif_func = ops; - wl->enable_ps = false; wl->chip_ps_state = WILC_CHIP_WAKEDUP; INIT_LIST_HEAD(&wl->txq_head.list); INIT_LIST_HEAD(&wl->rxq_head.list); @@ -1949,8 +1920,6 @@ int wilc_init_host_int(struct net_device *net) struct wilc_vif *vif = netdev_priv(net); struct wilc_priv *priv = &vif->priv; - timer_setup(&vif->during_ip_timer, clear_during_ip, 0); - priv->p2p_listen_state = false; mutex_init(&priv->scan_req_lock); @@ -1973,8 +1942,6 @@ void wilc_deinit_host_int(struct net_device *net) mutex_destroy(&priv->scan_req_lock); ret = wilc_deinit(vif); - del_timer_sync(&vif->during_ip_timer); - if (ret) netdev_err(net, "Error while deinitializing host interface\n"); } diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index 1e74a08e7cf1..978a8bdbfc40 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -203,7 +203,6 @@ struct wilc_vif { struct net_device *ndev; u8 mode; struct timer_list during_ip_timer; - bool obtaining_ip; struct timer_list periodic_rssi; struct rf_info periodic_stat; struct tcp_ack_filter ack_filter; @@ -217,6 +216,7 @@ struct wilc { int io_type; s8 mac_status; struct gpio_desc *gpio_irq; + struct clk *rtc_clk; bool initialized; int dev_irq_num; int close; @@ -262,7 +262,6 @@ struct wilc { struct device *dev; bool suspend_event; - bool enable_ps; int clients_count; struct workqueue_struct *hif_workqueue; enum chip_ps_states chip_ps_state; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index d46876edcfeb..771d8cb68dc1 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -455,20 +455,6 @@ void chip_wakeup(struct wilc *wilc) } EXPORT_SYMBOL_GPL(chip_wakeup); -void wilc_chip_sleep_manually(struct wilc *wilc) -{ - if (wilc->chip_ps_state != WILC_CHIP_WAKEDUP) - return; - acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); - - chip_allow_sleep(wilc); - wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1); - - wilc->chip_ps_state = WILC_CHIP_SLEEPING_MANUAL; - release_bus(wilc, WILC_BUS_RELEASE_ONLY); -} -EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually); - void host_wakeup_notify(struct wilc *wilc) { acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); @@ -703,8 +689,7 @@ static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size) do { buff_ptr = buffer + offset; - memcpy(&header, buff_ptr, 4); - le32_to_cpus(&header); + header = get_unaligned_le32(buff_ptr); is_cfg_packet = (header >> 31) & 0x1; pkt_offset = (header >> 22) & 0x1ff; @@ -773,26 +758,6 @@ static void wilc_unknown_isr_ext(struct wilc *wilc) wilc->hif_func->hif_clear_int_ext(wilc, 0); } -static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) -{ - int trials = 10; - - wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR); - - if (wilc->io_type == WILC_HIF_SDIO) - mdelay(WILC_PLL_TO_SDIO); - else - mdelay(WILC_PLL_TO_SPI); - - while (!(is_wilc1000(wilc_get_chipid(wilc, true)) && --trials)) - mdelay(1); -} - -static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1) -{ - wilc->hif_func->hif_clear_int_ext(wilc, SLEEP_INT_CLR); -} - static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) { u32 offset = wilc->rx_buffer_offset; @@ -842,15 +807,9 @@ void wilc_handle_isr(struct wilc *wilc) acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); wilc->hif_func->hif_read_int(wilc, &int_status); - if (int_status & PLL_INT_EXT) - wilc_pllupdate_isr_ext(wilc, int_status); - if (int_status & DATA_INT_EXT) wilc_wlan_handle_isr_ext(wilc, int_status); - if (int_status & SLEEP_INT_EXT) - wilc_sleeptimer_isr_ext(wilc, int_status); - if (!(int_status & (ALL_INT_EXT))) wilc_unknown_isr_ext(wilc); @@ -874,10 +833,8 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, offset = 0; do { - memcpy(&addr, &buffer[offset], 4); - memcpy(&size, &buffer[offset + 4], 4); - le32_to_cpus(&addr); - le32_to_cpus(&size); + addr = get_unaligned_le32(&buffer[offset]); + size = get_unaligned_le32(&buffer[offset + 4]); acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY); offset += 8; while (((int)size) && (offset < buffer_size)) { @@ -985,72 +942,52 @@ int wilc_wlan_start(struct wilc *wilc) return (ret < 0) ? ret : 0; } -int wilc_wlan_stop(struct wilc *wilc) +int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif) { u32 reg = 0; int ret; - u8 timeout = 10; acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); - ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®); + ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®); if (!ret) { + netdev_err(vif->ndev, "Error while reading reg\n"); release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return ret; + return -EIO; } - reg &= ~BIT(10); - ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0, + (reg | WILC_ABORT_REQ_BIT)); if (!ret) { + netdev_err(vif->ndev, "Error while writing reg\n"); release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return ret; + return -EIO; } - do { - ret = wilc->hif_func->hif_read_reg(wilc, - WILC_GLB_RESET_0, ®); - if (!ret) { - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return ret; - } - - if ((reg & BIT(10))) { - reg &= ~BIT(10); - ret = wilc->hif_func->hif_write_reg(wilc, - WILC_GLB_RESET_0, - reg); - timeout--; - } else { - ret = wilc->hif_func->hif_read_reg(wilc, - WILC_GLB_RESET_0, - ®); - if (!ret) { - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return ret; - } - break; - } - - } while (timeout); - reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) | - BIT(29) | BIT(30) | BIT(31)); - - wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); - reg = (u32)~BIT(10); + ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, ®); + if (!ret) { + netdev_err(vif->ndev, "Error while reading reg\n"); + release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); + return -EIO; + } + reg = BIT(0); - ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg); + ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg); + if (!ret) { + netdev_err(vif->ndev, "Error while writing reg\n"); + release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); + return -EIO; + } release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return ret; + return 0; } void wilc_wlan_cleanup(struct net_device *dev) { struct txq_entry_t *tqe; struct rxq_entry_t *rqe; - u32 reg = 0; - int ret; struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; @@ -1075,23 +1012,6 @@ void wilc_wlan_cleanup(struct net_device *dev) wilc->rx_buffer = NULL; kfree(wilc->tx_buffer); wilc->tx_buffer = NULL; - - acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); - - ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®); - if (!ret) { - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return; - } - - ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0, - (reg | ABORT_INT)); - if (!ret) { - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); - return; - } - - release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); wilc->hif_func->hif_deinit(NULL); } @@ -1196,11 +1116,6 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, return ret_size; } -int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, u32 buffer_size) -{ - return wilc_wlan_cfg_get_wid_value(wl, wid, buffer, buffer_size); -} - int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, u32 count) { diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index d2eef7b4c3b7..7469fa47d588 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -98,6 +98,7 @@ #define WILC_VMM_TBL_RX_SHADOW_BASE WILC_AHB_SHARE_MEM_BASE #define WILC_VMM_TBL_RX_SHADOW_SIZE 256 +#define WILC_FW_HOST_COMM 0x13c0 #define WILC_GP_REG_0 0x149c #define WILC_GP_REG_1 0x14a0 @@ -127,9 +128,7 @@ #define WILC_CFG_RSP_STATUS 2 #define WILC_CFG_RSP_SCAN 3 -#define WILC_PLL_TO_SDIO 4 -#define WILC_PLL_TO_SPI 2 -#define ABORT_INT BIT(31) +#define WILC_ABORT_REQ_BIT BIT(31) #define WILC_RX_BUFF_SIZE (96 * 1024) #define WILC_TX_BUFF_SIZE (64 * 1024) @@ -184,14 +183,10 @@ #define EN_VMM BIT(8) #define DATA_INT_EXT INT_0 -#define PLL_INT_EXT INT_1 -#define SLEEP_INT_EXT INT_2 -#define ALL_INT_EXT (DATA_INT_EXT | PLL_INT_EXT | SLEEP_INT_EXT) -#define NUM_INT_EXT 3 +#define ALL_INT_EXT DATA_INT_EXT +#define NUM_INT_EXT 1 #define DATA_INT_CLR CLR_INT0 -#define PLL_INT_CLR CLR_INT1 -#define SLEEP_INT_CLR CLR_INT2 #define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM) #define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM) @@ -280,7 +275,7 @@ struct wilc_vif; int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size); int wilc_wlan_start(struct wilc *wilc); -int wilc_wlan_stop(struct wilc *wilc); +int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif); int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, void (*tx_complete_fn)(void *, int)); @@ -291,12 +286,8 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, u32 drv_handler); -int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, - u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, void (*func)(void *, int)); -void wilc_chip_sleep_manually(struct wilc *wilc); - void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value); int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc); netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index 9dc5de4eb08d..3f53807cee0f 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -52,57 +52,35 @@ static const struct wilc_cfg_str g_cfg_str[] = { static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, u16 id, u8 val8) { - u8 *buf; - if ((offset + 4) >= WILC_MAX_CFG_FRAME_SIZE) return 0; - buf = &frame[offset]; - - buf[0] = (u8)id; - buf[1] = (u8)(id >> 8); - buf[2] = 1; - buf[3] = 0; - buf[4] = val8; + put_unaligned_le16(id, &frame[offset]); + put_unaligned_le16(1, &frame[offset + 2]); + frame[offset + 4] = val8; return 5; } static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16) { - u8 *buf; - if ((offset + 5) >= WILC_MAX_CFG_FRAME_SIZE) return 0; - buf = &frame[offset]; - - buf[0] = (u8)id; - buf[1] = (u8)(id >> 8); - buf[2] = 2; - buf[3] = 0; - buf[4] = (u8)val16; - buf[5] = (u8)(val16 >> 8); + put_unaligned_le16(id, &frame[offset]); + put_unaligned_le16(2, &frame[offset + 2]); + put_unaligned_le16(val16, &frame[offset + 4]); return 6; } static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32) { - u8 *buf; - if ((offset + 7) >= WILC_MAX_CFG_FRAME_SIZE) return 0; - buf = &frame[offset]; - - buf[0] = (u8)id; - buf[1] = (u8)(id >> 8); - buf[2] = 4; - buf[3] = 0; - buf[4] = (u8)val32; - buf[5] = (u8)(val32 >> 8); - buf[6] = (u8)(val32 >> 16); - buf[7] = (u8)(val32 >> 24); + put_unaligned_le16(id, &frame[offset]); + put_unaligned_le16(4, &frame[offset + 2]); + put_unaligned_le32(val32, &frame[offset + 4]); return 8; } @@ -110,46 +88,35 @@ static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32) static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, u32 size) { - u8 *buf; - if ((offset + size + 4) >= WILC_MAX_CFG_FRAME_SIZE) return 0; - buf = &frame[offset]; - - buf[0] = (u8)id; - buf[1] = (u8)(id >> 8); - buf[2] = (u8)size; - buf[3] = (u8)(size >> 8); - + put_unaligned_le16(id, &frame[offset]); + put_unaligned_le16(size, &frame[offset + 2]); if (str && size != 0) - memcpy(&buf[4], str, size); + memcpy(&frame[offset + 4], str, size); return (size + 4); } static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size) { - u8 *buf; u32 i; u8 checksum = 0; if ((offset + size + 5) >= WILC_MAX_CFG_FRAME_SIZE) return 0; - buf = &frame[offset]; - buf[0] = (u8)id; - buf[1] = (u8)(id >> 8); - buf[2] = (u8)size; - buf[3] = (u8)(size >> 8); + put_unaligned_le16(id, &frame[offset]); + put_unaligned_le16(size, &frame[offset + 2]); if ((b) && size != 0) { - memcpy(&buf[4], b, size); + memcpy(&frame[offset + 4], b, size); for (i = 0; i < size; i++) - checksum += buf[i + 4]; + checksum += frame[offset + i + 4]; } - buf[size + 4] = checksum; + frame[offset + size + 4] = checksum; return (size + 5); } @@ -307,21 +274,16 @@ int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size) int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id) { - u8 *buf; - if ((offset + 2) >= WILC_MAX_CFG_FRAME_SIZE) return 0; - buf = &frame[offset]; - - buf[0] = (u8)id; - buf[1] = (u8)(id >> 8); + put_unaligned_le16(id, &frame[offset]); return 2; } -int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer, - u32 buffer_size) +int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, + u32 buffer_size) { u32 type = (wid >> 12) & 0xf; int i, ret = 0; diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.h b/drivers/staging/wilc1000/wilc_wlan_cfg.h index e5ca6cea0682..614c5673f232 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.h +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.h @@ -44,8 +44,8 @@ struct wilc_cfg { struct wilc; int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size); int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id); -int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer, - u32 buffer_size); +int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, + u32 buffer_size); void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, struct wilc_cfg_rsp *rsp); int wilc_wlan_cfg_init(struct wilc *wl); diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index b89d0e0f04cc..70eac586f80c 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -724,7 +724,6 @@ enum { /* NMAC Integer WID list */ /* Custom Integer WID list */ WID_GET_INACTIVE_TIME = 0x2084, - WID_SET_OPERATION_MODE = 0X2086, /* EMAC String WID list */ WID_SSID = 0x3000, WID_FIRMWARE_VERSION = 0x3001, @@ -755,9 +754,9 @@ enum { WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */ WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */ WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */ - WID_SET_DRV_HANDLER = 0x3079, /* NMAC String WID list */ + WID_SET_OPERATION_MODE = 0x3079, WID_11N_P_ACTION_REQ = 0x3080, WID_HUT_TEST_ID = 0x3081, WID_PMKID_INFO = 0x3082, diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index ab734534093b..28d372a0663a 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -226,11 +226,9 @@ usbctlx_get_rridresult(const struct hfa384x_usb_rridresp *rridresp, /*---------------------------------------------------*/ /* Low level req/resp CTLX formatters and submitters */ -static int +static inline int hfa384x_docmd(struct hfa384x *hw, - enum cmd_mode mode, - struct hfa384x_metacmd *cmd, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data); + struct hfa384x_metacmd *cmd); static int hfa384x_dorrid(struct hfa384x *hw, @@ -250,21 +248,17 @@ hfa384x_dowrid(struct hfa384x *hw, static int hfa384x_dormem(struct hfa384x *hw, - enum cmd_mode mode, u16 page, u16 offset, void *data, - unsigned int len, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data); + unsigned int len); static int hfa384x_dowmem(struct hfa384x *hw, - enum cmd_mode mode, u16 page, u16 offset, void *data, - unsigned int len, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data); + unsigned int len); static int hfa384x_isgood_pdrcode(u16 pdrcode); @@ -820,99 +814,6 @@ static void hfa384x_cb_status(struct hfa384x *hw, } } -static inline int hfa384x_docmd_wait(struct hfa384x *hw, - struct hfa384x_metacmd *cmd) -{ - return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL); -} - -static inline int -hfa384x_docmd_async(struct hfa384x *hw, - struct hfa384x_metacmd *cmd, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data) -{ - return hfa384x_docmd(hw, DOASYNC, cmd, cmdcb, usercb, usercb_data); -} - -static inline int -hfa384x_dorrid_wait(struct hfa384x *hw, u16 rid, void *riddata, - unsigned int riddatalen) -{ - return hfa384x_dorrid(hw, DOWAIT, - rid, riddata, riddatalen, NULL, NULL, NULL); -} - -static inline int -hfa384x_dorrid_async(struct hfa384x *hw, - u16 rid, void *riddata, unsigned int riddatalen, - ctlx_cmdcb_t cmdcb, - ctlx_usercb_t usercb, void *usercb_data) -{ - return hfa384x_dorrid(hw, DOASYNC, - rid, riddata, riddatalen, - cmdcb, usercb, usercb_data); -} - -static inline int -hfa384x_dowrid_wait(struct hfa384x *hw, u16 rid, void *riddata, - unsigned int riddatalen) -{ - return hfa384x_dowrid(hw, DOWAIT, - rid, riddata, riddatalen, NULL, NULL, NULL); -} - -static inline int -hfa384x_dowrid_async(struct hfa384x *hw, - u16 rid, void *riddata, unsigned int riddatalen, - ctlx_cmdcb_t cmdcb, - ctlx_usercb_t usercb, void *usercb_data) -{ - return hfa384x_dowrid(hw, DOASYNC, - rid, riddata, riddatalen, - cmdcb, usercb, usercb_data); -} - -static inline int -hfa384x_dormem_wait(struct hfa384x *hw, - u16 page, u16 offset, void *data, unsigned int len) -{ - return hfa384x_dormem(hw, DOWAIT, - page, offset, data, len, NULL, NULL, NULL); -} - -static inline int -hfa384x_dormem_async(struct hfa384x *hw, - u16 page, u16 offset, void *data, unsigned int len, - ctlx_cmdcb_t cmdcb, - ctlx_usercb_t usercb, void *usercb_data) -{ - return hfa384x_dormem(hw, DOASYNC, - page, offset, data, len, - cmdcb, usercb, usercb_data); -} - -static inline int -hfa384x_dowmem_wait(struct hfa384x *hw, - u16 page, u16 offset, void *data, unsigned int len) -{ - return hfa384x_dowmem(hw, DOWAIT, - page, offset, data, len, NULL, NULL, NULL); -} - -static inline int -hfa384x_dowmem_async(struct hfa384x *hw, - u16 page, - u16 offset, - void *data, - unsigned int len, - ctlx_cmdcb_t cmdcb, - ctlx_usercb_t usercb, void *usercb_data) -{ - return hfa384x_dowmem(hw, DOASYNC, - page, offset, data, len, - cmdcb, usercb, usercb_data); -} - /*---------------------------------------------------------------- * hfa384x_cmd_initialize * @@ -944,7 +845,7 @@ int hfa384x_cmd_initialize(struct hfa384x *hw) cmd.parm1 = 0; cmd.parm2 = 0; - result = hfa384x_docmd_wait(hw, &cmd); + result = hfa384x_docmd(hw, &cmd); pr_debug("cmdresp.init: status=0x%04x, resp0=0x%04x, resp1=0x%04x, resp2=0x%04x\n", cmd.result.status, @@ -990,7 +891,7 @@ int hfa384x_cmd_disable(struct hfa384x *hw, u16 macport) cmd.parm1 = 0; cmd.parm2 = 0; - return hfa384x_docmd_wait(hw, &cmd); + return hfa384x_docmd(hw, &cmd); } /*---------------------------------------------------------------- @@ -1024,7 +925,7 @@ int hfa384x_cmd_enable(struct hfa384x *hw, u16 macport) cmd.parm1 = 0; cmd.parm2 = 0; - return hfa384x_docmd_wait(hw, &cmd); + return hfa384x_docmd(hw, &cmd); } /*---------------------------------------------------------------- @@ -1067,7 +968,7 @@ int hfa384x_cmd_monitor(struct hfa384x *hw, u16 enable) cmd.parm1 = 0; cmd.parm2 = 0; - return hfa384x_docmd_wait(hw, &cmd); + return hfa384x_docmd(hw, &cmd); } /*---------------------------------------------------------------- @@ -1124,7 +1025,7 @@ int hfa384x_cmd_download(struct hfa384x *hw, u16 mode, u16 lowaddr, cmd.parm1 = highaddr; cmd.parm2 = codelen; - return hfa384x_docmd_wait(hw, &cmd); + return hfa384x_docmd(hw, &cmd); } /*---------------------------------------------------------------- @@ -1284,13 +1185,8 @@ cleanup: * * Arguments: * hw device structure - * mode DOWAIT or DOASYNC * cmd cmd structure. Includes all arguments and result * data points. All in host order. in host order - * cmdcb command-specific callback - * usercb user callback for async calls, NULL for DOWAIT calls - * usercb_data user supplied data pointer for async calls, NULL - * for DOWAIT calls * * Returns: * 0 success @@ -1306,11 +1202,9 @@ cleanup: * process *---------------------------------------------------------------- */ -static int +static inline int hfa384x_docmd(struct hfa384x *hw, - enum cmd_mode mode, - struct hfa384x_metacmd *cmd, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data) + struct hfa384x_metacmd *cmd) { int result; struct hfa384x_usbctlx *ctlx; @@ -1333,15 +1227,15 @@ hfa384x_docmd(struct hfa384x *hw, pr_debug("cmdreq: cmd=0x%04x parm0=0x%04x parm1=0x%04x parm2=0x%04x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2); - ctlx->reapable = mode; - ctlx->cmdcb = cmdcb; - ctlx->usercb = usercb; - ctlx->usercb_data = usercb_data; + ctlx->reapable = DOWAIT; + ctlx->cmdcb = NULL; + ctlx->usercb = NULL; + ctlx->usercb_data = NULL; result = hfa384x_usbctlx_submit(hw, ctlx); if (result != 0) { kfree(ctlx); - } else if (mode == DOWAIT) { + } else { struct usbctlx_cmd_completor cmd_completor; struct usbctlx_completor *completor; @@ -1540,14 +1434,10 @@ done: * * Arguments: * hw device structure - * mode DOWAIT or DOASYNC * page MAC address space page (CMD format) * offset MAC address space offset * data Ptr to data buffer to receive read * len Length of the data to read (max == 2048) - * cmdcb command callback for async calls, NULL for DOWAIT calls - * usercb user callback for async calls, NULL for DOWAIT calls - * usercb_data user supplied data pointer for async calls * * Returns: * 0 success @@ -1559,18 +1449,15 @@ done: * Side effects: * * Call context: - * interrupt (DOASYNC) - * process (DOWAIT or DOASYNC) + * process (DOWAIT) *---------------------------------------------------------------- */ static int hfa384x_dormem(struct hfa384x *hw, - enum cmd_mode mode, u16 page, u16 offset, void *data, - unsigned int len, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data) + unsigned int len) { int result; struct hfa384x_usbctlx *ctlx; @@ -1598,15 +1485,15 @@ hfa384x_dormem(struct hfa384x *hw, pr_debug("pktsize=%zd\n", ROUNDUP64(sizeof(ctlx->outbuf.rmemreq))); - ctlx->reapable = mode; - ctlx->cmdcb = cmdcb; - ctlx->usercb = usercb; - ctlx->usercb_data = usercb_data; + ctlx->reapable = DOWAIT; + ctlx->cmdcb = NULL; + ctlx->usercb = NULL; + ctlx->usercb_data = NULL; result = hfa384x_usbctlx_submit(hw, ctlx); if (result != 0) { kfree(ctlx); - } else if (mode == DOWAIT) { + } else { struct usbctlx_rmem_completor completor; result = @@ -1632,14 +1519,10 @@ done: * * Arguments: * hw device structure - * mode DOWAIT or DOASYNC * page MAC address space page (CMD format) * offset MAC address space offset * data Ptr to data buffer containing write data * len Length of the data to read (max == 2048) - * cmdcb command callback for async calls, NULL for DOWAIT calls - * usercb user callback for async calls, NULL for DOWAIT calls - * usercb_data user supplied data pointer for async calls. * * Returns: * 0 success @@ -1652,17 +1535,15 @@ done: * * Call context: * interrupt (DOWAIT) - * process (DOWAIT or DOASYNC) + * process (DOWAIT) *---------------------------------------------------------------- */ static int hfa384x_dowmem(struct hfa384x *hw, - enum cmd_mode mode, u16 page, u16 offset, void *data, - unsigned int len, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data) + unsigned int len) { int result; struct hfa384x_usbctlx *ctlx; @@ -1689,15 +1570,15 @@ hfa384x_dowmem(struct hfa384x *hw, sizeof(ctlx->outbuf.wmemreq.offset) + sizeof(ctlx->outbuf.wmemreq.page) + len; - ctlx->reapable = mode; - ctlx->cmdcb = cmdcb; - ctlx->usercb = usercb; - ctlx->usercb_data = usercb_data; + ctlx->reapable = DOWAIT; + ctlx->cmdcb = NULL; + ctlx->usercb = NULL; + ctlx->usercb_data = NULL; result = hfa384x_usbctlx_submit(hw, ctlx); if (result != 0) { kfree(ctlx); - } else if (mode == DOWAIT) { + } else { struct usbctlx_cmd_completor completor; struct hfa384x_cmdresult wmemresult; @@ -2004,10 +1885,10 @@ int hfa384x_drvr_flashdl_write(struct hfa384x *hw, u32 daddr, writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ? HFA384x_USB_RWMEM_MAXLEN : writelen; - result = hfa384x_dowmem_wait(hw, - writepage, - writeoffset, - writebuf, writelen); + result = hfa384x_dowmem(hw, + writepage, + writeoffset, + writebuf, writelen); } /* set the download 'write flash' mode */ @@ -2061,7 +1942,7 @@ exit_proc: */ int hfa384x_drvr_getconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len) { - return hfa384x_dorrid_wait(hw, rid, buf, len); + return hfa384x_dorrid(hw, DOWAIT, rid, buf, len, NULL, NULL, NULL); } /*---------------------------------------------------------------- @@ -2094,8 +1975,8 @@ hfa384x_drvr_setconfig_async(struct hfa384x *hw, void *buf, u16 len, ctlx_usercb_t usercb, void *usercb_data) { - return hfa384x_dowrid_async(hw, rid, buf, len, - hfa384x_cb_status, usercb, usercb_data); + return hfa384x_dowrid(hw, DOASYNC, rid, buf, len, hfa384x_cb_status, + usercb, usercb_data); } /*---------------------------------------------------------------- @@ -2261,12 +2142,11 @@ int hfa384x_drvr_ramdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len) currlen = HFA384x_USB_RWMEM_MAXLEN; /* Do blocking ctlx */ - result = hfa384x_dowmem_wait(hw, - currpage, - curroffset, - data + - (i * HFA384x_USB_RWMEM_MAXLEN), - currlen); + result = hfa384x_dowmem(hw, + currpage, + curroffset, + data + (i * HFA384x_USB_RWMEM_MAXLEN), + currlen); if (result) break; @@ -2338,8 +2218,8 @@ int hfa384x_drvr_readpda(struct hfa384x *hw, void *buf, unsigned int len) curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr); /* units of bytes */ - result = hfa384x_dormem_wait(hw, currpage, curroffset, buf, - len); + result = hfa384x_dormem(hw, currpage, curroffset, buf, + len); if (result) { netdev_warn(hw->wlandev->netdev, @@ -2422,7 +2302,7 @@ int hfa384x_drvr_readpda(struct hfa384x *hw, void *buf, unsigned int len) */ int hfa384x_drvr_setconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len) { - return hfa384x_dowrid_wait(hw, rid, buf, len); + return hfa384x_dowrid(hw, DOWAIT, rid, buf, len, NULL, NULL, NULL); } /*---------------------------------------------------------------- diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index 1eba5fa28d8f..7d7d77b04255 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -126,13 +126,6 @@ static int prism2mib_privacyinvoked(struct mibrec *mib, struct p80211msg_dot11req_mibset *msg, void *data); -static int prism2mib_excludeunencrypted(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data); - static int prism2mib_fragmentationthreshold(struct mibrec *mib, int isget, @@ -176,7 +169,7 @@ static struct mibrec mibtab[] = { {DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, F_STA | F_READ | F_WRITE, HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0, - prism2mib_excludeunencrypted}, + prism2mib_flag}, /* dot11mac MIB's */ @@ -594,41 +587,6 @@ static int prism2mib_privacyinvoked(struct mibrec *mib, } /* - * prism2mib_excludeunencrypted - * - * Get/set the dot11ExcludeUnencrypted value. - * - * MIB record parameters: - * parm1 Prism2 RID value. - * parm2 Bit value for ExcludeUnencrypted flag. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int prism2mib_excludeunencrypted(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data) -{ - return prism2mib_flag(mib, isget, wlandev, hw, msg, data); -} - -/* * prism2mib_fragmentationthreshold * * Get/set the fragmentation threshold. diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index fb5441399131..8f25496188aa 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -846,7 +846,7 @@ static int prism2sta_getcardinfo(struct wlandevice *wlandev) result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, snum, HFA384x_RID_NICSERIALNUMBER_LEN); if (!result) { - netdev_info(wlandev->netdev, "Prism2 card SN: %*pEhp\n", + netdev_info(wlandev->netdev, "Prism2 card SN: %*pE\n", HFA384x_RID_NICSERIALNUMBER_LEN, snum); } else { netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); |