[PATCH] bmcsensors / get partial SDR

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Here's another patch I made to get bmcsensors working on our dual-core Xeon
ATCA carrier (Kontron 8020).  

When retrieving partial buffers for an SDR, the request for the last buffer
would return completion code 0xCA (cannot return number of requested data
bytes), causing the code to half its buffer size, try again, and ultimately
give up.  To get around this, I modified bmcsensors_get_sdr() and
bmcsensors_rcv_sdr_msg() to never request more than the known number of
remaining bytes.


--- old/bmcsensors.c	2007-01-10 11:13:47.353446400 -0700
+++ new/bmcsensors.c	2007-01-26 16:12:50.925455100 -0700
@@ -72,5 +72,5 @@
 			int ctl_name, int *nrels_mag, long *results);
 #endif
-static void bmcsensors_get_sdr(u16 resid, u16 record, u8 offset);
+static void bmcsensors_get_sdr(u16 resid, u16 record, u8 offset, u8 count);
 static void bmcsensors_get_reading(struct i2c_client *client, int i);
 
@@ -459,4 +459,5 @@
 	unsigned char * data;
 	u8 id[SDR_MAX_UNPACKED_ID_LENGTH];
+	int bytesleft;
 
 
@@ -472,5 +473,5 @@
 		printk(KERN_INFO "bmcsensors.o: Reducing SDR request size to
%d\n", ipmi_sdr_partial_size);
 #endif
-		bmcsensors_get_sdr(0, 0, 0);
+		bmcsensors_get_sdr(0, 0, 0, 0);
 		return STATE_SDR;
 	}
@@ -483,14 +484,20 @@
 			rx_msg_data_offset += ipmi_sdr_partial_size;
 		}
-		if(rx_msg_data_offset > rx_msg_data[7] + 7) {
-			/* got last chunk */
-			rx_msg_data_offset =  0;
-			data = rx_msg_data;
-		} else {
+
+		/* compute total bytes remaining based on sensor record
bytes remaining */
+		bytesleft = (int)rx_msg_data[7] + 8 - rx_msg_data_offset;
+
+		if (bytesleft > 0) {
 			/* get more */
 			record = (rx_msg_data[4] << 8) | rx_msg_data[3];
-			bmcsensors_get_sdr(resid, record, rx_msg_data_offset
- 3);
+			bmcsensors_get_sdr(resid, record, rx_msg_data_offset
- 3, bytesleft);
 			return STATE_SDR;
 		}
+		else {
+			/* got last chunk */
+			rx_msg_data_offset = 0;
+			data = rx_msg_data;
+		}
+
 	} else {
 		data = msg->data;	/* got it in one chunk */
@@ -631,5 +638,5 @@
 	} else {
 
-		bmcsensors_get_sdr(0, nextrecord, 0);
+		bmcsensors_get_sdr(0, nextrecord, 0, 0);
 	}
 	return rstate;
@@ -647,5 +654,5 @@
 			printk(KERN_DEBUG "bmcsensors.o: Got first resid
0x%.4x\n", resid);
 #endif
-			bmcsensors_get_sdr(0, 0, 0);
+			bmcsensors_get_sdr(0, 0, 0, 0);
 			state = STATE_SDR;
 			break;
@@ -677,5 +684,5 @@
 #endif
 			rx_msg_data_offset = 0;
-			bmcsensors_get_sdr(0, nextrecord, 0);
+			bmcsensors_get_sdr(0, nextrecord, 0, 0);
 			state = STATE_SDR;
 			break;
@@ -755,12 +762,17 @@
 
 /* Componse and send a "get SDR" message */
-static void bmcsensors_get_sdr(u16 res_id, u16 record, u8 offset)
+static void bmcsensors_get_sdr(u16 res_id, u16 record, u8 offset, u8 count)
 {
 #ifdef DEBUG
-	printk(KERN_DEBUG "bmcsensors.o: Get SDR 0x%x 0x%x 0x%x\n",
-		       res_id, record, offset);
+	printk(KERN_DEBUG "bmcsensors.o: Get SDR 0x%x 0x%x 0x%x 0x%x\n",
+		       res_id, record, offset, count);
 #endif
 	tx_message.netfn = IPMI_NETFN_STORAGE;
 	tx_message.cmd = IPMI_GET_SDR;
+
+	/* Reset count to default value if necessary */
+	if (count == 0 || count > ipmi_sdr_partial_size)
+		count = ipmi_sdr_partial_size;
+
 	tx_message.data_len = 6;
 	tx_message.data = tx_msg_data;
@@ -770,5 +782,5 @@
 	tx_msg_data[3] = record >> 8;
 	tx_msg_data[4] = offset;
-	tx_msg_data[5] = ipmi_sdr_partial_size;
+	tx_msg_data[5] = count;
 	bmcsensors_send_message(&tx_message);
 }


--------------------
Chuck Grant
Performance Software







[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux