iPXE
httpblock.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * Hyper Text Transfer Protocol (HTTP) block device
30  *
31  */
32 
33 #include <stdint.h>
34 #include <ipxe/uaccess.h>
35 #include <ipxe/blocktrans.h>
36 #include <ipxe/blockdev.h>
37 #include <ipxe/acpi.h>
38 #include <ipxe/http.h>
39 
40 /** Block size used for HTTP block device requests */
41 #define HTTP_BLKSIZE 512
42 
43 /**
44  * Read from block device
45  *
46  * @v http HTTP transaction
47  * @v data Data interface
48  * @v lba Starting logical block address
49  * @v count Number of logical blocks
50  * @v buffer Data buffer
51  * @v len Length of data buffer
52  * @ret rc Return status code
53  */
54 int http_block_read ( struct http_transaction *http, struct interface *data,
55  uint64_t lba, unsigned int count, userptr_t buffer,
56  size_t len ) {
57  struct http_request_range range;
58  int rc;
59 
60  /* Sanity check */
61  assert ( len == ( count * HTTP_BLKSIZE ) );
62 
63  /* Construct request range descriptor */
64  range.start = ( lba * HTTP_BLKSIZE );
65  range.len = len;
66 
67  /* Start a range request to retrieve the block(s) */
68  if ( ( rc = http_open ( data, &http_get, http->uri, &range,
69  NULL ) ) != 0 )
70  goto err_open;
71 
72  /* Insert block device translator */
73  if ( ( rc = block_translate ( data, buffer, len ) ) != 0 ) {
74  DBGC ( http, "HTTP %p could not insert block translator: %s\n",
75  http, strerror ( rc ) );
76  goto err_translate;
77  }
78 
79  return 0;
80 
81  err_translate:
82  intf_restart ( data, rc );
83  err_open:
84  return rc;
85 }
86 
87 /**
88  * Read block device capacity
89  *
90  * @v control Control interface
91  * @v data Data interface
92  * @ret rc Return status code
93  */
95  struct interface *data ) {
96  int rc;
97 
98  /* Start a HEAD request to retrieve the capacity */
99  if ( ( rc = http_open ( data, &http_head, http->uri, NULL,
100  NULL ) ) != 0 )
101  goto err_open;
102 
103  /* Insert block device translator */
104  if ( ( rc = block_translate ( data, UNULL, HTTP_BLKSIZE ) ) != 0 ) {
105  DBGC ( http, "HTTP %p could not insert block translator: %s\n",
106  http, strerror ( rc ) );
107  goto err_translate;
108  }
109 
110  return 0;
111 
112  err_translate:
113  intf_restart ( data, rc );
114  err_open:
115  return rc;
116 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
size_t start
Range start.
Definition: http.h:139
uint32_t lba
Start address.
Definition: scsi.h:23
struct http_method http_head
HTTP HEAD method.
Definition: httpcore.c:133
HTTP request range descriptor.
Definition: http.h:137
#define DBGC(...)
Definition: compiler.h:505
struct uri * uri
Request URI.
Definition: http.h:434
unsigned long long uint64_t
Definition: stdint.h:13
Block device translator.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
int block_translate(struct interface *block, userptr_t buffer, size_t size)
Insert block device translator.
Definition: blocktrans.c:223
Access to external ("user") memory.
int http_block_read_capacity(struct http_transaction *http, struct interface *data)
Read block device capacity.
Definition: httpblock.c:94
An HTTP transaction.
Definition: http.h:417
Hyper Text Transport Protocol.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
An object interface.
Definition: interface.h:109
struct http_method http_get
HTTP GET method.
Definition: httpcore.c:138
Block devices.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
ACPI data structures.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
size_t len
Range length, or zero for no range request.
Definition: http.h:141
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
uint32_t len
Length.
Definition: ena.h:14
int http_open(struct interface *xfer, struct http_method *method, struct uri *uri, struct http_request_range *range, struct http_request_content *content)
Open HTTP transaction.
Definition: httpcore.c:586
uint16_t count
Number of entries.
Definition: ena.h:22
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
int http_block_read(struct http_transaction *http, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len)
Read from block device.
Definition: httpblock.c:54
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
#define HTTP_BLKSIZE
Block size used for HTTP block device requests.
Definition: httpblock.c:41