Lines Matching refs:port

80 static void vdc_ldc_reset(struct vdc_port *port);
95 static inline int vdc_version_supported(struct vdc_port *port, in vdc_version_supported() argument
98 return port->vio.ver.major == major && port->vio.ver.minor >= minor; in vdc_version_supported()
163 static void vdc_blk_queue_start(struct vdc_port *port) in vdc_blk_queue_start() argument
165 struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in vdc_blk_queue_start()
171 if (port->disk && blk_queue_stopped(port->disk->queue) && in vdc_blk_queue_start()
173 blk_start_queue(port->disk->queue); in vdc_blk_queue_start()
191 struct vdc_port *port = to_vdc_port(vio); in vdc_handshake_complete() local
193 del_timer(&port->ldc_reset_timer); in vdc_handshake_complete()
195 vdc_blk_queue_start(port); in vdc_handshake_complete()
198 static int vdc_handle_unknown(struct vdc_port *port, void *arg) in vdc_handle_unknown() argument
206 ldc_disconnect(port->vio.lp); in vdc_handle_unknown()
213 struct vdc_port *port = to_vdc_port(vio); in vdc_send_attr() local
224 pkt.vdisk_block_size = port->vdisk_block_size; in vdc_send_attr()
225 pkt.max_xfer_size = port->max_xfer_size; in vdc_send_attr()
230 return vio_ldc_send(&port->vio, &pkt, sizeof(pkt)); in vdc_send_attr()
235 struct vdc_port *port = to_vdc_port(vio); in vdc_handle_attr() local
257 if (pkt->vdisk_block_size > port->vdisk_block_size) { in vdc_handle_attr()
261 port->vdisk_block_size, pkt->vdisk_block_size); in vdc_handle_attr()
265 port->operations = pkt->operations; in vdc_handle_attr()
266 port->vdisk_type = pkt->vdisk_type; in vdc_handle_attr()
267 if (vdc_version_supported(port, 1, 1)) { in vdc_handle_attr()
268 port->vdisk_size = pkt->vdisk_size; in vdc_handle_attr()
269 port->vdisk_mtype = pkt->vdisk_mtype; in vdc_handle_attr()
271 if (pkt->max_xfer_size < port->max_xfer_size) in vdc_handle_attr()
272 port->max_xfer_size = pkt->max_xfer_size; in vdc_handle_attr()
273 port->vdisk_block_size = pkt->vdisk_block_size; in vdc_handle_attr()
282 static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc) in vdc_end_special() argument
286 vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD); in vdc_end_special()
289 static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, in vdc_end_one() argument
293 struct vdc_req_entry *rqe = &port->rq_arr[index]; in vdc_end_one()
299 ldc_unmap(port->vio.lp, desc->cookies, desc->ncookies); in vdc_end_one()
305 vdc_end_special(port, desc); in vdc_end_one()
313 vdc_blk_queue_start(port); in vdc_end_one()
316 static int vdc_ack(struct vdc_port *port, void *msgbuf) in vdc_ack() argument
318 struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in vdc_ack()
326 vdc_end_one(port, dr, pkt->start_idx); in vdc_ack()
331 static int vdc_nack(struct vdc_port *port, void *msgbuf) in vdc_nack() argument
339 struct vdc_port *port = arg; in vdc_event() local
340 struct vio_driver_state *vio = &port->vio; in vdc_event()
348 queue_work(sunvdc_wq, &port->ldc_reset_work); in vdc_event()
388 err = vdc_ack(port, &msgbuf); in vdc_event()
390 err = vdc_nack(port, &msgbuf); in vdc_event()
392 err = vdc_handle_unknown(port, &msgbuf); in vdc_event()
396 err = vdc_handle_unknown(port, &msgbuf); in vdc_event()
402 vdc_finish(&port->vio, err, WAITING_FOR_ANY); in vdc_event()
407 static int __vdc_tx_trigger(struct vdc_port *port) in __vdc_tx_trigger() argument
409 struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in __vdc_tx_trigger()
415 .sid = vio_send_sid(&port->vio), in __vdc_tx_trigger()
426 err = vio_ldc_send(&port->vio, &hdr, sizeof(hdr)); in __vdc_tx_trigger()
437 vdc_ldc_reset(port); in __vdc_tx_trigger()
443 struct vdc_port *port = req->rq_disk->private_data; in __send_request() local
444 struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in __send_request()
445 struct scatterlist sg[port->ring_cookies]; in __send_request()
463 sg_init_table(sg, port->ring_cookies); in __send_request()
472 err = ldc_map_sg(port->vio.lp, sg, nsg, in __send_request()
473 desc->cookies, port->ring_cookies, in __send_request()
480 rqe = &port->rq_arr[dr->prod]; in __send_request()
484 desc->req_id = port->req_id; in __send_request()
486 if (port->vdisk_type == VD_DISK_TYPE_DISK) { in __send_request()
492 desc->offset = (blk_rq_pos(req) << 9) / port->vdisk_block_size; in __send_request()
502 err = __vdc_tx_trigger(port); in __send_request()
506 port->req_id++; in __send_request()
518 struct vdc_port *port; in do_vdc_request() local
521 port = req->rq_disk->private_data; in do_vdc_request()
522 dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in do_vdc_request()
538 static int generic_request(struct vdc_port *port, u8 op, void *buf, int len) in generic_request() argument
548 if (!(((u64)1 << (u64)op) & port->operations)) in generic_request()
621 spin_lock_irqsave(&port->vio.lock, flags); in generic_request()
623 dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in generic_request()
630 err = ldc_map_single(port->vio.lp, req_buf, op_len, in generic_request()
631 desc->cookies, port->ring_cookies, in generic_request()
634 spin_unlock_irqrestore(&port->vio.lock, flags); in generic_request()
641 port->vio.cmp = &comp; in generic_request()
644 desc->req_id = port->req_id; in generic_request()
658 err = __vdc_tx_trigger(port); in generic_request()
660 port->req_id++; in generic_request()
662 spin_unlock_irqrestore(&port->vio.lock, flags); in generic_request()
667 port->vio.cmp = NULL; in generic_request()
668 spin_unlock_irqrestore(&port->vio.lock, flags); in generic_request()
679 static int vdc_alloc_tx_ring(struct vdc_port *port) in vdc_alloc_tx_ring() argument
681 struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in vdc_alloc_tx_ring()
687 (sizeof(struct ldc_trans_cookie) * port->ring_cookies); in vdc_alloc_tx_ring()
691 dring = ldc_alloc_exp_dring(port->vio.lp, len, in vdc_alloc_tx_ring()
709 static void vdc_free_tx_ring(struct vdc_port *port) in vdc_free_tx_ring() argument
711 struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in vdc_free_tx_ring()
714 ldc_free_exp_dring(port->vio.lp, dr->base, in vdc_free_tx_ring()
725 static int vdc_port_up(struct vdc_port *port) in vdc_port_up() argument
732 port->vio.cmp = &comp; in vdc_port_up()
734 vio_port_up(&port->vio); in vdc_port_up()
739 static void vdc_port_down(struct vdc_port *port) in vdc_port_down() argument
741 ldc_disconnect(port->vio.lp); in vdc_port_down()
742 ldc_unbind(port->vio.lp); in vdc_port_down()
743 vdc_free_tx_ring(port); in vdc_port_down()
744 vio_ldc_free(&port->vio); in vdc_port_down()
747 static int probe_disk(struct vdc_port *port) in probe_disk() argument
753 err = vdc_port_up(port); in probe_disk()
757 if (vdc_version_supported(port, 1, 1)) { in probe_disk()
761 if (port->vdisk_size == -1) in probe_disk()
766 err = generic_request(port, VD_OP_GET_DISKGEOM, in probe_disk()
773 port->vdisk_size = ((u64)geom.num_cyl * in probe_disk()
778 q = blk_init_queue(do_vdc_request, &port->vio.lock); in probe_disk()
781 port->vio.name); in probe_disk()
787 port->vio.name); in probe_disk()
792 port->disk = g; in probe_disk()
798 blk_queue_max_segments(q, port->ring_cookies); in probe_disk()
799 blk_queue_max_hw_sectors(q, port->max_xfer_size); in probe_disk()
801 g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT; in probe_disk()
802 strcpy(g->disk_name, port->disk_name); in probe_disk()
806 g->private_data = port; in probe_disk()
807 g->driverfs_dev = &port->vio.vdev->dev; in probe_disk()
809 set_capacity(g, port->vdisk_size); in probe_disk()
811 if (vdc_version_supported(port, 1, 1)) { in probe_disk()
812 switch (port->vdisk_mtype) { in probe_disk()
814 pr_info(PFX "Virtual CDROM %s\n", port->disk_name); in probe_disk()
821 pr_info(PFX "Virtual DVD %s\n", port->disk_name); in probe_disk()
828 pr_info(PFX "Virtual Hard disk %s\n", port->disk_name); in probe_disk()
835 port->vdisk_size, (port->vdisk_size >> (20 - 9)), in probe_disk()
836 port->vio.ver.major, port->vio.ver.minor); in probe_disk()
866 struct vdc_port *port; in vdc_port_probe() local
881 port = kzalloc(sizeof(*port), GFP_KERNEL); in vdc_port_probe()
883 if (!port) { in vdc_port_probe()
889 snprintf(port->disk_name, sizeof(port->disk_name), in vdc_port_probe()
894 snprintf(port->disk_name, sizeof(port->disk_name), in vdc_port_probe()
896 port->vdisk_size = -1; in vdc_port_probe()
903 port->ldc_timeout = ldc_timeout ? *ldc_timeout : 0; in vdc_port_probe()
904 setup_timer(&port->ldc_reset_timer, vdc_ldc_reset_timer, in vdc_port_probe()
905 (unsigned long)port); in vdc_port_probe()
906 INIT_WORK(&port->ldc_reset_work, vdc_ldc_reset_work); in vdc_port_probe()
908 err = vio_driver_init(&port->vio, vdev, VDEV_DISK, in vdc_port_probe()
910 &vdc_vio_ops, port->disk_name); in vdc_port_probe()
914 port->vdisk_block_size = 512; in vdc_port_probe()
915 port->max_xfer_size = ((128 * 1024) / port->vdisk_block_size); in vdc_port_probe()
916 port->ring_cookies = ((port->max_xfer_size * in vdc_port_probe()
917 port->vdisk_block_size) / PAGE_SIZE) + 2; in vdc_port_probe()
919 err = vio_ldc_alloc(&port->vio, &vdc_ldc_cfg, port); in vdc_port_probe()
923 err = vdc_alloc_tx_ring(port); in vdc_port_probe()
927 err = probe_disk(port); in vdc_port_probe()
931 dev_set_drvdata(&vdev->dev, port); in vdc_port_probe()
938 vdc_free_tx_ring(port); in vdc_port_probe()
941 vio_ldc_free(&port->vio); in vdc_port_probe()
944 kfree(port); in vdc_port_probe()
953 struct vdc_port *port = dev_get_drvdata(&vdev->dev); in vdc_port_remove() local
955 if (port) { in vdc_port_remove()
958 spin_lock_irqsave(&port->vio.lock, flags); in vdc_port_remove()
959 blk_stop_queue(port->disk->queue); in vdc_port_remove()
960 spin_unlock_irqrestore(&port->vio.lock, flags); in vdc_port_remove()
962 flush_work(&port->ldc_reset_work); in vdc_port_remove()
963 del_timer_sync(&port->ldc_reset_timer); in vdc_port_remove()
964 del_timer_sync(&port->vio.timer); in vdc_port_remove()
966 del_gendisk(port->disk); in vdc_port_remove()
967 blk_cleanup_queue(port->disk->queue); in vdc_port_remove()
968 put_disk(port->disk); in vdc_port_remove()
969 port->disk = NULL; in vdc_port_remove()
971 vdc_free_tx_ring(port); in vdc_port_remove()
972 vio_ldc_free(&port->vio); in vdc_port_remove()
976 kfree(port); in vdc_port_remove()
981 static void vdc_requeue_inflight(struct vdc_port *port) in vdc_requeue_inflight() argument
983 struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; in vdc_requeue_inflight()
988 struct vdc_req_entry *rqe = &port->rq_arr[idx]; in vdc_requeue_inflight()
991 ldc_unmap(port->vio.lp, desc->cookies, desc->ncookies); in vdc_requeue_inflight()
997 vdc_end_special(port, desc); in vdc_requeue_inflight()
1002 blk_requeue_request(port->disk->queue, req); in vdc_requeue_inflight()
1006 static void vdc_queue_drain(struct vdc_port *port) in vdc_queue_drain() argument
1010 while ((req = blk_fetch_request(port->disk->queue)) != NULL) in vdc_queue_drain()
1016 struct vdc_port *port = (struct vdc_port *) _arg; in vdc_ldc_reset_timer() local
1017 struct vio_driver_state *vio = &port->vio; in vdc_ldc_reset_timer()
1021 if (!(port->vio.hs_state & VIO_HS_COMPLETE)) { in vdc_ldc_reset_timer()
1023 port->disk_name, port->ldc_timeout); in vdc_ldc_reset_timer()
1024 vdc_queue_drain(port); in vdc_ldc_reset_timer()
1025 vdc_blk_queue_start(port); in vdc_ldc_reset_timer()
1032 struct vdc_port *port; in vdc_ldc_reset_work() local
1036 port = container_of(work, struct vdc_port, ldc_reset_work); in vdc_ldc_reset_work()
1037 vio = &port->vio; in vdc_ldc_reset_work()
1040 vdc_ldc_reset(port); in vdc_ldc_reset_work()
1044 static void vdc_ldc_reset(struct vdc_port *port) in vdc_ldc_reset() argument
1048 assert_spin_locked(&port->vio.lock); in vdc_ldc_reset()
1050 pr_warn(PFX "%s ldc link reset\n", port->disk_name); in vdc_ldc_reset()
1051 blk_stop_queue(port->disk->queue); in vdc_ldc_reset()
1052 vdc_requeue_inflight(port); in vdc_ldc_reset()
1053 vdc_port_down(port); in vdc_ldc_reset()
1055 err = vio_ldc_alloc(&port->vio, &vdc_ldc_cfg, port); in vdc_ldc_reset()
1057 pr_err(PFX "%s vio_ldc_alloc:%d\n", port->disk_name, err); in vdc_ldc_reset()
1061 err = vdc_alloc_tx_ring(port); in vdc_ldc_reset()
1063 pr_err(PFX "%s vio_alloc_tx_ring:%d\n", port->disk_name, err); in vdc_ldc_reset()
1067 if (port->ldc_timeout) in vdc_ldc_reset()
1068 mod_timer(&port->ldc_reset_timer, in vdc_ldc_reset()
1069 round_jiffies(jiffies + HZ * port->ldc_timeout)); in vdc_ldc_reset()
1070 mod_timer(&port->vio.timer, round_jiffies(jiffies + HZ)); in vdc_ldc_reset()
1074 vio_ldc_free(&port->vio); in vdc_ldc_reset()