50
50
MODULE_AUTHOR ("Abhay Salunke <abhay_salunke@dell.com>" );
51
51
MODULE_DESCRIPTION ("Driver for updating BIOS image on DELL systems" );
52
52
MODULE_LICENSE ("GPL" );
53
- MODULE_VERSION ("2 .0" );
53
+ MODULE_VERSION ("3 .0" );
54
54
55
55
#define BIOS_SCAN_LIMIT 0xffffffff
56
56
#define MAX_IMAGE_LENGTH 16
@@ -62,15 +62,16 @@ static struct _rbu_data {
62
62
int dma_alloc ;
63
63
spinlock_t lock ;
64
64
unsigned long packet_read_count ;
65
- unsigned long packet_write_count ;
66
65
unsigned long num_packets ;
67
66
unsigned long packetsize ;
67
+ unsigned long imagesize ;
68
68
int entry_created ;
69
69
} rbu_data ;
70
70
71
71
static char image_type [MAX_IMAGE_LENGTH + 1 ] = "mono" ;
72
72
module_param_string (image_type , image_type , sizeof (image_type ), 0 );
73
- MODULE_PARM_DESC (image_type , "BIOS image type. choose- mono or packet" );
73
+ MODULE_PARM_DESC (image_type ,
74
+ "BIOS image type. choose- mono or packet or init" );
74
75
75
76
struct packet_data {
76
77
struct list_head list ;
@@ -88,55 +89,13 @@ static dma_addr_t dell_rbu_dmaaddr;
88
89
static void init_packet_head (void )
89
90
{
90
91
INIT_LIST_HEAD (& packet_data_head .list );
91
- rbu_data .packet_write_count = 0 ;
92
92
rbu_data .packet_read_count = 0 ;
93
93
rbu_data .num_packets = 0 ;
94
94
rbu_data .packetsize = 0 ;
95
+ rbu_data .imagesize = 0 ;
95
96
}
96
97
97
- static int fill_last_packet (void * data , size_t length )
98
- {
99
- struct list_head * ptemp_list ;
100
- struct packet_data * packet = NULL ;
101
- int packet_count = 0 ;
102
-
103
- pr_debug ("fill_last_packet: entry \n" );
104
-
105
- if (!rbu_data .num_packets ) {
106
- pr_debug ("fill_last_packet: num_packets=0\n" );
107
- return - ENOMEM ;
108
- }
109
-
110
- packet_count = rbu_data .num_packets ;
111
-
112
- ptemp_list = (& packet_data_head .list )-> prev ;
113
-
114
- packet = list_entry (ptemp_list , struct packet_data , list );
115
-
116
- if ((rbu_data .packet_write_count + length ) > rbu_data .packetsize ) {
117
- pr_debug ("dell_rbu:%s: packet size data "
118
- "overrun\n" , __FUNCTION__ );
119
- return - EINVAL ;
120
- }
121
-
122
- pr_debug ("fill_last_packet : buffer = %p\n" , packet -> data );
123
-
124
- memcpy ((packet -> data + rbu_data .packet_write_count ), data , length );
125
-
126
- if ((rbu_data .packet_write_count + length ) == rbu_data .packetsize ) {
127
- /*
128
- * this was the last data chunk in the packet
129
- * so reinitialize the packet data counter to zero
130
- */
131
- rbu_data .packet_write_count = 0 ;
132
- } else
133
- rbu_data .packet_write_count += length ;
134
-
135
- pr_debug ("fill_last_packet: exit \n" );
136
- return 0 ;
137
- }
138
-
139
- static int create_packet (size_t length )
98
+ static int create_packet (void * data , size_t length )
140
99
{
141
100
struct packet_data * newpacket ;
142
101
int ordernum = 0 ;
@@ -186,9 +145,11 @@ static int create_packet(size_t length)
186
145
INIT_LIST_HEAD (& newpacket -> list );
187
146
list_add_tail (& newpacket -> list , & packet_data_head .list );
188
147
/*
189
- * packets have fixed size
148
+ * packets may not have fixed size
190
149
*/
191
- newpacket -> length = rbu_data .packetsize ;
150
+ newpacket -> length = length ;
151
+
152
+ memcpy (newpacket -> data , data , length );
192
153
193
154
pr_debug ("create_packet: exit \n" );
194
155
@@ -198,13 +159,37 @@ static int create_packet(size_t length)
198
159
static int packetize_data (void * data , size_t length )
199
160
{
200
161
int rc = 0 ;
162
+ int done = 0 ;
163
+ int packet_length ;
164
+ u8 * temp ;
165
+ u8 * end = (u8 * ) data + length ;
166
+ pr_debug ("packetize_data: data length %d\n" , length );
167
+ if (!rbu_data .packetsize ) {
168
+ printk (KERN_WARNING
169
+ "dell_rbu: packetsize not specified\n" );
170
+ return - EIO ;
171
+ }
201
172
202
- if (!rbu_data .packet_write_count ) {
203
- if ((rc = create_packet (length )))
173
+ temp = (u8 * ) data ;
174
+
175
+ /* packetize the hunk */
176
+ while (!done ) {
177
+ if ((temp + rbu_data .packetsize ) < end )
178
+ packet_length = rbu_data .packetsize ;
179
+ else {
180
+ /* this is the last packet */
181
+ packet_length = end - temp ;
182
+ done = 1 ;
183
+ }
184
+
185
+ if ((rc = create_packet (temp , packet_length )))
204
186
return rc ;
187
+
188
+ pr_debug ("%lu:%lu\n" , temp , (end - temp ));
189
+ temp += packet_length ;
205
190
}
206
- if (( rc = fill_last_packet ( data , length )))
207
- return rc ;
191
+
192
+ rbu_data . imagesize = length ;
208
193
209
194
return rc ;
210
195
}
@@ -243,7 +228,7 @@ static int do_packet_read(char *data, struct list_head *ptemp_list,
243
228
return bytes_copied ;
244
229
}
245
230
246
- static int packet_read_list (char * data , size_t * pread_length )
231
+ static int packet_read_list (char * data , size_t * pread_length )
247
232
{
248
233
struct list_head * ptemp_list ;
249
234
int temp_count = 0 ;
@@ -303,10 +288,9 @@ static void packet_empty_list(void)
303
288
newpacket -> ordernum );
304
289
kfree (newpacket );
305
290
}
306
- rbu_data .packet_write_count = 0 ;
307
291
rbu_data .packet_read_count = 0 ;
308
292
rbu_data .num_packets = 0 ;
309
- rbu_data .packetsize = 0 ;
293
+ rbu_data .imagesize = 0 ;
310
294
}
311
295
312
296
/*
@@ -425,7 +409,6 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
425
409
size_t bytes_left ;
426
410
size_t data_length ;
427
411
char * ptempBuf = buffer ;
428
- unsigned long imagesize ;
429
412
430
413
/* check to see if we have something to return */
431
414
if (rbu_data .num_packets == 0 ) {
@@ -434,22 +417,20 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
434
417
goto read_rbu_data_exit ;
435
418
}
436
419
437
- imagesize = rbu_data .num_packets * rbu_data .packetsize ;
438
-
439
- if (pos > imagesize ) {
420
+ if (pos > rbu_data .imagesize ) {
440
421
retval = 0 ;
441
422
printk (KERN_WARNING "dell_rbu:read_packet_data: "
442
423
"data underrun\n" );
443
424
goto read_rbu_data_exit ;
444
425
}
445
426
446
- bytes_left = imagesize - pos ;
427
+ bytes_left = rbu_data . imagesize - pos ;
447
428
data_length = min (bytes_left , count );
448
429
449
430
if ((retval = packet_read_list (ptempBuf , & data_length )) < 0 )
450
431
goto read_rbu_data_exit ;
451
432
452
- if ((pos + count ) > imagesize ) {
433
+ if ((pos + count ) > rbu_data . imagesize ) {
453
434
rbu_data .packet_read_count = 0 ;
454
435
/* this was the last copy */
455
436
retval = bytes_left ;
@@ -499,7 +480,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
499
480
}
500
481
501
482
static ssize_t read_rbu_data (struct kobject * kobj , char * buffer ,
502
- loff_t pos , size_t count )
483
+ loff_t pos , size_t count )
503
484
{
504
485
ssize_t ret_count = 0 ;
505
486
@@ -531,13 +512,18 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
531
512
memcpy (rbu_data .image_update_buffer ,
532
513
fw -> data , fw -> size );
533
514
} else if (!strcmp (image_type , "packet" )) {
534
- if (!rbu_data .packetsize )
535
- rbu_data .packetsize = fw -> size ;
536
- else if (rbu_data .packetsize != fw -> size ) {
515
+ /*
516
+ * we need to free previous packets if a
517
+ * new hunk of packets needs to be downloaded
518
+ */
519
+ packet_empty_list ();
520
+ if (packetize_data (fw -> data , fw -> size ))
521
+ /* Incase something goes wrong when we are
522
+ * in middle of packetizing the data, we
523
+ * need to free up whatever packets might
524
+ * have been created before we quit.
525
+ */
537
526
packet_empty_list ();
538
- rbu_data .packetsize = fw -> size ;
539
- }
540
- packetize_data (fw -> data , fw -> size );
541
527
} else
542
528
pr_debug ("invalid image type specified.\n" );
543
529
spin_unlock (& rbu_data .lock );
@@ -553,7 +539,7 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
553
539
}
554
540
555
541
static ssize_t read_rbu_image_type (struct kobject * kobj , char * buffer ,
556
- loff_t pos , size_t count )
542
+ loff_t pos , size_t count )
557
543
{
558
544
int size = 0 ;
559
545
if (!pos )
@@ -562,7 +548,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
562
548
}
563
549
564
550
static ssize_t write_rbu_image_type (struct kobject * kobj , char * buffer ,
565
- loff_t pos , size_t count )
551
+ loff_t pos , size_t count )
566
552
{
567
553
int rc = count ;
568
554
int req_firm_rc = 0 ;
@@ -621,25 +607,49 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
621
607
return rc ;
622
608
}
623
609
610
+ static ssize_t read_rbu_packet_size (struct kobject * kobj , char * buffer ,
611
+ loff_t pos , size_t count )
612
+ {
613
+ int size = 0 ;
614
+ if (!pos ) {
615
+ spin_lock (& rbu_data .lock );
616
+ size = sprintf (buffer , "%lu\n" , rbu_data .packetsize );
617
+ spin_unlock (& rbu_data .lock );
618
+ }
619
+ return size ;
620
+ }
621
+
622
+ static ssize_t write_rbu_packet_size (struct kobject * kobj , char * buffer ,
623
+ loff_t pos , size_t count )
624
+ {
625
+ unsigned long temp ;
626
+ spin_lock (& rbu_data .lock );
627
+ packet_empty_list ();
628
+ sscanf (buffer , "%lu" , & temp );
629
+ if (temp < 0xffffffff )
630
+ rbu_data .packetsize = temp ;
631
+
632
+ spin_unlock (& rbu_data .lock );
633
+ return count ;
634
+ }
635
+
624
636
static struct bin_attribute rbu_data_attr = {
625
- .attr = {
626
- .name = "data" ,
627
- .owner = THIS_MODULE ,
628
- .mode = 0444 ,
629
- },
637
+ .attr = {.name = "data" ,.owner = THIS_MODULE ,.mode = 0444 },
630
638
.read = read_rbu_data ,
631
639
};
632
640
633
641
static struct bin_attribute rbu_image_type_attr = {
634
- .attr = {
635
- .name = "image_type" ,
636
- .owner = THIS_MODULE ,
637
- .mode = 0644 ,
638
- },
642
+ .attr = {.name = "image_type" ,.owner = THIS_MODULE ,.mode = 0644 },
639
643
.read = read_rbu_image_type ,
640
644
.write = write_rbu_image_type ,
641
645
};
642
646
647
+ static struct bin_attribute rbu_packet_size_attr = {
648
+ .attr = {.name = "packet_size" ,.owner = THIS_MODULE ,.mode = 0644 },
649
+ .read = read_rbu_packet_size ,
650
+ .write = write_rbu_packet_size ,
651
+ };
652
+
643
653
static int __init dcdrbu_init (void )
644
654
{
645
655
int rc = 0 ;
@@ -657,6 +667,8 @@ static int __init dcdrbu_init(void)
657
667
658
668
sysfs_create_bin_file (& rbu_device -> dev .kobj , & rbu_data_attr );
659
669
sysfs_create_bin_file (& rbu_device -> dev .kobj , & rbu_image_type_attr );
670
+ sysfs_create_bin_file (& rbu_device -> dev .kobj ,
671
+ & rbu_packet_size_attr );
660
672
661
673
rc = request_firmware_nowait (THIS_MODULE , FW_ACTION_NOHOTPLUG ,
662
674
"dell_rbu" , & rbu_device -> dev , & context , callbackfn_rbu );
0 commit comments