Lines Matching refs:ssif_bmc
135 struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); in ssif_bmc_read() local
140 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_read()
141 while (!ssif_bmc->request_available) { in ssif_bmc_read()
142 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_read()
145 ret = wait_event_interruptible(ssif_bmc->wait_queue, in ssif_bmc_read()
146 ssif_bmc->request_available); in ssif_bmc_read()
149 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_read()
153 sizeof_field(struct ipmi_ssif_msg, len) + ssif_bmc->request.len, in ssif_bmc_read()
155 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_read()
159 sizeof_field(struct ipmi_ssif_msg, len) + ssif_bmc->request.len, in ssif_bmc_read()
161 memcpy(&msg, &ssif_bmc->request, count); in ssif_bmc_read()
162 ssif_bmc->request_available = false; in ssif_bmc_read()
163 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_read()
175 struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); in ssif_bmc_write() local
191 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_write()
192 while (ssif_bmc->response_in_progress) { in ssif_bmc_write()
193 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_write()
196 ret = wait_event_interruptible(ssif_bmc->wait_queue, in ssif_bmc_write()
197 !ssif_bmc->response_in_progress); in ssif_bmc_write()
200 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_write()
208 ret = (ssif_bmc->response_timer_inited) ? 0 : -EINVAL; in ssif_bmc_write()
212 del_timer(&ssif_bmc->response_timer); in ssif_bmc_write()
213 ssif_bmc->response_timer_inited = false; in ssif_bmc_write()
215 memcpy(&ssif_bmc->response, &msg, count); in ssif_bmc_write()
216 ssif_bmc->is_singlepart_read = (msg.len <= MAX_PAYLOAD_PER_TRANSACTION); in ssif_bmc_write()
218 ssif_bmc->response_in_progress = true; in ssif_bmc_write()
221 ssif_bmc->busy = false; in ssif_bmc_write()
224 memset(&ssif_bmc->request, 0, sizeof(struct ipmi_ssif_msg)); in ssif_bmc_write()
226 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_write()
233 struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); in ssif_bmc_open() local
236 spin_lock_irq(&ssif_bmc->lock); in ssif_bmc_open()
237 if (!ssif_bmc->running) in ssif_bmc_open()
238 ssif_bmc->running = 1; in ssif_bmc_open()
241 spin_unlock_irq(&ssif_bmc->lock); in ssif_bmc_open()
248 struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); in ssif_bmc_poll() local
251 poll_wait(file, &ssif_bmc->wait_queue, wait); in ssif_bmc_poll()
253 spin_lock_irq(&ssif_bmc->lock); in ssif_bmc_poll()
255 if (ssif_bmc->request_available) in ssif_bmc_poll()
258 spin_unlock_irq(&ssif_bmc->lock); in ssif_bmc_poll()
265 struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); in ssif_bmc_release() local
267 spin_lock_irq(&ssif_bmc->lock); in ssif_bmc_release()
268 ssif_bmc->running = 0; in ssif_bmc_release()
269 spin_unlock_irq(&ssif_bmc->lock); in ssif_bmc_release()
287 static void complete_response(struct ssif_bmc_ctx *ssif_bmc) in complete_response() argument
290 ssif_bmc->response.len = 0; in complete_response()
291 ssif_bmc->response_in_progress = false; in complete_response()
292 ssif_bmc->nbytes_processed = 0; in complete_response()
293 ssif_bmc->remain_len = 0; in complete_response()
294 ssif_bmc->busy = false; in complete_response()
295 memset(&ssif_bmc->part_buf, 0, sizeof(struct ssif_part_buffer)); in complete_response()
296 wake_up_all(&ssif_bmc->wait_queue); in complete_response()
301 struct ssif_bmc_ctx *ssif_bmc = from_timer(ssif_bmc, t, response_timer); in response_timeout() local
304 spin_lock_irqsave(&ssif_bmc->lock, flags); in response_timeout()
307 if (!ssif_bmc->response_in_progress) { in response_timeout()
309 ssif_bmc->busy = false; in response_timeout()
310 ssif_bmc->response_timer_inited = false; in response_timeout()
312 ssif_bmc->aborting = true; in response_timeout()
315 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in response_timeout()
319 static void handle_request(struct ssif_bmc_ctx *ssif_bmc) in handle_request() argument
322 ssif_bmc->busy = true; in handle_request()
324 ssif_bmc->request_available = true; in handle_request()
326 memset(&ssif_bmc->response, 0, sizeof(struct ipmi_ssif_msg)); in handle_request()
328 wake_up_all(&ssif_bmc->wait_queue); in handle_request()
331 if (!ssif_bmc->response_timer_inited) { in handle_request()
332 timer_setup(&ssif_bmc->response_timer, response_timeout, 0); in handle_request()
333 ssif_bmc->response_timer_inited = true; in handle_request()
335 mod_timer(&ssif_bmc->response_timer, jiffies + msecs_to_jiffies(RESPONSE_TIMEOUT)); in handle_request()
354 static void set_singlepart_response_buffer(struct ssif_bmc_ctx *ssif_bmc) in set_singlepart_response_buffer() argument
356 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in set_singlepart_response_buffer()
358 part->address = GET_8BIT_ADDR(ssif_bmc->client->addr); in set_singlepart_response_buffer()
359 part->length = (u8)ssif_bmc->response.len; in set_singlepart_response_buffer()
363 memcpy(&part->payload[0], &ssif_bmc->response.payload[0], part->length); in set_singlepart_response_buffer()
366 static void set_multipart_response_buffer(struct ssif_bmc_ctx *ssif_bmc) in set_multipart_response_buffer() argument
368 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in set_multipart_response_buffer()
371 part->address = GET_8BIT_ADDR(ssif_bmc->client->addr); in set_multipart_response_buffer()
379 ssif_bmc->nbytes_processed = 0; in set_multipart_response_buffer()
380 ssif_bmc->block_num = 0; in set_multipart_response_buffer()
383 ssif_bmc->remain_len = ssif_bmc->response.len - part_len; in set_multipart_response_buffer()
388 memcpy(&part->payload[2], &ssif_bmc->response.payload[0], part_len); in set_multipart_response_buffer()
396 if (ssif_bmc->remain_len <= MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION) { in set_multipart_response_buffer()
406 part->length = ssif_bmc->remain_len + 1; in set_multipart_response_buffer()
407 part_len = ssif_bmc->remain_len; in set_multipart_response_buffer()
408 ssif_bmc->block_num = 0xFF; in set_multipart_response_buffer()
409 part->payload[0] = ssif_bmc->block_num; in set_multipart_response_buffer()
419 part->payload[0] = ssif_bmc->block_num; in set_multipart_response_buffer()
420 ssif_bmc->block_num++; in set_multipart_response_buffer()
423 ssif_bmc->remain_len -= part_len; in set_multipart_response_buffer()
424 memcpy(&part->payload[1], ssif_bmc->response.payload + ssif_bmc->nbytes_processed, in set_multipart_response_buffer()
430 dev_err(&ssif_bmc->client->dev, "%s: Unexpected SMBus command 0x%x\n", in set_multipart_response_buffer()
435 ssif_bmc->nbytes_processed += part_len; in set_multipart_response_buffer()
460 static void handle_read_processed(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in handle_read_processed() argument
462 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in handle_read_processed()
467 else if (part->index == part->length && ssif_bmc->pec_support) in handle_read_processed()
475 static void handle_write_received(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in handle_write_received() argument
482 if (ssif_bmc->msg_idx < 1 || ssif_bmc->msg_idx > MAX_TRANSACTION) in handle_write_received()
485 if (ssif_bmc->msg_idx == 1) { in handle_write_received()
486 ssif_bmc->part_buf.length = *val; in handle_write_received()
487 ssif_bmc->part_buf.index = 0; in handle_write_received()
489 ssif_bmc->part_buf.payload[ssif_bmc->part_buf.index++] = *val; in handle_write_received()
492 ssif_bmc->msg_idx++; in handle_write_received()
495 static bool validate_request_part(struct ssif_bmc_ctx *ssif_bmc) in validate_request_part() argument
497 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in validate_request_part()
504 ssif_bmc->pec_support = false; in validate_request_part()
515 ssif_bmc->pec_support = true; in validate_request_part()
517 addr = GET_8BIT_ADDR(ssif_bmc->client->addr); in validate_request_part()
540 static void process_request_part(struct ssif_bmc_ctx *ssif_bmc) in process_request_part() argument
542 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in process_request_part()
548 ssif_bmc->request.len = part->length; in process_request_part()
549 memcpy(ssif_bmc->request.payload, part->payload, part->length); in process_request_part()
553 ssif_bmc->request.len = 0; in process_request_part()
558 len = ssif_bmc->request.len + part->length; in process_request_part()
561 dev_warn(&ssif_bmc->client->dev, in process_request_part()
564 ssif_bmc->aborting = true; in process_request_part()
566 memcpy(ssif_bmc->request.payload + ssif_bmc->request.len, in process_request_part()
568 ssif_bmc->request.len += part->length; in process_request_part()
573 dev_err(&ssif_bmc->client->dev, "%s: Unexpected SMBus command 0x%x\n", in process_request_part()
579 static void process_smbus_cmd(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in process_smbus_cmd() argument
582 ssif_bmc->part_buf.smbus_cmd = *val; in process_smbus_cmd()
583 ssif_bmc->msg_idx = 1; in process_smbus_cmd()
584 memset(&ssif_bmc->part_buf.payload[0], 0, MAX_PAYLOAD_PER_TRANSACTION); in process_smbus_cmd()
592 if (ssif_bmc->response_in_progress) in process_smbus_cmd()
593 complete_response(ssif_bmc); in process_smbus_cmd()
596 if (ssif_bmc->aborting) in process_smbus_cmd()
597 ssif_bmc->aborting = false; in process_smbus_cmd()
601 static void on_read_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in on_read_requested_event() argument
603 if (ssif_bmc->state == SSIF_READY || in on_read_requested_event()
604 ssif_bmc->state == SSIF_START || in on_read_requested_event()
605 ssif_bmc->state == SSIF_REQ_RECVING || in on_read_requested_event()
606 ssif_bmc->state == SSIF_RES_SENDING) { in on_read_requested_event()
607 dev_warn(&ssif_bmc->client->dev, in on_read_requested_event()
609 __func__, state_to_string(ssif_bmc->state)); in on_read_requested_event()
610 ssif_bmc->state = SSIF_ABORTING; in on_read_requested_event()
614 } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { in on_read_requested_event()
615 if (!supported_read_cmd(ssif_bmc->part_buf.smbus_cmd)) { in on_read_requested_event()
616 dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus read command=0x%x", in on_read_requested_event()
617 ssif_bmc->part_buf.smbus_cmd); in on_read_requested_event()
618 ssif_bmc->aborting = true; in on_read_requested_event()
621 if (ssif_bmc->aborting) in on_read_requested_event()
622 ssif_bmc->state = SSIF_ABORTING; in on_read_requested_event()
624 ssif_bmc->state = SSIF_RES_SENDING; in on_read_requested_event()
627 ssif_bmc->msg_idx = 0; in on_read_requested_event()
630 if (!ssif_bmc->response_in_progress || ssif_bmc->state == SSIF_ABORTING) { in on_read_requested_event()
635 if (ssif_bmc->is_singlepart_read) in on_read_requested_event()
636 set_singlepart_response_buffer(ssif_bmc); in on_read_requested_event()
638 set_multipart_response_buffer(ssif_bmc); in on_read_requested_event()
640 calculate_response_part_pec(&ssif_bmc->part_buf); in on_read_requested_event()
641 ssif_bmc->part_buf.index = 0; in on_read_requested_event()
642 *val = ssif_bmc->part_buf.length; in on_read_requested_event()
645 static void on_read_processed_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in on_read_processed_event() argument
647 if (ssif_bmc->state == SSIF_READY || in on_read_processed_event()
648 ssif_bmc->state == SSIF_START || in on_read_processed_event()
649 ssif_bmc->state == SSIF_REQ_RECVING || in on_read_processed_event()
650 ssif_bmc->state == SSIF_SMBUS_CMD) { in on_read_processed_event()
651 dev_warn(&ssif_bmc->client->dev, in on_read_processed_event()
653 __func__, state_to_string(ssif_bmc->state)); in on_read_processed_event()
654 ssif_bmc->state = SSIF_ABORTING; in on_read_processed_event()
660 if (!ssif_bmc->response_in_progress || ssif_bmc->state == SSIF_ABORTING) { in on_read_processed_event()
665 handle_read_processed(ssif_bmc, val); in on_read_processed_event()
668 static void on_write_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in on_write_requested_event() argument
670 if (ssif_bmc->state == SSIF_READY || ssif_bmc->state == SSIF_SMBUS_CMD) { in on_write_requested_event()
671 ssif_bmc->state = SSIF_START; in on_write_requested_event()
673 } else if (ssif_bmc->state == SSIF_START || in on_write_requested_event()
674 ssif_bmc->state == SSIF_REQ_RECVING || in on_write_requested_event()
675 ssif_bmc->state == SSIF_RES_SENDING) { in on_write_requested_event()
676 dev_warn(&ssif_bmc->client->dev, in on_write_requested_event()
678 __func__, state_to_string(ssif_bmc->state)); in on_write_requested_event()
679 ssif_bmc->state = SSIF_ABORTING; in on_write_requested_event()
683 ssif_bmc->msg_idx = 0; in on_write_requested_event()
684 ssif_bmc->part_buf.address = *val; in on_write_requested_event()
687 static void on_write_received_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in on_write_received_event() argument
689 if (ssif_bmc->state == SSIF_READY || in on_write_received_event()
690 ssif_bmc->state == SSIF_RES_SENDING) { in on_write_received_event()
691 dev_warn(&ssif_bmc->client->dev, in on_write_received_event()
693 __func__, state_to_string(ssif_bmc->state)); in on_write_received_event()
694 ssif_bmc->state = SSIF_ABORTING; in on_write_received_event()
696 } else if (ssif_bmc->state == SSIF_START) { in on_write_received_event()
697 ssif_bmc->state = SSIF_SMBUS_CMD; in on_write_received_event()
699 } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { in on_write_received_event()
700 if (!supported_write_cmd(ssif_bmc->part_buf.smbus_cmd)) { in on_write_received_event()
701 dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus write command=0x%x", in on_write_received_event()
702 ssif_bmc->part_buf.smbus_cmd); in on_write_received_event()
703 ssif_bmc->aborting = true; in on_write_received_event()
706 if (ssif_bmc->aborting) in on_write_received_event()
707 ssif_bmc->state = SSIF_ABORTING; in on_write_received_event()
709 ssif_bmc->state = SSIF_REQ_RECVING; in on_write_received_event()
713 if (ssif_bmc->state == SSIF_REQ_RECVING) in on_write_received_event()
714 handle_write_received(ssif_bmc, val); in on_write_received_event()
715 else if (ssif_bmc->state == SSIF_SMBUS_CMD) in on_write_received_event()
716 process_smbus_cmd(ssif_bmc, val); in on_write_received_event()
719 static void on_stop_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) in on_stop_event() argument
721 if (ssif_bmc->state == SSIF_READY || in on_stop_event()
722 ssif_bmc->state == SSIF_START || in on_stop_event()
723 ssif_bmc->state == SSIF_SMBUS_CMD || in on_stop_event()
724 ssif_bmc->state == SSIF_ABORTING) { in on_stop_event()
725 dev_warn(&ssif_bmc->client->dev, in on_stop_event()
727 __func__, state_to_string(ssif_bmc->state)); in on_stop_event()
728 ssif_bmc->state = SSIF_READY; in on_stop_event()
730 } else if (ssif_bmc->state == SSIF_REQ_RECVING) { in on_stop_event()
731 if (validate_request_part(ssif_bmc)) { in on_stop_event()
732 process_request_part(ssif_bmc); in on_stop_event()
733 if (ssif_bmc->part_buf.smbus_cmd == SSIF_IPMI_SINGLEPART_WRITE || in on_stop_event()
734 ssif_bmc->part_buf.smbus_cmd == SSIF_IPMI_MULTIPART_WRITE_END) in on_stop_event()
735 handle_request(ssif_bmc); in on_stop_event()
736 ssif_bmc->state = SSIF_READY; in on_stop_event()
743 dev_err(&ssif_bmc->client->dev, "Error: invalid pec\n"); in on_stop_event()
744 ssif_bmc->aborting = true; in on_stop_event()
746 } else if (ssif_bmc->state == SSIF_RES_SENDING) { in on_stop_event()
747 if (ssif_bmc->is_singlepart_read || ssif_bmc->block_num == 0xFF) in on_stop_event()
749 complete_response(ssif_bmc); in on_stop_event()
750 ssif_bmc->state = SSIF_READY; in on_stop_event()
754 ssif_bmc->msg_idx = 0; in on_stop_event()
763 struct ssif_bmc_ctx *ssif_bmc = i2c_get_clientdata(client); in ssif_bmc_cb() local
766 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_cb()
770 on_read_requested_event(ssif_bmc, val); in ssif_bmc_cb()
774 on_write_requested_event(ssif_bmc, val); in ssif_bmc_cb()
778 on_read_processed_event(ssif_bmc, val); in ssif_bmc_cb()
782 on_write_received_event(ssif_bmc, val); in ssif_bmc_cb()
786 on_stop_event(ssif_bmc, val); in ssif_bmc_cb()
790 dev_warn(&ssif_bmc->client->dev, "Warn: Unknown i2c slave event\n"); in ssif_bmc_cb()
794 if (!ssif_bmc->aborting && ssif_bmc->busy) in ssif_bmc_cb()
797 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_cb()
804 struct ssif_bmc_ctx *ssif_bmc; in ssif_bmc_probe() local
807 ssif_bmc = devm_kzalloc(&client->dev, sizeof(*ssif_bmc), GFP_KERNEL); in ssif_bmc_probe()
808 if (!ssif_bmc) in ssif_bmc_probe()
811 spin_lock_init(&ssif_bmc->lock); in ssif_bmc_probe()
813 init_waitqueue_head(&ssif_bmc->wait_queue); in ssif_bmc_probe()
814 ssif_bmc->request_available = false; in ssif_bmc_probe()
815 ssif_bmc->response_in_progress = false; in ssif_bmc_probe()
816 ssif_bmc->busy = false; in ssif_bmc_probe()
817 ssif_bmc->response_timer_inited = false; in ssif_bmc_probe()
820 ssif_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; in ssif_bmc_probe()
821 ssif_bmc->miscdev.name = DEVICE_NAME; in ssif_bmc_probe()
822 ssif_bmc->miscdev.fops = &ssif_bmc_fops; in ssif_bmc_probe()
823 ssif_bmc->miscdev.parent = &client->dev; in ssif_bmc_probe()
824 ret = misc_register(&ssif_bmc->miscdev); in ssif_bmc_probe()
828 ssif_bmc->client = client; in ssif_bmc_probe()
829 ssif_bmc->client->flags |= I2C_CLIENT_SLAVE; in ssif_bmc_probe()
832 i2c_set_clientdata(client, ssif_bmc); in ssif_bmc_probe()
835 misc_deregister(&ssif_bmc->miscdev); in ssif_bmc_probe()
842 struct ssif_bmc_ctx *ssif_bmc = i2c_get_clientdata(client); in ssif_bmc_remove() local
845 misc_deregister(&ssif_bmc->miscdev); in ssif_bmc_remove()