| 324 | ****************************************************************************/ |
| 325 | |
| 326 | static ssize_t rpmsgblk_write(FAR struct inode *inode, |
| 327 | FAR const unsigned char *buffer, |
| 328 | blkcnt_t start_sector, unsigned int nsectors) |
| 329 | { |
| 330 | FAR struct rpmsgblk_s *priv = inode->i_private; |
| 331 | FAR struct rpmsgblk_write_s *msg; |
| 332 | struct rpmsgblk_cookie_s cookie; |
| 333 | uint32_t sectorsize; |
| 334 | uint32_t space; |
| 335 | size_t written = 0; |
| 336 | int ret; |
| 337 | |
| 338 | if (buffer == NULL) |
| 339 | { |
| 340 | return -EINVAL; |
| 341 | } |
| 342 | |
| 343 | /* Sanity checks */ |
| 344 | |
| 345 | DEBUGASSERT(priv != NULL); |
| 346 | |
| 347 | ret = rpmsgblk_geometry(inode, &priv->geo); |
| 348 | if (ret < 0) |
| 349 | { |
| 350 | ferr("Get geometry failed, ret=%d\n", ret); |
| 351 | return ret; |
| 352 | } |
| 353 | |
| 354 | /* Perform the rpmsg write */ |
| 355 | |
| 356 | memset(&cookie, 0, sizeof(cookie)); |
| 357 | nxsem_init(&cookie.sem, 0, 0); |
| 358 | |
| 359 | sectorsize = priv->geo.geo_sectorsize; |
| 360 | while (written < nsectors) |
| 361 | { |
| 362 | msg = rpmsgblk_get_tx_payload_buffer(priv, &space); |
| 363 | if (msg == NULL) |
| 364 | { |
| 365 | ret = -ENOMEM; |
| 366 | goto out; |
| 367 | } |
| 368 | |
| 369 | DEBUGASSERT(sizeof(*msg) - 1 + sectorsize <= space); |
| 370 | |
| 371 | msg->nsectors = (space - sizeof(*msg) + 1) / sectorsize; |
| 372 | if (msg->nsectors >= nsectors - written) |
| 373 | { |
| 374 | /* Send complete, set cookie is valid, need ack */ |
| 375 | |
| 376 | msg->nsectors = nsectors - written; |
| 377 | msg->header.cookie = (uintptr_t)&cookie; |
| 378 | } |
| 379 | else |
| 380 | { |
| 381 | /* Not send complete, set cookie invalid, do not need ack */ |
| 382 | |
| 383 | msg->header.cookie = 0; |
nothing calls this directly
no test coverage detected