Changeset 1626

Show
Ignore:
Timestamp:
11/19/02 21:14:39 (11 years ago)
Author:
mds
Message:

cleanup, handle reservation cancellation,

skip non-threshold sensors

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/kernel/chips/bmcsensors.c

    r1615 r1626  
    3636static unsigned short normal_i2c[] = { SENSORS_I2C_END }; 
    3737static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; 
    38 static unsigned int normal_isa[] = { 0, SENSORS_ISA_END }; 
     38static unsigned int normal_isa[] = { SENSORS_ISA_END }; 
    3939static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; 
    4040 
     
    7777static void bmcsensors_init_client(struct i2c_client *client); 
    7878static int bmcsensors_find(int *address); 
     79static void bmcsensors_reserve_sdr(void); 
    7980 
    8081 
     
    163164static long msgid;              /* message ID */ 
    164165static u16 resid; 
    165  
    166 enum states {STATE_INIT, STATE_RESERVE, STATE_SDR, STATE_SDRPARTIAL, STATE_READING, STATE_DONE}; 
     166static u16 nextrecord; 
     167int errorcount; 
     168 
     169enum states {STATE_INIT, STATE_RESERVE, STATE_SDR, STATE_SDRPARTIAL, 
     170             STATE_READING, STATE_UNCANCEL, STATE_DONE}; 
    167171int state; 
    168172static int receive_counter; 
     
    184188#define STYPE_FAN       0x04 
    185189 
    186 /* get rid of this ***************/ 
    187 #define STYPE_MAX       0x29            /* the last sensor type we are interested in */ 
    188 static u8 bmcs_count[STYPE_MAX + 1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 
    189 static const u8 bmcs_max[STYPE_MAX + 1] = { 
    190 0, 10, 10, 10, 10, 0, 0, 0}; /* more zeros*/ 
     190/* do we really need maximums per-type? */ 
     191#define STYPE_MAX       4               /* the last sensor type we are interested in */ 
     192static u8 bmcs_count[STYPE_MAX + 1] = {0,0,0,0,0}; 
     193static const u8 bmcs_max[STYPE_MAX + 1] = {0, 20, 20, 20, 20}; 
    191194 
    192195/************************************/ 
     
    293296                printk(KERN_INFO "bmcsensors.o: sensor %d: using %s for upper limit\n", 
    294297                        i, threshold_text[sdrd[i].lim1]); 
    295 /* 
     298#ifdef DEBUG 
    296299        else 
    297300                printk(KERN_INFO "bmcsensors.o: sensor %d: no readable upper limit\n", i); 
    298 */ 
     301#endif 
    299302        if(sdrd[i].lim2 >= 0) 
    300303                printk(KERN_INFO "bmcsensors.o: sensor %d: using %s for lower limit\n", 
    301304                        i, threshold_text[sdrd[i].lim2]); 
    302 /* 
     305#ifdef DEBUG 
    303306        else 
    304307                printk(KERN_INFO "bmcsensors.o: sensor %d: no readable lower limit\n", i); 
    305 */ 
     308#endif 
    306309} 
    307310 
    308311/* After we have received all the SDR entries and picked out the ones 
    309    we are interested in, build a table of the /proc entries and register. 
     312   we are interested in, build a table of the /proc entries and register with i2c. 
    310313*/ 
    311314static void bmcsensors_build_proc_table() 
     
    365368                        sdrd[i].m, sdrd[i].b,sdrd[i].k & 0xf, sdrd[i].k >> 4, 
    366369                        sdrd[i].capab, sdrd[i].thresh_mask); 
    367                 if(sdrd[i].id_length) { 
     370                if(sdrd[i].id_length > 0) { 
    368371                        ipmi_sprintf(id, sdrd[i].id, sdrd[i].string_type, sdrd[i].id_length); 
    369372                        printk(KERN_INFO "bmcsensors.o: sensors.conf: label %s \"%s\"\n", 
     
    372375                bmcsensors_select_thresholds(i); 
    373376                if(sdrd[i].linear != 0) { 
    374                         printk(KERN_INFO "bmcsensors.o: sensor %d: nonlinear function 0x%.2x unsupported\n", 
    375                                 i, sdrd[i].linear); 
     377                        printk(KERN_INFO 
     378                               "bmcsensors.o: sensor %d: nonlinear function 0x%.2x unsupported, expect bad results\n", 
     379                               i, sdrd[i].linear); 
    376380                } 
    377381                if((sdrd[i].format & 0x03) == 0x02) { 
    378                         printk(KERN_INFO "bmcsensors.o: sensor %d: 1's complement format unsupported\n", 
     382                        printk(KERN_INFO 
     383                               "bmcsensors.o: sensor %d: 1's complement format unsupported, expect bad results\n", 
    379384                                i); 
    380385                } else if((sdrd[i].format & 0x03) == 0x03) { 
    381                         printk(KERN_INFO "bmcsensors.o: sensor %d: threshold sensor only, no readings available", 
     386                        printk(KERN_INFO 
     387                               "bmcsensors.o: sensor %d: threshold sensor only, no readings available", 
    382388                                i); 
    383389                } 
     
    390396 
    391397        if ((i = i2c_register_entry(&bmc_client, "bmc", 
    392                                         bmcsensors_dir_table, 
    393                                         THIS_MODULE)) < 0) { 
     398                                    bmcsensors_dir_table, 
     399                                    THIS_MODULE)) < 0) { 
    394400                printk(KERN_INFO "bmcsensors.o: i2c registration failed.\n"); 
    395401                kfree(bmcsensors_dir_table); 
     
    426432                return STATE_DONE; 
    427433        } 
    428         bmcsensors_get_reading(&bmc_client, receive_counter); /* don't really need to pass client */ 
     434        /* don't really need to pass client */ 
     435        bmcsensors_get_reading(&bmc_client, receive_counter); 
    429436        return STATE_READING;  
    430437} 
    431438 
    432 /* Process a SDR response */ 
     439/* Process an SDR response, save the SDR's we like in the sdrd table */ 
    433440static int bmcsensors_rcv_sdr_msg(struct ipmi_msg *msg, int state) 
    434441{ 
    435         u16 record, nextrecord; 
    436         int version, type, length, owner, lun, number, entity, instance, init; 
     442        u16 record; 
     443        int type, length, owner, lun, number, entity, instance, init; 
    437444        int stype, code; 
    438445        int id_length; 
     
    441448        struct ipmi_msg txmsg; 
    442449        unsigned char * data; 
     450        u8 id[SDR_MAX_UNPACKED_ID_LENGTH]; 
    443451 
    444452 
     
    450458                        return STATE_DONE; 
    451459                } 
     460#ifdef DEBUG 
    452461                printk(KERN_INFO "bmcsensors.o: Reducing SDR request size to %d\n", ipmi_sdr_partial_size); 
     462#endif 
    453463                bmcsensors_get_sdr(resid, 0, 0); 
    454464                return STATE_SDR; 
     
    477487 
    478488        nextrecord = (data[2] << 8) | data[1]; 
    479         version = data[5]; 
    480489        type = data[6]; 
    481490        if(type == 1 || type == 2) {            /* known SDR type */ 
    482491/* 
     492                version = data[5]; 
    483493                owner = data[8]; 
    484494                lun = data[9]; 
     
    487497*/ 
    488498                stype = data[15]; 
    489  
    490499                if(stype <= STYPE_MAX) {        /* known sensor type */ 
    491500                        if(bmcs_count[stype] >= bmcs_max[stype]) { 
    492                                 if(bmcs_max[stype] > 0) { 
    493                                         printk(KERN_INFO "bmcsensors.o: Limit of %d exceeded for sensor type 0x%x\n", bmcs_max[stype], stype); 
     501                                if(bmcs_max[stype] > 0) 
     502                                        printk(KERN_INFO 
     503                                               "bmcsensors.o: Limit of %d exceeded for sensor type 0x%x\n", 
     504                                               bmcs_max[stype], stype); 
    494505#ifdef DEBUG 
     506                                else 
     507                                        printk(KERN_INFO 
     508                                               "bmcsensors.o: Ignoring unsupported sensor type 0x%x\n", 
     509                                               stype); 
     510#endif 
     511                        } else if(sdrd_count >= MAX_SDR_ENTRIES) { 
     512                                printk(KERN_INFO 
     513                                       "bmcsensors.o: Limit of %d exceeded for total sensors\n", 
     514                                       MAX_SDR_ENTRIES); 
     515                                nextrecord = 0xffff; 
     516                        } else if(data[16] != 0x01) { 
     517                                if(type == 1) 
     518                                        ipmi_sprintf(id, &data[51], data[50] >> 6, data[50] & 0x1f); 
     519                                else 
     520                                        ipmi_sprintf(id, &data[35], data[34] >> 6, data[34] & 0x1f); 
     521                                printk(KERN_INFO 
     522                                       "bmcsensors.o: skipping non-threshold sensor \"%s\"\n", 
     523                                       id); 
     524                        } else { 
     525                                /* add entry to sdrd table */ 
     526                                sdrd[sdrd_count].stype = stype; 
     527                                sdrd[sdrd_count].number = data[10]; 
     528                                sdrd[sdrd_count].capab = data[14]; 
     529                                sdrd[sdrd_count].thresh_mask = (((u16) data[22]) << 8) | data[21]; 
     530                                if(type == 1) { 
     531                                        sdrd[sdrd_count].format = data[24] >> 6; 
     532                                        sdrd[sdrd_count].linear = data[26] & 0x7f; 
     533                                        sdrd[sdrd_count].m = data[27]; 
     534                                        sdrd[sdrd_count].m |= ((u16) (data[28] & 0xc0)) << 2; 
     535                                        if(sdrd[sdrd_count].m & 0x0200) 
     536                                                sdrd[sdrd_count].m |= 0xfc00;   /* sign extend */ 
     537                                        sdrd[sdrd_count].b = data[29]; 
     538                                        sdrd[sdrd_count].b |= ((u16) (data[30] & 0xc0)) << 2; 
     539                                        if(sdrd[sdrd_count].b & 0x0200) 
     540                                                sdrd[sdrd_count].b |= 0xfc00;   /* sign extend */ 
     541                                        sdrd[sdrd_count].k = data[32]; 
     542                                        sdrd[sdrd_count].nominal = data[34]; 
     543                                        for(i = 0; i < SDR_LIMITS; i++)         /* assume readable */ 
     544                                                sdrd[sdrd_count].limits[i] = data[39 + i]; 
     545                                        sdrd[sdrd_count].string_type = data[50] >> 6; 
     546                                        id_length = data[50] & 0x1f; 
     547                                        memcpy(sdrd[sdrd_count].id, &data[51], id_length); 
     548                                        sdrd[sdrd_count].id_length = id_length; 
    495549                                } else { 
    496                                         printk(KERN_INFO "bmcsensors.o: Ignoring unsupported sensor type 0x%x\n", stype); 
    497 #endif 
     550                                        sdrd[sdrd_count].m = 1; 
     551                                        sdrd[sdrd_count].b = 0; 
     552                                        sdrd[sdrd_count].k = 0; 
     553                                        sdrd[sdrd_count].string_type = data[34] >> 6; 
     554                                        id_length = data[34] & 0x1f; 
     555                                        if(id_length > 0) 
     556                                                memcpy(sdrd[sdrd_count].id, &data[35], id_length); 
     557                                        sdrd[sdrd_count].id_length = id_length; 
     558                                        /* limits?? */ 
    498559                                } 
    499                         } else { 
    500                                 if(sdrd_count >= MAX_SDR_ENTRIES) { 
    501                                         printk(KERN_INFO "bmcsensors.o: Limit of %d exceeded for total sensors\n", MAX_SDR_ENTRIES); 
    502                                 } else { 
    503                                         /* add SDR database entry */ 
    504                                         sdrd[sdrd_count].stype = stype; 
    505                                         sdrd[sdrd_count].number = data[10]; 
    506                                         sdrd[sdrd_count].capab = data[14]; 
    507                                         sdrd[sdrd_count].thresh_mask = (data[22] << 8) | data[21]; 
    508                                         if(type == 1) { 
    509                                                 sdrd[sdrd_count].format = data[24] >> 6; 
    510                                                 sdrd[sdrd_count].linear = data[26] & 0x7f; 
    511                                                 sdrd[sdrd_count].m = data[27]; 
    512                                                 sdrd[sdrd_count].m |= ((u16) (data[28] & 0xc0)) << 2; 
    513                                                 if(sdrd[sdrd_count].m & 0x0200) 
    514                                                         sdrd[sdrd_count].m |= 0xfc00;   /* sign extend */ 
    515                                                 sdrd[sdrd_count].b = data[29]; 
    516                                                 sdrd[sdrd_count].b |= ((u16) (data[30] & 0xc0)) << 2; 
    517                                                 if(sdrd[sdrd_count].b & 0x0200) 
    518                                                         sdrd[sdrd_count].b |= 0xfc00;   /* sign extend */ 
    519                                                 sdrd[sdrd_count].k = data[32]; 
    520                                                 sdrd[sdrd_count].nominal = data[34]; 
    521                                                 for(i = 0; i < SDR_LIMITS; i++)         /* assume readable */ 
    522                                                         sdrd[sdrd_count].limits[i] = data[39 + i]; 
    523                                                 sdrd[sdrd_count].string_type = data[50] >> 6; 
    524                                                 id_length = data[50] & 0x1f; 
    525                                                 if(id_length > 0) 
    526                                                         memcpy(sdrd[sdrd_count].id, &data[51], id_length); 
    527                                                 sdrd[sdrd_count].id_length = id_length; 
    528                                         } else { 
    529                                                 sdrd[sdrd_count].m = 1; 
    530                                                 sdrd[sdrd_count].b = 0; 
    531                                                 sdrd[sdrd_count].k = 0; 
    532                                                 sdrd[sdrd_count].string_type = data[34] >> 6; 
    533                                                 id_length = data[34] & 0x1f; 
    534                                                 if(id_length > 0) 
    535                                                         memcpy(sdrd[sdrd_count].id, &data[35], id_length); 
    536                                                 sdrd[sdrd_count].id_length = id_length; 
    537                                                 /* limits?? */ 
    538                                         } 
    539                                         bmcs_count[stype]++; 
    540                                         sdrd_count++; 
    541                                 } 
     560                                bmcs_count[stype]++; 
     561                                sdrd_count++; 
    542562                        } 
    543563                } 
     564#ifdef DEBUG 
     565        /* peek at the other SDR types */ 
     566        } else if(type == 0x10 || type == 0x11 || type == 0x12) { 
     567                ipmi_sprintf(id, data + 19, data[18]>>6, data[18] & 0x1f); 
     568                if(type == 0x10) { 
     569                        printk(KERN_INFO "bmcsensors.o: Generic Device acc=0x%x; slv=0x%x; lun=0x%x; type=0x%x; \"%s\"\n", 
     570                                data[8], data[9], data[10], data[13], id); 
     571                else if(type == 0x11) { 
     572                        printk(KERN_INFO "bmcsensors.o: FRU Device acc=0x%x; slv=0x%x; log=0x%x; ch=0x%x; type=0x%x; \"%s\"\n", 
     573                                data[8], data[9], data[10], data[11], data[13], id); 
     574                } else { 
     575                        printk(KERN_INFO "bmcsensors.o: Mgmt Ctllr Device slv=0x%x; \"%s\"\n", 
     576                                data[8], id); 
     577                } 
     578        } else if(type == 0x14) { 
     579                printk(KERN_INFO "bmcsensors.o: Message Channel Info Records:\n"); 
     580                for(i = 0; i < 8; i++) { 
     581                        printk(KERN_INFO "bmcsensors.o: Channel %d info 0x%x\n", 
     582                                i, data[9 + i]); 
     583                } 
     584        } else { 
     585                printk(KERN_INFO "bmcsensors.o: Skipping SDR type 0x%x\n", type); 
     586#endif 
    544587        } 
    545588                         
    546589        if(nextrecord == 0xFFFF) { 
    547                 rstate = STATE_READING; 
    548590                if(sdrd_count == 0) { 
    549591                        printk(KERN_INFO "bmcsensors.o: No recognized sensors found.\n"); 
     592                        rstate = STATE_DONE; 
     593                        /* unregister?? */ 
    550594                } else { 
    551                         printk(KERN_INFO "bmcsensors.o: found %d temp, %d volt, %d current, %d fan sensors\n", 
    552 bmcs_count[1], bmcs_count[2], bmcs_count[3], bmcs_count[4]); 
    553595                        bmcsensors_build_proc_table(); 
     596                        rstate = STATE_READING; 
    554597                } 
    555598        } else { 
     
    566609                case STATE_INIT: 
    567610                case STATE_RESERVE: 
    568                         resid = (msg->data[2] << 8) || msg->data[1]; 
     611                        resid = (((u16)msg->data[2]) << 8) || msg->data[1]; 
     612#ifdef DEBUG 
     613                        printk(KERN_INFO "bmcsensors.o: Got first resid 0x%.4x\n", resid); 
     614#endif 
    569615                        bmcsensors_get_sdr(resid, 0, 0); 
    570616                        state = STATE_SDR; 
     
    580626                        break; 
    581627 
     628                case STATE_UNCANCEL: 
     629                        resid = (((u16)msg->data[2]) << 8) || msg->data[1]; 
     630#ifdef DEBUG 
     631                        printk(KERN_INFO "bmcsensors.o: Got new resid 0x%.4x\n", resid); 
     632#endif 
     633                        rx_msg_data_offset = 0; 
     634                        bmcsensors_get_sdr(resid, nextrecord, 0); 
     635                        state = STATE_SDR; 
     636                        break; 
     637 
    582638                case STATE_DONE: 
    583639                        break; 
     
    593649                                   void * handler_data) 
    594650{ 
    595         if (msg->msg.data[0] != 0 && msg->msg.data[0] != 0xca) { 
    596                 printk(KERN_ERR "BMCsensors response: Error %x on cmd %x; state = %d; probably fatal.\n", 
    597                        msg->msg.data[0], msg->msg.cmd, state); 
     651        if(state == STATE_SDR && msg->msg.data[0] == 0xc5) { 
     652                /* )(*&@(*&#@$ reservation cancelled, get new resid */ 
     653                if(errorcount++ > 200) { 
     654                        printk(KERN_ERR 
     655                               "bmcsensors.o: Too many reservations cancelled, giving up\n"); 
     656                        state = STATE_DONE; 
     657                } else { 
     658                        bmcsensors_reserve_sdr(); 
     659                        state = STATE_UNCANCEL; 
     660                } 
     661        } else if (msg->msg.data[0] != 0 && msg->msg.data[0] != 0xca) { 
     662                printk(KERN_ERR 
     663                       "bmcsensors.o: Error 0x%x on cmd 0x%x/0x%x; state = %d; probably fatal.\n", 
     664                       msg->msg.data[0], msg->msg.netfn & 0xfe, msg->msg.cmd, state); 
    598665        } else { 
    599666                bmcsensors_rcv_msg(&(msg->msg)); 
     
    611678                       msg->cmd); 
    612679#endif 
    613 /* 
    614         bmcclient_i2c_send_message(&bmc_client, msgid++, msg); 
    615 */ 
    616680        bmc_client.adapter->algo->slave_send((struct i2c_adapter *) &bmc_client, 
    617681                                             (char *) msg, msgid++);