drivers/staging/greybus/raw.c
Source file repositories/reference/linux-study-clean/drivers/staging/greybus/raw.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/staging/greybus/raw.c- Extension
.c- Size
- 8877 bytes
- Lines
- 400
- Domain
- Driver Families
- Bucket
- drivers/staging
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/slab.hlinux/sizes.hlinux/cdev.hlinux/fs.hlinux/idr.hlinux/uaccess.hlinux/greybus.h
Detected Declarations
struct gb_rawstruct raw_datafunction receive_datafunction gb_raw_request_handlerfunction gb_raw_sendfunction raw_dev_releasefunction gb_raw_probefunction gb_raw_disconnectfunction readfunction raw_writefunction raw_readfunction raw_initfunction raw_exitmodule init raw_init
Annotated Snippet
static const struct file_operations raw_fops;
static DEFINE_IDA(minors);
/* Number of minor devices this driver supports */
#define NUM_MINORS 256
/* Maximum size of any one send data buffer we support */
#define MAX_PACKET_SIZE (PAGE_SIZE * 2)
/*
* Maximum size of the data in the receive buffer we allow before we start to
* drop messages on the floor
*/
#define MAX_DATA_SIZE (MAX_PACKET_SIZE * 8)
/*
* Add the raw data message to the list of received messages.
*/
static int receive_data(struct gb_raw *raw, u32 len, u8 *data)
{
struct raw_data *raw_data;
struct device *dev = &raw->connection->bundle->dev;
int retval = 0;
if (len > MAX_PACKET_SIZE) {
dev_err(dev, "Too big of a data packet, rejected\n");
return -EINVAL;
}
mutex_lock(&raw->list_lock);
if ((raw->list_data + len) > MAX_DATA_SIZE) {
dev_err(dev, "Too much data in receive buffer, now dropping packets\n");
retval = -EINVAL;
goto exit;
}
raw_data = kmalloc_flex(*raw_data, data, len);
if (!raw_data) {
retval = -ENOMEM;
goto exit;
}
raw->list_data += len;
raw_data->len = len;
memcpy(&raw_data->data[0], data, len);
list_add_tail(&raw_data->entry, &raw->list);
exit:
mutex_unlock(&raw->list_lock);
return retval;
}
static int gb_raw_request_handler(struct gb_operation *op)
{
struct gb_connection *connection = op->connection;
struct device *dev = &connection->bundle->dev;
struct gb_raw *raw = greybus_get_drvdata(connection->bundle);
struct gb_raw_send_request *receive;
u32 len;
if (op->type != GB_RAW_TYPE_SEND) {
dev_err(dev, "unknown request type 0x%02x\n", op->type);
return -EINVAL;
}
/* Verify size of payload */
if (op->request->payload_size < sizeof(*receive)) {
dev_err(dev, "raw receive request too small (%zu < %zu)\n",
op->request->payload_size, sizeof(*receive));
return -EINVAL;
}
receive = op->request->payload;
len = le32_to_cpu(receive->len);
if (len != (int)(op->request->payload_size - sizeof(__le32))) {
dev_err(dev, "raw receive request wrong size %d vs %d\n", len,
(int)(op->request->payload_size - sizeof(__le32)));
return -EINVAL;
}
if (len == 0) {
dev_err(dev, "raw receive request of 0 bytes?\n");
return -EINVAL;
}
return receive_data(raw, len, receive->data);
}
static int gb_raw_send(struct gb_raw *raw, u32 len, const char __user *data)
{
struct gb_connection *connection = raw->connection;
struct gb_raw_send_request *request;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/slab.h`, `linux/sizes.h`, `linux/cdev.h`, `linux/fs.h`, `linux/idr.h`, `linux/uaccess.h`.
- Detected declarations: `struct gb_raw`, `struct raw_data`, `function receive_data`, `function gb_raw_request_handler`, `function gb_raw_send`, `function raw_dev_release`, `function gb_raw_probe`, `function gb_raw_disconnect`, `function read`, `function raw_write`.
- Atlas domain: Driver Families / drivers/staging.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.