1 #include <linux/kernel.h>
3 #include <linux/semaphore.h>
4 #include <linux/slab.h>
5 #include <linux/uaccess.h>
11 #define DOWNLOAD_IMAGE 1
12 #define VALIDATE_IMAGE 2
26 static struct semaphore sem
;
27 static unsigned long *buffer
[CXL_AI_MAX_ENTRIES
];
28 static struct sg_list
*le
;
29 static u64 continue_token
;
30 static unsigned int transfer
;
32 struct update_props_workarea
{
39 struct update_nodes_workarea
{
45 #define DEVICE_SCOPE 3
46 #define NODE_ACTION_MASK 0xff000000
47 #define NODE_COUNT_MASK 0x00ffffff
48 #define OPCODE_DELETE 0x01000000
49 #define OPCODE_UPDATE 0x02000000
50 #define OPCODE_ADD 0x03000000
52 static int rcall(int token
, char *buf
, s32 scope
)
56 spin_lock(&rtas_data_buf_lock
);
58 memcpy(rtas_data_buf
, buf
, RTAS_DATA_BUF_SIZE
);
59 rc
= rtas_call(token
, 2, 1, NULL
, rtas_data_buf
, scope
);
60 memcpy(buf
, rtas_data_buf
, RTAS_DATA_BUF_SIZE
);
62 spin_unlock(&rtas_data_buf_lock
);
66 static int update_property(struct device_node
*dn
, const char *name
,
69 struct property
*new_prop
;
73 new_prop
= kzalloc(sizeof(*new_prop
), GFP_KERNEL
);
77 new_prop
->name
= kstrdup(name
, GFP_KERNEL
);
78 if (!new_prop
->name
) {
83 new_prop
->length
= vd
;
84 new_prop
->value
= kzalloc(new_prop
->length
, GFP_KERNEL
);
85 if (!new_prop
->value
) {
86 kfree(new_prop
->name
);
90 memcpy(new_prop
->value
, value
, vd
);
92 val
= (u32
*)new_prop
->value
;
93 rc
= cxl_update_properties(dn
, new_prop
);
94 pr_devel("%s: update property (%s, length: %i, value: %#x)\n",
95 dn
->name
, name
, vd
, be32_to_cpu(*val
));
98 kfree(new_prop
->name
);
99 kfree(new_prop
->value
);
105 static int update_node(__be32 phandle
, s32 scope
)
107 struct update_props_workarea
*upwa
;
108 struct device_node
*dn
;
116 token
= rtas_token("ibm,update-properties");
117 if (token
== RTAS_UNKNOWN_SERVICE
)
120 buf
= kzalloc(RTAS_DATA_BUF_SIZE
, GFP_KERNEL
);
124 dn
= of_find_node_by_phandle(be32_to_cpu(phandle
));
130 upwa
= (struct update_props_workarea
*)&buf
[0];
131 upwa
->phandle
= phandle
;
133 rc
= rcall(token
, buf
, scope
);
137 prop_data
= buf
+ sizeof(*upwa
);
138 nprops
= be32_to_cpu(upwa
->nprops
);
140 if (*prop_data
== 0) {
142 vd
= be32_to_cpu(*(__be32
*)prop_data
);
143 prop_data
+= vd
+ sizeof(vd
);
147 for (i
= 0; i
< nprops
; i
++) {
150 prop_name
= prop_data
;
151 prop_data
+= strlen(prop_name
) + 1;
152 vd
= be32_to_cpu(*(__be32
*)prop_data
);
153 prop_data
+= sizeof(vd
);
155 if ((vd
!= 0x00000000) && (vd
!= 0x80000000)) {
156 ret
= update_property(dn
, prop_name
, vd
,
159 pr_err("cxl: Could not update property %s - %i\n",
172 static int update_devicetree(struct cxl
*adapter
, s32 scope
)
174 struct update_nodes_workarea
*unwa
;
175 u32 action
, node_count
;
177 __be32
*data
, drc_index
, phandle
;
180 token
= rtas_token("ibm,update-nodes");
181 if (token
== RTAS_UNKNOWN_SERVICE
)
184 buf
= kzalloc(RTAS_DATA_BUF_SIZE
, GFP_KERNEL
);
188 unwa
= (struct update_nodes_workarea
*)&buf
[0];
189 unwa
->unit_address
= cpu_to_be64(adapter
->guest
->handle
);
191 rc
= rcall(token
, buf
, scope
);
195 data
= (__be32
*)buf
+ 4;
196 while (be32_to_cpu(*data
) & NODE_ACTION_MASK
) {
197 action
= be32_to_cpu(*data
) & NODE_ACTION_MASK
;
198 node_count
= be32_to_cpu(*data
) & NODE_COUNT_MASK
;
199 pr_devel("device reconfiguration - action: %#x, nodes: %#x\n",
203 for (i
= 0; i
< node_count
; i
++) {
211 update_node(phandle
, scope
);
214 /* nothing to do, just move pointer */
226 static int handle_image(struct cxl
*adapter
, int operation
,
227 long (*fct
)(u64
, u64
, u64
, u64
*),
228 struct cxl_adapter_image
*ai
)
230 size_t mod
, s_copy
, len_chunk
= 0;
231 struct ai_header
*header
= NULL
;
232 unsigned int entries
= 0, i
;
234 int rc
= 0, need_header
;
236 /* base adapter image header */
237 need_header
= (ai
->flags
& CXL_AI_NEED_HEADER
);
239 header
= kzalloc(sizeof(struct ai_header
), GFP_KERNEL
);
242 header
->version
= cpu_to_be16(1);
243 header
->vendor
= cpu_to_be16(adapter
->guest
->vendor
);
244 header
->device
= cpu_to_be16(adapter
->guest
->device
);
245 header
->subsystem_vendor
= cpu_to_be16(adapter
->guest
->subsystem_vendor
);
246 header
->subsystem
= cpu_to_be16(adapter
->guest
->subsystem
);
247 header
->image_offset
= cpu_to_be64(CXL_AI_HEADER_SIZE
);
248 header
->image_length
= cpu_to_be64(ai
->len_image
);
251 /* number of entries in the list */
252 len_chunk
= ai
->len_data
;
254 len_chunk
+= CXL_AI_HEADER_SIZE
;
256 entries
= len_chunk
/ CXL_AI_BUFFER_SIZE
;
257 mod
= len_chunk
% CXL_AI_BUFFER_SIZE
;
261 if (entries
> CXL_AI_MAX_ENTRIES
) {
266 /* < -- MAX_CHUNK_SIZE = 4096 * 256 = 1048576 bytes -->
267 * chunk 0 ----------------------------------------------------
269 * ----------------------------------------------------
270 * chunk 1 ----------------------------------------------------
272 * ----------------------------------------------------
274 * chunk n ----------------------------------------------------
276 * ----------------------------------------------------
278 from
= (void *) ai
->data
;
279 for (i
= 0; i
< entries
; i
++) {
281 s_copy
= CXL_AI_BUFFER_SIZE
;
283 if ((need_header
) && (i
== 0)) {
284 /* add adapter image header */
285 memcpy(buffer
[i
], header
, sizeof(struct ai_header
));
286 s_copy
= CXL_AI_BUFFER_SIZE
- CXL_AI_HEADER_SIZE
;
287 dest
+= CXL_AI_HEADER_SIZE
; /* image offset */
289 if ((i
== (entries
- 1)) && mod
)
293 if (copy_from_user(dest
, from
, s_copy
))
296 /* fill in the list */
297 le
[i
].phys_addr
= cpu_to_be64(virt_to_phys(buffer
[i
]));
298 le
[i
].len
= cpu_to_be64(CXL_AI_BUFFER_SIZE
);
299 if ((i
== (entries
- 1)) && mod
)
300 le
[i
].len
= cpu_to_be64(mod
);
303 pr_devel("%s (op: %i, need header: %i, entries: %i, token: %#llx)\n",
304 __func__
, operation
, need_header
, entries
, continue_token
);
307 * download/validate the adapter image to the coherent
310 rc
= fct(adapter
->guest
->handle
, virt_to_phys(le
), entries
,
312 if (rc
== 0) /* success of download/validation operation */
321 static int transfer_image(struct cxl
*adapter
, int operation
,
322 struct cxl_adapter_image
*ai
)
329 rc
= handle_image(adapter
, operation
,
330 &cxl_h_download_adapter_image
, ai
);
332 pr_devel("resetting adapter\n");
333 cxl_h_reset_adapter(adapter
->guest
->handle
);
338 rc
= handle_image(adapter
, operation
,
339 &cxl_h_validate_adapter_image
, ai
);
341 pr_devel("resetting adapter\n");
342 cxl_h_reset_adapter(adapter
->guest
->handle
);
346 pr_devel("remove curent afu\n");
347 for (afu
= 0; afu
< adapter
->slices
; afu
++)
348 cxl_guest_remove_afu(adapter
->afu
[afu
]);
350 pr_devel("resetting adapter\n");
351 cxl_h_reset_adapter(adapter
->guest
->handle
);
353 /* The entire image has now been
354 * downloaded and the validation has
355 * been successfully performed.
356 * After that, the partition should call
357 * ibm,update-nodes and
358 * ibm,update-properties to receive the
359 * current configuration
361 rc
= update_devicetree(adapter
, DEVICE_SCOPE
);
370 static long ioctl_transfer_image(struct cxl
*adapter
, int operation
,
371 struct cxl_adapter_image __user
*uai
)
373 struct cxl_adapter_image ai
;
375 pr_devel("%s\n", __func__
);
377 if (copy_from_user(&ai
, uai
, sizeof(struct cxl_adapter_image
)))
381 * Make sure reserved fields and bits are set to 0
383 if (ai
.reserved1
|| ai
.reserved2
|| ai
.reserved3
|| ai
.reserved4
||
384 (ai
.flags
& ~CXL_AI_ALL
))
387 return transfer_image(adapter
, operation
, &ai
);
390 static int device_open(struct inode
*inode
, struct file
*file
)
392 int adapter_num
= CXL_DEVT_ADAPTER(inode
->i_rdev
);
396 pr_devel("in %s\n", __func__
);
398 BUG_ON(sizeof(struct ai_header
) != CXL_AI_HEADER_SIZE
);
400 /* Allows one process to open the device by using a semaphore */
401 if (down_interruptible(&sem
) != 0)
404 if (!(adapter
= get_cxl_adapter(adapter_num
)))
407 file
->private_data
= adapter
;
411 for (i
= 0; i
< CXL_AI_MAX_ENTRIES
; i
++)
414 /* aligned buffer containing list entries which describes up to
415 * 1 megabyte of data (256 entries of 4096 bytes each)
416 * Logical real address of buffer 0 - Buffer 0 length in bytes
417 * Logical real address of buffer 1 - Buffer 1 length in bytes
418 * Logical real address of buffer 2 - Buffer 2 length in bytes
421 * Logical real address of buffer N - Buffer N length in bytes
423 le
= (struct sg_list
*)get_zeroed_page(GFP_KERNEL
);
429 for (i
= 0; i
< CXL_AI_MAX_ENTRIES
; i
++) {
430 buffer
[i
] = (unsigned long *)get_zeroed_page(GFP_KERNEL
);
440 for (i
= 0; i
< CXL_AI_MAX_ENTRIES
; i
++) {
442 free_page((unsigned long) buffer
[i
]);
446 free_page((unsigned long) le
);
448 put_device(&adapter
->dev
);
453 static long device_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
455 struct cxl
*adapter
= file
->private_data
;
457 pr_devel("in %s\n", __func__
);
459 if (cmd
== CXL_IOCTL_DOWNLOAD_IMAGE
)
460 return ioctl_transfer_image(adapter
,
462 (struct cxl_adapter_image __user
*)arg
);
463 else if (cmd
== CXL_IOCTL_VALIDATE_IMAGE
)
464 return ioctl_transfer_image(adapter
,
466 (struct cxl_adapter_image __user
*)arg
);
471 static long device_compat_ioctl(struct file
*file
, unsigned int cmd
,
474 return device_ioctl(file
, cmd
, arg
);
477 static int device_close(struct inode
*inode
, struct file
*file
)
479 struct cxl
*adapter
= file
->private_data
;
482 pr_devel("in %s\n", __func__
);
484 for (i
= 0; i
< CXL_AI_MAX_ENTRIES
; i
++) {
486 free_page((unsigned long) buffer
[i
]);
490 free_page((unsigned long) le
);
493 put_device(&adapter
->dev
);
496 /* reload the module */
498 cxl_guest_reload_module(adapter
);
500 pr_devel("resetting adapter\n");
501 cxl_h_reset_adapter(adapter
->guest
->handle
);
508 static const struct file_operations fops
= {
509 .owner
= THIS_MODULE
,
511 .unlocked_ioctl
= device_ioctl
,
512 .compat_ioctl
= device_compat_ioctl
,
513 .release
= device_close
,
516 void cxl_guest_remove_chardev(struct cxl
*adapter
)
518 cdev_del(&adapter
->guest
->cdev
);
521 int cxl_guest_add_chardev(struct cxl
*adapter
)
526 devt
= MKDEV(MAJOR(cxl_get_dev()), CXL_CARD_MINOR(adapter
));
527 cdev_init(&adapter
->guest
->cdev
, &fops
);
528 if ((rc
= cdev_add(&adapter
->guest
->cdev
, devt
, 1))) {
529 dev_err(&adapter
->dev
,
530 "Unable to add chardev on adapter (card%i): %i\n",
531 adapter
->adapter_num
, rc
);
534 adapter
->dev
.devt
= devt
;