*/
int sja1000p_chip_config(struct chip_t *chip)
{
+ int i;
+ unsigned char n, r;
+
if (sja1000p_enable_configuration(chip))
return -ENODEV;
can_write_reg(chip,CDR_PELICAN|chip->sja_cdr_reg,SJACDR);
/* Set driver output configuration */
can_write_reg(chip,chip->sja_ocr_reg,SJAOCR);
+
+ /* Simple check for chip presence */
+ for (i=0, n=0x5a; i<8; i++, n+=0xf) {
+ can_write_reg(chip,n,SJAACR0+i);
+ }
+ for (i=0, n=0x5a; i<8; i++, n+=0xf) {
+ r = n^can_read_reg(chip,SJAACR0+i);
+ if (r) {
+ CANMSG("sja1000p_chip_config: chip connection broken,"
+ " readback differ 0x%02x\n", r);
+ return -ENODEV;
+ }
+ }
+
if (sja1000p_extended_mask(chip,0x00000000, 0xffffffff))
return -ENODEV;
((flags & FRM_RTR) ? MSG_RTR : 0) |
((flags & FRM_FF) ? MSG_EXT : 0);
len = flags & FRM_DLC_M;
+ obj->rx_msg.length = len;
+ if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
for(i=0; i< len; i++) {
obj->rx_msg.data[i]=can_read_reg(chip,datastart+i);
}
- obj->rx_msg.length = len;
canque_filter_msg2edges(obj->qends, &obj->rx_msg);
int i=0;
unsigned int id;
int status;
+ int len;
/* Wait until Transmit Buffer Status is released */
while ( !((status=can_read_reg(chip, SJASR)) & SR_TBS) &&
return -EIO;
}
}
- msg->length &= FRM_DLC_M;
+ len = msg->length;
+ if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
+ /* len &= FRM_DLC_M; ensured by above condition already */
can_write_reg(chip, ((msg->flags&MSG_EXT)?FRM_FF:0) |
- ((msg->flags & MSG_RTR) ? FRM_RTR : 0) |
- msg->length, SJAFRM);
+ ((msg->flags & MSG_RTR) ? FRM_RTR : 0) | len, SJAFRM);
if(msg->flags&MSG_EXT) {
id=msg->id<<3;
can_write_reg(chip, id & 0xff, SJAID3);
can_write_reg(chip, id & 0xff, SJAID1);
id >>= 8;
can_write_reg(chip, id, SJAID0);
- for(i=0; i < msg->length; i++) {
+ for(i=0; i < len; i++) {
can_write_reg(chip, msg->data[i], SJADATE+i);
}
} else {
id=msg->id<<5;
can_write_reg(chip, (id >> 8) & 0xff, SJAID0);
can_write_reg(chip, id & 0xff, SJAID1);
- for(i=0; i < msg->length; i++) {
+ for(i=0; i < len; i++) {
can_write_reg(chip, msg->data[i], SJADATS+i);
}
}
int cmd;
if(obj->tx_slot){
+ /* Do local transmitted message distribution if enabled */
+ if (processlocal){
+ obj->tx_slot->msg.flags |= MSG_LOCAL;
+ canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
+ }
+ /* Free transmitted slot */
canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
obj->tx_slot=NULL;
}
irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
int irq_register, status, error_code;
- int static retransmitted=0; /* FIXME - should go into chip struct */
struct chip_t *chip=(struct chip_t *)dev_id;
struct msgobj_t *obj=chip->msgobj[0];
obj->ret= -ENXIO;
/* no such device or address - no ACK received */
}
- if(retransmitted++>MAX_RETR) {
+ if(obj->tx_retry_cnt++>MAX_RETR) {
can_write_reg(chip, CMR_AT, SJACMR); // cancel any transmition
- retransmitted = 0;
+ obj->tx_retry_cnt = 0;
}
if(status&SR_BS) {
CANMSG("bus-off, resetting sja1000p\n");
}
} else {
- retransmitted=0;
+ obj->tx_retry_cnt=0;
}
return IRQ_HANDLED;
while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
clear_bit(OBJ_TX_REQUEST,&obj->flags);
- if (can_read_reg(chip, SJASR) & SR_TBS)
+ if (can_read_reg(chip, SJASR) & SR_TBS){
+ obj->tx_retry_cnt=0;
sja1000p_irq_write_handler(chip, obj);
+ }
clear_bit(OBJ_TX_LOCK,&obj->flags);
if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;