• Home
  • Raw
  • Download

Lines Matching +full:part +full:- +full:number

1 // SPDX-License-Identifier: GPL-2.0-only
22 #define DEVICE_NAME "ipmi-ssif-host"
44 * Request-to-Response Time is T6max(250ms) - T1max(20ms) - 3ms = 227ms
90 /* Flag to identify a Multi-part Read Transaction */
95 /* Block Number of a Multi-part Read Transaction */
101 /* Buffer for SSIF Transaction part*/
109 return container_of(file->private_data, struct ssif_bmc_ctx, miscdev); in to_ssif_bmc()
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()
143 if (file->f_flags & O_NONBLOCK) in ssif_bmc_read()
144 return -EAGAIN; 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()
156 ret = -EINVAL; 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()
181 return -EINVAL; in ssif_bmc_write()
184 return -EFAULT; in ssif_bmc_write()
187 return -EINVAL; in ssif_bmc_write()
189 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_write()
190 while (ssif_bmc->response_in_progress) { in ssif_bmc_write()
191 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_write()
192 if (file->f_flags & O_NONBLOCK) in ssif_bmc_write()
193 return -EAGAIN; in ssif_bmc_write()
194 ret = wait_event_interruptible(ssif_bmc->wait_queue, in ssif_bmc_write()
195 !ssif_bmc->response_in_progress); in ssif_bmc_write()
198 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_write()
204 * Return -EINVAL if the response is aborted in ssif_bmc_write()
206 ret = (ssif_bmc->response_timer_inited) ? 0 : -EINVAL; in ssif_bmc_write()
210 del_timer(&ssif_bmc->response_timer); in ssif_bmc_write()
211 ssif_bmc->response_timer_inited = false; in ssif_bmc_write()
213 memcpy(&ssif_bmc->response, &msg, count); in ssif_bmc_write()
214 ssif_bmc->is_singlepart_read = (msg.len <= MAX_PAYLOAD_PER_TRANSACTION); in ssif_bmc_write()
216 ssif_bmc->response_in_progress = true; in ssif_bmc_write()
219 ssif_bmc->busy = false; in ssif_bmc_write()
222 memset(&ssif_bmc->request, 0, sizeof(struct ipmi_ssif_msg)); in ssif_bmc_write()
224 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_write()
234 spin_lock_irq(&ssif_bmc->lock); in ssif_bmc_open()
235 if (!ssif_bmc->running) in ssif_bmc_open()
236 ssif_bmc->running = 1; in ssif_bmc_open()
238 ret = -EBUSY; in ssif_bmc_open()
239 spin_unlock_irq(&ssif_bmc->lock); in ssif_bmc_open()
249 poll_wait(file, &ssif_bmc->wait_queue, wait); in ssif_bmc_poll()
251 spin_lock_irq(&ssif_bmc->lock); in ssif_bmc_poll()
253 if (ssif_bmc->request_available) in ssif_bmc_poll()
256 spin_unlock_irq(&ssif_bmc->lock); in ssif_bmc_poll()
265 spin_lock_irq(&ssif_bmc->lock); in ssif_bmc_release()
266 ssif_bmc->running = 0; in ssif_bmc_release()
267 spin_unlock_irq(&ssif_bmc->lock); in ssif_bmc_release()
284 /* Called with ssif_bmc->lock held. */
288 ssif_bmc->response.len = 0; in complete_response()
289 ssif_bmc->response_in_progress = false; in complete_response()
290 ssif_bmc->nbytes_processed = 0; in complete_response()
291 ssif_bmc->remain_len = 0; in complete_response()
292 ssif_bmc->busy = false; in complete_response()
293 memset(&ssif_bmc->part_buf, 0, sizeof(struct ssif_part_buffer)); in complete_response()
294 wake_up_all(&ssif_bmc->wait_queue); in complete_response()
302 spin_lock_irqsave(&ssif_bmc->lock, flags); in response_timeout()
305 if (!ssif_bmc->response_in_progress) { in response_timeout()
307 ssif_bmc->busy = false; in response_timeout()
308 ssif_bmc->response_timer_inited = false; in response_timeout()
310 ssif_bmc->aborting = true; in response_timeout()
313 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in response_timeout()
316 /* Called with ssif_bmc->lock held. */
320 ssif_bmc->busy = true; in handle_request()
322 ssif_bmc->request_available = true; in handle_request()
324 memset(&ssif_bmc->response, 0, sizeof(struct ipmi_ssif_msg)); in handle_request()
326 wake_up_all(&ssif_bmc->wait_queue); in handle_request()
329 if (!ssif_bmc->response_timer_inited) { in handle_request()
330 timer_setup(&ssif_bmc->response_timer, response_timeout, 0); in handle_request()
331 ssif_bmc->response_timer_inited = true; in handle_request()
333 mod_timer(&ssif_bmc->response_timer, jiffies + msecs_to_jiffies(RESPONSE_TIMEOUT)); in handle_request()
336 static void calculate_response_part_pec(struct ssif_part_buffer *part) in calculate_response_part_pec() argument
338 u8 addr = part->address; in calculate_response_part_pec()
340 /* PEC - Start Read Address */ in calculate_response_part_pec()
341 part->pec = i2c_smbus_pec(0, &addr, 1); in calculate_response_part_pec()
342 /* PEC - SSIF Command */ in calculate_response_part_pec()
343 part->pec = i2c_smbus_pec(part->pec, &part->smbus_cmd, 1); in calculate_response_part_pec()
344 /* PEC - Restart Write Address */ in calculate_response_part_pec()
346 part->pec = i2c_smbus_pec(part->pec, &addr, 1); in calculate_response_part_pec()
347 part->pec = i2c_smbus_pec(part->pec, &part->length, 1); in calculate_response_part_pec()
348 if (part->length) in calculate_response_part_pec()
349 part->pec = i2c_smbus_pec(part->pec, part->payload, part->length); in calculate_response_part_pec()
354 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in set_singlepart_response_buffer() local
356 part->address = GET_8BIT_ADDR(ssif_bmc->client->addr); in set_singlepart_response_buffer()
357 part->length = (u8)ssif_bmc->response.len; in set_singlepart_response_buffer()
360 memset(part->payload + part->length, 0, MAX_PAYLOAD_PER_TRANSACTION - part->length); in set_singlepart_response_buffer()
361 memcpy(&part->payload[0], &ssif_bmc->response.payload[0], part->length); in set_singlepart_response_buffer()
366 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in set_multipart_response_buffer() local
369 part->address = GET_8BIT_ADDR(ssif_bmc->client->addr); in set_multipart_response_buffer()
370 switch (part->smbus_cmd) { in set_multipart_response_buffer()
377 ssif_bmc->nbytes_processed = 0; in set_multipart_response_buffer()
378 ssif_bmc->block_num = 0; in set_multipart_response_buffer()
379 part->length = MAX_PAYLOAD_PER_TRANSACTION; in set_multipart_response_buffer()
381 ssif_bmc->remain_len = ssif_bmc->response.len - part_len; in set_multipart_response_buffer()
383 part->payload[0] = 0x00; /* Start Flag */ in set_multipart_response_buffer()
384 part->payload[1] = 0x01; /* Start Flag */ in set_multipart_response_buffer()
386 memcpy(&part->payload[2], &ssif_bmc->response.payload[0], part_len); in set_multipart_response_buffer()
392 * IPMI data plus block number byte. in set_multipart_response_buffer()
394 if (ssif_bmc->remain_len <= MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION) { in set_multipart_response_buffer()
398 * plus block number in set_multipart_response_buffer()
399 * Block number 0xFF is to indicate this is last message in set_multipart_response_buffer()
403 memset(&part->payload[0], 0, MAX_PAYLOAD_PER_TRANSACTION); in set_multipart_response_buffer()
404 part->length = ssif_bmc->remain_len + 1; in set_multipart_response_buffer()
405 part_len = ssif_bmc->remain_len; in set_multipart_response_buffer()
406 ssif_bmc->block_num = 0xFF; in set_multipart_response_buffer()
407 part->payload[0] = ssif_bmc->block_num; in set_multipart_response_buffer()
412 * Block number byte is incremented in set_multipart_response_buffer()
415 part->length = MAX_PAYLOAD_PER_TRANSACTION; in set_multipart_response_buffer()
417 part->payload[0] = ssif_bmc->block_num; in set_multipart_response_buffer()
418 ssif_bmc->block_num++; in set_multipart_response_buffer()
421 ssif_bmc->remain_len -= part_len; in set_multipart_response_buffer()
422 memcpy(&part->payload[1], ssif_bmc->response.payload + ssif_bmc->nbytes_processed, in set_multipart_response_buffer()
428 dev_err(&ssif_bmc->client->dev, "%s: Unexpected SMBus command 0x%x\n", in set_multipart_response_buffer()
429 __func__, part->smbus_cmd); in set_multipart_response_buffer()
433 ssif_bmc->nbytes_processed += part_len; in set_multipart_response_buffer()
460 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in handle_read_processed() local
463 if (part->index < part->length) in handle_read_processed()
464 *val = part->payload[part->index]; in handle_read_processed()
465 else if (part->index == part->length && ssif_bmc->pec_support) in handle_read_processed()
466 *val = part->pec; in handle_read_processed()
470 part->index++; in handle_read_processed()
480 if (ssif_bmc->msg_idx < 1 || ssif_bmc->msg_idx > MAX_TRANSACTION) in handle_write_received()
483 if (ssif_bmc->msg_idx == 1) { in handle_write_received()
484 ssif_bmc->part_buf.length = *val; in handle_write_received()
485 ssif_bmc->part_buf.index = 0; in handle_write_received()
487 ssif_bmc->part_buf.payload[ssif_bmc->part_buf.index++] = *val; in handle_write_received()
490 ssif_bmc->msg_idx++; in handle_write_received()
495 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in validate_request_part() local
500 if (part->index == part->length) { in validate_request_part()
502 ssif_bmc->pec_support = false; in validate_request_part()
507 if (part->index != part->length + 1) { in validate_request_part()
513 ssif_bmc->pec_support = true; in validate_request_part()
514 part->pec = part->payload[part->length]; in validate_request_part()
515 addr = GET_8BIT_ADDR(ssif_bmc->client->addr); in validate_request_part()
517 cpec = i2c_smbus_pec(cpec, &part->smbus_cmd, 1); in validate_request_part()
518 cpec = i2c_smbus_pec(cpec, &part->length, 1); in validate_request_part()
521 * (byte count) in the Write-Block protocol to be zero. in validate_request_part()
523 * transaction in the sequence carry 32-byte and have in validate_request_part()
528 if (part->length) in validate_request_part()
529 cpec = i2c_smbus_pec(cpec, part->payload, part->length); in validate_request_part()
531 if (cpec != part->pec) in validate_request_part()
540 struct ssif_part_buffer *part = &ssif_bmc->part_buf; in process_request_part() local
543 switch (part->smbus_cmd) { in process_request_part()
545 /* save the whole part to request*/ in process_request_part()
546 ssif_bmc->request.len = part->length; in process_request_part()
547 memcpy(ssif_bmc->request.payload, part->payload, part->length); in process_request_part()
551 ssif_bmc->request.len = 0; in process_request_part()
556 len = ssif_bmc->request.len + part->length; in process_request_part()
559 dev_warn(&ssif_bmc->client->dev, in process_request_part()
562 ssif_bmc->aborting = true; in process_request_part()
564 memcpy(ssif_bmc->request.payload + ssif_bmc->request.len, in process_request_part()
565 part->payload, part->length); in process_request_part()
566 ssif_bmc->request.len += part->length; in process_request_part()
571 dev_err(&ssif_bmc->client->dev, "%s: Unexpected SMBus command 0x%x\n", in process_request_part()
572 __func__, part->smbus_cmd); in process_request_part()
579 /* SMBUS command can vary (single or multi-part) */ in process_smbus_cmd()
580 ssif_bmc->part_buf.smbus_cmd = *val; in process_smbus_cmd()
581 ssif_bmc->msg_idx = 1; in process_smbus_cmd()
582 memset(&ssif_bmc->part_buf.payload[0], 0, MAX_PAYLOAD_PER_TRANSACTION); in process_smbus_cmd()
586 * The response maybe not come in-time, causing host SSIF driver in process_smbus_cmd()
590 if (ssif_bmc->response_in_progress) in process_smbus_cmd()
594 if (ssif_bmc->aborting) in process_smbus_cmd()
595 ssif_bmc->aborting = false; in process_smbus_cmd()
601 if (ssif_bmc->state == SSIF_READY || in on_read_requested_event()
602 ssif_bmc->state == SSIF_START || in on_read_requested_event()
603 ssif_bmc->state == SSIF_REQ_RECVING || in on_read_requested_event()
604 ssif_bmc->state == SSIF_RES_SENDING) { in on_read_requested_event()
605 dev_warn(&ssif_bmc->client->dev, in on_read_requested_event()
607 __func__, state_to_string(ssif_bmc->state)); in on_read_requested_event()
608 ssif_bmc->state = SSIF_ABORTING; in on_read_requested_event()
612 } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { in on_read_requested_event()
613 if (!supported_read_cmd(ssif_bmc->part_buf.smbus_cmd)) { in on_read_requested_event()
614 dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus read command=0x%x", in on_read_requested_event()
615 ssif_bmc->part_buf.smbus_cmd); in on_read_requested_event()
616 ssif_bmc->aborting = true; in on_read_requested_event()
619 if (ssif_bmc->aborting) in on_read_requested_event()
620 ssif_bmc->state = SSIF_ABORTING; in on_read_requested_event()
622 ssif_bmc->state = SSIF_RES_SENDING; in on_read_requested_event()
625 ssif_bmc->msg_idx = 0; in on_read_requested_event()
628 if (!ssif_bmc->response_in_progress || ssif_bmc->state == SSIF_ABORTING) { in on_read_requested_event()
633 if (ssif_bmc->is_singlepart_read) in on_read_requested_event()
638 calculate_response_part_pec(&ssif_bmc->part_buf); in on_read_requested_event()
639 ssif_bmc->part_buf.index = 0; in on_read_requested_event()
640 *val = ssif_bmc->part_buf.length; in on_read_requested_event()
645 if (ssif_bmc->state == SSIF_READY || in on_read_processed_event()
646 ssif_bmc->state == SSIF_START || in on_read_processed_event()
647 ssif_bmc->state == SSIF_REQ_RECVING || in on_read_processed_event()
648 ssif_bmc->state == SSIF_SMBUS_CMD) { in on_read_processed_event()
649 dev_warn(&ssif_bmc->client->dev, in on_read_processed_event()
651 __func__, state_to_string(ssif_bmc->state)); in on_read_processed_event()
652 ssif_bmc->state = SSIF_ABORTING; in on_read_processed_event()
658 if (!ssif_bmc->response_in_progress || ssif_bmc->state == SSIF_ABORTING) { in on_read_processed_event()
668 if (ssif_bmc->state == SSIF_READY || ssif_bmc->state == SSIF_SMBUS_CMD) { in on_write_requested_event()
669 ssif_bmc->state = SSIF_START; in on_write_requested_event()
671 } else if (ssif_bmc->state == SSIF_START || in on_write_requested_event()
672 ssif_bmc->state == SSIF_REQ_RECVING || in on_write_requested_event()
673 ssif_bmc->state == SSIF_RES_SENDING) { in on_write_requested_event()
674 dev_warn(&ssif_bmc->client->dev, in on_write_requested_event()
676 __func__, state_to_string(ssif_bmc->state)); in on_write_requested_event()
677 ssif_bmc->state = SSIF_ABORTING; in on_write_requested_event()
681 ssif_bmc->msg_idx = 0; in on_write_requested_event()
682 ssif_bmc->part_buf.address = *val; in on_write_requested_event()
687 if (ssif_bmc->state == SSIF_READY || in on_write_received_event()
688 ssif_bmc->state == SSIF_RES_SENDING) { in on_write_received_event()
689 dev_warn(&ssif_bmc->client->dev, in on_write_received_event()
691 __func__, state_to_string(ssif_bmc->state)); in on_write_received_event()
692 ssif_bmc->state = SSIF_ABORTING; in on_write_received_event()
694 } else if (ssif_bmc->state == SSIF_START) { in on_write_received_event()
695 ssif_bmc->state = SSIF_SMBUS_CMD; in on_write_received_event()
697 } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { in on_write_received_event()
698 if (!supported_write_cmd(ssif_bmc->part_buf.smbus_cmd)) { in on_write_received_event()
699 dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus write command=0x%x", in on_write_received_event()
700 ssif_bmc->part_buf.smbus_cmd); in on_write_received_event()
701 ssif_bmc->aborting = true; in on_write_received_event()
704 if (ssif_bmc->aborting) in on_write_received_event()
705 ssif_bmc->state = SSIF_ABORTING; in on_write_received_event()
707 ssif_bmc->state = SSIF_REQ_RECVING; in on_write_received_event()
711 if (ssif_bmc->state == SSIF_REQ_RECVING) in on_write_received_event()
713 else if (ssif_bmc->state == SSIF_SMBUS_CMD) in on_write_received_event()
719 if (ssif_bmc->state == SSIF_READY || in on_stop_event()
720 ssif_bmc->state == SSIF_START || in on_stop_event()
721 ssif_bmc->state == SSIF_SMBUS_CMD || in on_stop_event()
722 ssif_bmc->state == SSIF_ABORTING) { in on_stop_event()
723 dev_warn(&ssif_bmc->client->dev, in on_stop_event()
725 __func__, state_to_string(ssif_bmc->state)); in on_stop_event()
726 ssif_bmc->state = SSIF_READY; in on_stop_event()
728 } else if (ssif_bmc->state == SSIF_REQ_RECVING) { in on_stop_event()
731 if (ssif_bmc->part_buf.smbus_cmd == SSIF_IPMI_SINGLEPART_WRITE || in on_stop_event()
732 ssif_bmc->part_buf.smbus_cmd == SSIF_IPMI_MULTIPART_WRITE_END) in on_stop_event()
734 ssif_bmc->state = SSIF_READY; in on_stop_event()
741 dev_err(&ssif_bmc->client->dev, "Error: invalid pec\n"); in on_stop_event()
742 ssif_bmc->aborting = true; in on_stop_event()
744 } else if (ssif_bmc->state == SSIF_RES_SENDING) { in on_stop_event()
745 if (ssif_bmc->is_singlepart_read || ssif_bmc->block_num == 0xFF) in on_stop_event()
748 ssif_bmc->state = SSIF_READY; in on_stop_event()
752 ssif_bmc->msg_idx = 0; in on_stop_event()
764 spin_lock_irqsave(&ssif_bmc->lock, flags); in ssif_bmc_cb()
788 dev_warn(&ssif_bmc->client->dev, "Warn: Unknown i2c slave event\n"); in ssif_bmc_cb()
792 if (!ssif_bmc->aborting && ssif_bmc->busy) in ssif_bmc_cb()
793 ret = -EBUSY; in ssif_bmc_cb()
795 spin_unlock_irqrestore(&ssif_bmc->lock, flags); in ssif_bmc_cb()
805 ssif_bmc = devm_kzalloc(&client->dev, sizeof(*ssif_bmc), GFP_KERNEL); in ssif_bmc_probe()
807 return -ENOMEM; in ssif_bmc_probe()
809 spin_lock_init(&ssif_bmc->lock); in ssif_bmc_probe()
811 init_waitqueue_head(&ssif_bmc->wait_queue); in ssif_bmc_probe()
812 ssif_bmc->request_available = false; in ssif_bmc_probe()
813 ssif_bmc->response_in_progress = false; in ssif_bmc_probe()
814 ssif_bmc->busy = false; in ssif_bmc_probe()
815 ssif_bmc->response_timer_inited = false; in ssif_bmc_probe()
818 ssif_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; in ssif_bmc_probe()
819 ssif_bmc->miscdev.name = DEVICE_NAME; in ssif_bmc_probe()
820 ssif_bmc->miscdev.fops = &ssif_bmc_fops; in ssif_bmc_probe()
821 ssif_bmc->miscdev.parent = &client->dev; in ssif_bmc_probe()
822 ret = misc_register(&ssif_bmc->miscdev); in ssif_bmc_probe()
826 ssif_bmc->client = client; in ssif_bmc_probe()
827 ssif_bmc->client->flags |= I2C_CLIENT_SLAVE; in ssif_bmc_probe()
833 misc_deregister(&ssif_bmc->miscdev); in ssif_bmc_probe()
843 misc_deregister(&ssif_bmc->miscdev); in ssif_bmc_remove()
847 { .compatible = "ssif-bmc" },