38 #include <linux/module.h>
39 #include <linux/slab.h>
40 #include <linux/string.h>
41 #include <linux/errno.h>
54 #define BIOS_SCAN_LIMIT 0xffffffff
55 #define MAX_IMAGE_LENGTH 16
56 static struct _rbu_data {
57 void *image_update_buffer;
58 unsigned long image_update_buffer_size;
59 unsigned long bios_image_size;
60 int image_update_ordernum;
63 unsigned long packet_read_count;
64 unsigned long num_packets;
65 unsigned long packetsize;
66 unsigned long imagesize;
73 "BIOS image type. choose- mono or packet or init");
75 static unsigned long allocation_floor = 0x100000;
78 "Minimum address for allocations when using Packet mode");
93 static void init_packet_head(
void)
95 INIT_LIST_HEAD(&packet_data_head.list);
96 rbu_data.packet_read_count = 0;
97 rbu_data.num_packets = 0;
98 rbu_data.packetsize = 0;
99 rbu_data.imagesize = 0;
102 static int create_packet(
void *
data,
size_t length)
107 unsigned int packet_array_size = 0;
108 void **invalid_addr_packet_array =
NULL;
109 void *packet_data_temp_buf =
NULL;
110 unsigned int idx = 0;
112 pr_debug(
"create_packet: entry \n");
114 if (!rbu_data.packetsize) {
115 pr_debug(
"create_packet: packetsize not specified\n");
120 spin_unlock(&rbu_data.lock);
126 "dell_rbu:%s: failed to allocate new "
127 "packet\n", __func__);
129 spin_lock(&rbu_data.lock);
146 packet_array_size =
max(
147 (
unsigned int)(allocation_floor / rbu_data.packetsize),
149 invalid_addr_packet_array = kzalloc(packet_array_size *
sizeof(
void*),
152 if (!invalid_addr_packet_array) {
154 "dell_rbu:%s: failed to allocate "
155 "invalid_addr_packet_array \n",
158 spin_lock(&rbu_data.lock);
159 goto out_alloc_packet;
162 while (!packet_data_temp_buf) {
163 packet_data_temp_buf = (
unsigned char *)
165 if (!packet_data_temp_buf) {
167 "dell_rbu:%s: failed to allocate new "
168 "packet\n", __func__);
170 spin_lock(&rbu_data.lock);
171 goto out_alloc_packet_array;
175 < allocation_floor) {
176 pr_debug(
"packet 0x%lx below floor at 0x%lx.\n",
178 packet_data_temp_buf),
180 invalid_addr_packet_array[idx++] = packet_data_temp_buf;
181 packet_data_temp_buf =
NULL;
184 spin_lock(&rbu_data.lock);
186 newpacket->
data = packet_data_temp_buf;
188 pr_debug(
"create_packet: newpacket at physical addr %lx\n",
194 ++rbu_data.num_packets;
197 INIT_LIST_HEAD(&newpacket->
list);
204 out_alloc_packet_array:
207 pr_debug(
"freeing unused packet below floor 0x%lx.\n",
209 invalid_addr_packet_array[idx-1]));
210 free_pages((
unsigned long)invalid_addr_packet_array[idx-1],
213 kfree(invalid_addr_packet_array);
224 static int packetize_data(
const u8 *data,
size_t length)
230 u8 *
end = (
u8 *) data + length;
231 pr_debug(
"packetize_data: data length %zd\n", length);
232 if (!rbu_data.packetsize) {
234 "dell_rbu: packetsize not specified\n");
242 if ((temp + rbu_data.packetsize) <
end)
243 packet_length = rbu_data.packetsize;
246 packet_length = end - temp;
250 if ((rc = create_packet(temp, packet_length)))
253 pr_debug(
"%p:%td\n", temp, (end - temp));
254 temp += packet_length;
257 rbu_data.imagesize =
length;
262 static int do_packet_read(
char *data,
struct list_head *ptemp_list,
263 int length,
int bytes_read,
int *list_read_count)
267 int bytes_copied = 0;
271 *list_read_count += newpacket->
length;
273 if (*list_read_count > bytes_read) {
275 j = newpacket->
length - (*list_read_count - bytes_read);
277 ptemp_buf = (
u8 *) newpacket->
data + j;
282 if (length > (*list_read_count - bytes_read))
287 bytes_copied = (*list_read_count - bytes_read);
291 memcpy(data, ptemp_buf, bytes_copied);
296 static int packet_read_list(
char *data,
size_t * pread_length)
300 int bytes_copied = 0;
302 int remaining_bytes = 0;
306 if (0 == rbu_data.num_packets)
309 remaining_bytes = *pread_length;
310 bytes_read = rbu_data.packet_read_count;
312 ptemp_list = (&packet_data_head.list)->
next;
313 while (!list_empty(ptemp_list)) {
314 bytes_copied = do_packet_read(pdest, ptemp_list,
315 remaining_bytes, bytes_read, &temp_count);
316 remaining_bytes -= bytes_copied;
317 bytes_read += bytes_copied;
318 pdest += bytes_copied;
323 if (remaining_bytes == 0)
326 ptemp_list = ptemp_list->
next;
329 *pread_length = bytes_read - rbu_data.packet_read_count;
330 rbu_data.packet_read_count = bytes_read;
334 static void packet_empty_list(
void)
340 ptemp_list = (&packet_data_head.list)->
next;
341 while (!list_empty(ptemp_list)) {
344 pnext_list = ptemp_list->
next;
346 ptemp_list = pnext_list;
351 memset(newpacket->
data, 0, rbu_data.packetsize);
356 rbu_data.packet_read_count = 0;
357 rbu_data.num_packets = 0;
358 rbu_data.imagesize = 0;
365 static void img_update_free(
void)
367 if (!rbu_data.image_update_buffer)
373 memset(rbu_data.image_update_buffer, 0,
374 rbu_data.image_update_buffer_size);
375 if (rbu_data.dma_alloc == 1)
377 rbu_data.image_update_buffer, dell_rbu_dmaaddr);
379 free_pages((
unsigned long) rbu_data.image_update_buffer,
380 rbu_data.image_update_ordernum);
385 rbu_data.image_update_ordernum = -1;
386 rbu_data.image_update_buffer =
NULL;
387 rbu_data.image_update_buffer_size = 0;
388 rbu_data.bios_image_size = 0;
389 rbu_data.dma_alloc = 0;
402 static int img_update_realloc(
unsigned long size)
404 unsigned char *image_update_buffer =
NULL;
406 unsigned long img_buf_phys_addr;
414 if (rbu_data.image_update_buffer_size >= size) {
418 if ((size != 0) && (rbu_data.image_update_buffer ==
NULL)) {
420 "check failed\n", __func__);
435 spin_unlock(&rbu_data.lock);
438 image_update_buffer =
445 free_pages((
unsigned long) image_update_buffer, ordernum);
452 spin_lock(&rbu_data.lock);
454 if (image_update_buffer !=
NULL) {
455 rbu_data.image_update_buffer = image_update_buffer;
456 rbu_data.image_update_buffer_size =
size;
457 rbu_data.bios_image_size =
458 rbu_data.image_update_buffer_size;
459 rbu_data.image_update_ordernum =
ordernum;
460 rbu_data.dma_alloc = dma_alloc;
463 pr_debug(
"Not enough memory for image update:"
464 "size = %ld\n", size);
479 if (rbu_data.num_packets == 0) {
480 pr_debug(
"read_packet_data: no packets written\n");
482 goto read_rbu_data_exit;
485 if (pos > rbu_data.imagesize) {
489 goto read_rbu_data_exit;
492 bytes_left = rbu_data.imagesize -
pos;
493 data_length =
min(bytes_left, count);
495 if ((retval = packet_read_list(ptempBuf, &data_length)) < 0)
496 goto read_rbu_data_exit;
498 if ((pos + count) > rbu_data.imagesize) {
499 rbu_data.packet_read_count = 0;
509 static ssize_t read_rbu_mono_data(
char *buffer, loff_t pos,
size_t count)
512 if ((rbu_data.image_update_buffer ==
NULL) ||
513 (rbu_data.bios_image_size == 0)) {
514 pr_debug(
"read_rbu_data_mono: image_update_buffer %p ,"
515 "bios_image_size %lu\n",
516 rbu_data.image_update_buffer,
517 rbu_data.bios_image_size);
522 rbu_data.image_update_buffer, rbu_data.bios_image_size);
527 char *buffer, loff_t pos,
size_t count)
531 spin_lock(&rbu_data.lock);
533 if (!
strcmp(image_type,
"mono"))
534 ret_count = read_rbu_mono_data(buffer, pos, count);
535 else if (!
strcmp(image_type,
"packet"))
536 ret_count = read_packet_data(buffer, pos, count);
538 pr_debug(
"read_rbu_data: invalid image type specified\n");
540 spin_unlock(&rbu_data.lock);
544 static void callbackfn_rbu(
const struct firmware *
fw,
void *context)
546 rbu_data.entry_created = 0;
554 spin_lock(&rbu_data.lock);
555 if (!
strcmp(image_type,
"mono")) {
556 if (!img_update_realloc(fw->
size))
557 memcpy(rbu_data.image_update_buffer,
559 }
else if (!
strcmp(image_type,
"packet")) {
565 if (packetize_data(fw->
data, fw->
size))
573 pr_debug(
"invalid image type specified.\n");
574 spin_unlock(&rbu_data.lock);
581 char *buffer, loff_t pos,
size_t count)
585 size =
scnprintf(buffer, count,
"%s\n", image_type);
591 char *buffer, loff_t pos,
size_t count)
596 spin_lock(&rbu_data.lock);
600 for (i = 0; i <
count; ++
i)
601 if (buffer[i] ==
'\n' || buffer[i] ==
' ') {
606 buffer[
count] =
'\0';
608 if (
strstr(buffer,
"mono"))
609 strcpy(image_type,
"mono");
610 else if (
strstr(buffer,
"packet"))
611 strcpy(image_type,
"packet");
612 else if (
strstr(buffer,
"init")) {
620 if (!rbu_data.entry_created) {
621 spin_unlock(&rbu_data.lock);
628 "dell_rbu:%s request_firmware_nowait"
629 " failed %d\n", __func__, rc);
632 rbu_data.entry_created = 1;
634 spin_lock(&rbu_data.lock);
638 spin_unlock(&rbu_data.lock);
645 spin_unlock(&rbu_data.lock);
652 char *buffer, loff_t pos,
size_t count)
656 spin_lock(&rbu_data.lock);
657 size =
scnprintf(buffer, count,
"%lu\n", rbu_data.packetsize);
658 spin_unlock(&rbu_data.lock);
665 char *buffer, loff_t pos,
size_t count)
668 spin_lock(&rbu_data.lock);
670 sscanf(buffer,
"%lu", &temp);
671 if (temp < 0xffffffff)
672 rbu_data.packetsize =
temp;
674 spin_unlock(&rbu_data.lock);
679 .attr = {.name =
"data", .mode = 0444},
680 .read = read_rbu_data,
684 .attr = {.name =
"image_type", .mode = 0644},
685 .read = read_rbu_image_type,
686 .write = write_rbu_image_type,
690 .attr = {.name =
"packet_size", .mode = 0644},
691 .read = read_rbu_packet_size,
692 .write = write_rbu_packet_size,
695 static int __init dcdrbu_init(
void)
701 rbu_device = platform_device_register_simple(
"dell_rbu", -1,
NULL, 0);
702 if (IS_ERR(rbu_device)) {
704 "dell_rbu:%s:platform_device_register_simple "
705 "failed\n", __func__);
706 return PTR_ERR(rbu_device);
716 &rbu_packet_size_attr);
720 rbu_data.entry_created = 0;
732 static __exit void dcdrbu_exit(
void)
734 spin_lock(&rbu_data.lock);
737 spin_unlock(&rbu_data.lock);